Compare commits

..

2 Commits

Author SHA1 Message Date
Henrik Grimler 29aac0f5cb
BridgeManager: print error code when alt_setting function fail 2021-11-22 17:33:00 +01:00
Henrik Grimler 3d74deee1e
builds: test build for ubuntu 20.04 as well 2021-11-22 17:32:57 +01:00
22 changed files with 358 additions and 485 deletions

View File

@ -1,9 +1,5 @@
# Heimdall # Heimdall
[![builds.sr.ht status](https://builds.sr.ht/~grimler/Heimdall/commits/ubuntu.yml.svg)](https://builds.sr.ht/~grimler/Heimdall/commits/ubuntu.yml?)
[![builds.sr.ht status](https://builds.sr.ht/~grimler/Heimdall/commits/archlinux.yml.svg)](https://builds.sr.ht/~grimler/Heimdall/commits/archlinux.yml?)
[![builds.sr.ht status](https://builds.sr.ht/~grimler/Heimdall/commits/alpine.yml.svg)](https://builds.sr.ht/~grimler/Heimdall/commits/alpine.yml?)
Heimdall is a cross-platform open-source tool suite used to flash Heimdall is a cross-platform open-source tool suite used to flash
firmware (aka ROMs) onto Samsung mobile devices. firmware (aka ROMs) onto Samsung mobile devices.
@ -24,7 +20,7 @@ Heimdall communicate via the custom Samsung-developed protocol
typically referred to as the 'Odin 3 protocol'. typically referred to as the 'Odin 3 protocol'.
USB communication in Heimdall is handled by the popular open-source USB communication in Heimdall is handled by the popular open-source
USB library, [libusb](https://libusb.info). USB library, [libusb](http://libusb.info).
## Free & Open Source ## Free & Open Source
@ -44,17 +40,12 @@ refer to the appropriate platform specific README:
#### Linux #### Linux
- Linux/README ([online](Linux/README)) - Linux/README ([online](https://raw.githubusercontent.com/Benjamin-Dobell/Heimdall/master/Linux/README))
#### OS X #### OS X
- OSX/README.txt ([online](OSX/README.txt)) - OSX/README.txt ([online](https://raw.githubusercontent.com/Benjamin-Dobell/Heimdall/master/OSX/README.txt))
#### Windows #### Windows
- Win32/README.txt ([online](Win32/README.txt)) - Win32/README.txt ([online](https://raw.githubusercontent.com/Benjamin-Dobell/Heimdall/master/Win32/README.txt))
### Odin protocol and PIT format
For more details on the Odin protocol, and the PIT files, see the
external project [samsung-loki/samsung-docs](https://samsung-loki.github.io/samsung-docs/).

BIN
Win32/Drivers/zadig.exe Normal file

Binary file not shown.

View File

@ -20,7 +20,7 @@ Driver Installation Instructions:
1. Put your device into download mode and plug it in. 1. Put your device into download mode and plug it in.
2. Download zadig from https://zadig.akeo.ie/downloads/, and run zadig.exe. 2. Run zadig.exe included in the Drivers subdirectory.
3. From the menu chose Options -> List All Devices. 3. From the menu chose Options -> List All Devices.

View File

@ -1,85 +0,0 @@
# CMake support for fseeko
#
# Based on FindLFS.cmake by
# Copyright (C) 2016 Julian Andres Klode <jak@debian.org>.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# This defines the following variables
#
# FSEEKO_DEFINITIONS - List of definitions to pass to add_definitions()
# FSEEKO_COMPILE_OPTIONS - List of definitions to pass to add_compile_options()
# FSEEKO_LIBRARIES - List of libraries and linker flags
# FSEEKO_FOUND - If there is Large files support
#
include(CheckCSourceCompiles)
include(FindPackageHandleStandardArgs)
include(CMakePushCheckState)
# Check for the availability of fseeko()
# The cases handled are:
#
# * Native fseeko()
# * Preprocessor flag -D_LARGEFILE_SOURCE
#
function(_fseeko_check)
set(_fseeko_cppflags)
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET 1)
set(CMAKE_REQUIRED_DEFINITIONS ${LFS_DEFINITIONS})
message(STATUS "Looking for native fseeko support")
check_symbol_exists(fseeko stdio.h fseeko_native)
cmake_pop_check_state()
if (fseeko_native)
message(STATUS "Looking for native fseeko support - found")
set(FSEEKO_FOUND TRUE)
else()
message(STATUS "Looking for native fseeko support - not found")
endif()
if (NOT FSEEKO_FOUND)
# See if it's available with _LARGEFILE_SOURCE.
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET 1)
set(CMAKE_REQUIRED_DEFINITIONS ${LFS_DEFINITIONS} "-D_LARGEFILE_SOURCE")
check_symbol_exists(fseeko stdio.h fseeko_need_largefile_source)
cmake_pop_check_state()
if (fseeko_need_largefile_source)
message(STATUS "Looking for fseeko support with _LARGEFILE_SOURCE - found")
set(FSEEKO_FOUND TRUE)
set(_fseeko_cppflags "-D_LARGEFILE_SOURCE")
else()
message(STATUS "Looking for fseeko support with _LARGEFILE_SOURCE - not found")
endif()
endif()
set(FSEEKO_DEFINITIONS ${_fseeko_cppflags} CACHE STRING "Extra definitions for fseeko support")
set(FSEEKO_COMPILE_OPTIONS "" CACHE STRING "Extra compiler options for fseeko support")
set(FSEEKO_LIBRARIES "" CACHE STRING "Extra definitions for fseeko support")
set(FSEEKO_FOUND ${FSEEKO_FOUND} CACHE INTERNAL "Found fseeko")
endfunction()
if (NOT FSEEKO_FOUND)
_fseeko_check()
endif()
find_package_handle_standard_args(FSEEKO "Could not find fseeko. Set FSEEKO_DEFINITIONS, FSEEKO_COMPILE_OPTIONS, FSEEKO_LIBRARIES." FSEEKO_FOUND)

View File

@ -1,153 +0,0 @@
# CMake support for large files
#
# Copyright (C) 2016 Julian Andres Klode <jak@debian.org>.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# This defines the following variables
#
# LFS_DEFINITIONS - List of definitions to pass to add_definitions()
# LFS_COMPILE_OPTIONS - List of definitions to pass to add_compile_options()
# LFS_LIBRARIES - List of libraries and linker flags
# LFS_FOUND - If there is Large files support
#
include(CheckCSourceCompiles)
include(FindPackageHandleStandardArgs)
include(CMakePushCheckState)
# Test program to check for LFS. Requires that off_t has at least 8 byte large
set(_lfs_test_source
"
#include <sys/types.h>
typedef char my_static_assert[sizeof(off_t) >= 8 ? 1 : -1];
int main(void) { return 0; }
"
)
# Check if the given options are needed
#
# This appends to the variables _lfs_cppflags, _lfs_cflags, and _lfs_ldflags,
# it also sets LFS_FOUND to 1 if it works.
function(_lfs_check_compiler_option var options definitions libraries)
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET 1)
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} ${options})
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${definitions})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_DEFINITIONS} ${libraries})
message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries}")
check_c_source_compiles("${_lfs_test_source}" ${var})
cmake_pop_check_state()
if(${var})
message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries} - found")
set(_lfs_cppflags ${_lfs_cppflags} ${definitions} PARENT_SCOPE)
set(_lfs_cflags ${_lfs_cflags} ${options} PARENT_SCOPE)
set(_lfs_ldflags ${_lfs_ldflags} ${libraries} PARENT_SCOPE)
set(LFS_FOUND TRUE PARENT_SCOPE)
else()
message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries} - not found")
endif()
endfunction()
# Check for the availability of LFS.
# The cases handled are:
#
# * Native LFS
# * Output of getconf LFS_CFLAGS; getconf LFS_LIBS; getconf LFS_LDFLAGS
# * Preprocessor flag -D_FILE_OFFSET_BITS=64
# * Preprocessor flag -D_LARGE_FILES
#
function(_lfs_check)
set(_lfs_cflags)
set(_lfs_cppflags)
set(_lfs_ldflags)
set(_lfs_libs)
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET 1)
message(STATUS "Looking for native LFS support")
check_c_source_compiles("${_lfs_test_source}" lfs_native)
cmake_pop_check_state()
if (lfs_native)
message(STATUS "Looking for native LFS support - found")
set(LFS_FOUND TRUE)
else()
message(STATUS "Looking for native LFS support - not found")
endif()
if (NOT LFS_FOUND)
# Check using getconf. If getconf fails, don't worry, the check in
# _lfs_check_compiler_option will fail as well.
execute_process(COMMAND getconf LFS_CFLAGS
OUTPUT_VARIABLE _lfs_cflags_raw
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
execute_process(COMMAND getconf LFS_LIBS
OUTPUT_VARIABLE _lfs_libs_tmp
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
execute_process(COMMAND getconf LFS_LDFLAGS
OUTPUT_VARIABLE _lfs_ldflags_tmp
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
separate_arguments(_lfs_cflags_raw)
separate_arguments(_lfs_ldflags_tmp)
separate_arguments(_lfs_libs_tmp)
# Move -D flags to the place they are supposed to be
foreach(flag ${_lfs_cflags_raw})
if (flag MATCHES "-D.*")
list(APPEND _lfs_cppflags_tmp ${flag})
else()
list(APPEND _lfs_cflags_tmp ${flag})
endif()
endforeach()
# Check if the flags we received (if any) produce working LFS support
_lfs_check_compiler_option(lfs_getconf_works
"${_lfs_cflags_tmp}"
"${_lfs_cppflags_tmp}"
"${_lfs_libs_tmp};${_lfs_ldflags_tmp}")
endif()
if(NOT LFS_FOUND) # IRIX stuff
_lfs_check_compiler_option(lfs_need_n32 "-n32" "" "")
endif()
if(NOT LFS_FOUND) # Linux and friends
_lfs_check_compiler_option(lfs_need_file_offset_bits "" "-D_FILE_OFFSET_BITS=64" "")
endif()
if(NOT LFS_FOUND) # AIX
_lfs_check_compiler_option(lfs_need_large_files "" "-D_LARGE_FILES=1" "")
endif()
set(LFS_DEFINITIONS ${_lfs_cppflags} CACHE STRING "Extra definitions for large file support")
set(LFS_COMPILE_OPTIONS ${_lfs_cflags} CACHE STRING "Extra definitions for large file support")
set(LFS_LIBRARIES ${_lfs_libs} ${_lfs_ldflags} CACHE STRING "Extra definitions for large file support")
set(LFS_FOUND ${LFS_FOUND} CACHE INTERNAL "Found LFS")
endfunction()
if (NOT LFS_FOUND)
_lfs_check()
endif()
find_package_handle_standard_args(LFS "Could not find LFS. Set LFS_DEFINITIONS, LFS_COMPILE_OPTIONS, LFS_LIBRARIES." LFS_FOUND)

15
cmake/LargeFiles.c Normal file
View File

@ -0,0 +1,15 @@
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
#define VALID_ARRAY_LENGTH 1
#define INVALID_ARRAY_LENGTH -1
int main(int argc, const char **argv)
{
int a[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? VALID_ARRAY_LENGTH : INVALID_ARRAY_LENGTH];
off_t offset = ftello(NULL);
fseeko(NULL, offset, SEEK_SET);
return 0;
}

107
cmake/LargeFiles.cmake Normal file
View File

@ -0,0 +1,107 @@
macro(test_large_files VARIABLE USE_64_SUFFIX)
if(NOT DEFINED ${VARIABLE})
message(STATUS "Checking if large (64-bit) file support is available...")
if(USE_64_SUFFIX)
set(SUFFIX_64 "64")
else(USE_64_SUFFIX)
set(SUFFIX_64 "")
endif(USE_64_SUFFIX)
# First try without any macros defined
try_compile(LARGE_FILES_SUPPORTED "${CMAKE_BINARY_DIR}"
"${CMAKE_MODULE_PATH}/LargeFiles${SUFFIX_64}.c"
OUTPUT_VARIABLE TRY_LARGE_FILES_OUTPUT)
if(VERBOSE_LARGE_FILES)
message(STATUS "Large file output (no special flags):\n${TRY_LARGE_FILES_OUTPUT}")
endif(VERBOSE_LARGE_FILES)
if(NOT LARGE_FILES_SUPPORTED)
# Try with C macro _FILE_OFFSET_BITS=64
try_compile(LARGE_FILES_SUPPORTED "${CMAKE_BINARY_DIR}"
"${CMAKE_MODULE_PATH}/LargeFiles${SUFFIX_64}.c"
COMPILE_DEFINITIONS "-D_FILE_OFFSET_BITS=64"
OUTPUT_VARIABLE TRY_LARGE_FILES_OUTPUT)
if(VERBOSE_LARGE_FILES)
message(STATUS "Large file output (_FILE_OFFSET_BITS=64):\n${TRY_LARGE_FILES_OUTPUT}")
endif(VERBOSE_LARGE_FILES)
if(LARGE_FILES_SUPPORTED)
set(_FILE_OFFSET_BITS=64 CACHE INTERNAL "C macro _FILE_OFFSET_BITS=64 is required for 64-bit file support")
endif(LARGE_FILES_SUPPORTED)
endif(NOT LARGE_FILES_SUPPORTED)
if(NOT LARGE_FILES_SUPPORTED)
# Try with C macro _LARGEFILE_SOURCE
try_compile(LARGE_FILES_SUPPORTED "${CMAKE_BINARY_DIR}"
"${CMAKE_MODULE_PATH}/LargeFiles${SUFFIX_64}.c"
COMPILE_DEFINITIONS "-D_LARGEFILE${SUFFIX_64}_SOURCE"
OUTPUT_VARIABLE TRY_LARGE_FILES_OUTPUT)
if(VERBOSE_LARGE_FILES)
message(STATUS "Large file output (_LARGEFILE${SUFFIX_64}_SOURCE):\n${TRY_LARGE_FILES_OUTPUT}")
endif(VERBOSE_LARGE_FILES)
if(LARGE_FILES_SUPPORTED)
set(_LARGEFILE${SUFFIX_64}_SOURCE=1 CACHE INTERNAL "C macro _LARGEFILE${SUFFIX_64}_SOURCE is required for 64-bit file support")
endif(LARGE_FILES_SUPPORTED)
endif(NOT LARGE_FILES_SUPPORTED)
if(NOT LARGE_FILES_SUPPORTED)
# Try with both C macro _FILE_OFFSET_BITS=64 and _LARGEFILE_SOURCE
try_compile(LARGE_FILES_SUPPORTED "${CMAKE_BINARY_DIR}"
"${CMAKE_MODULE_PATH}/LargeFiles${SUFFIX_64}.c"
COMPILE_DEFINITIONS "-D_FILE_OFFSET_BITS=64" "-D_LARGEFILE${SUFFIX_64}_SOURCE"
OUTPUT_VARIABLE TRY_LARGE_FILES_OUTPUT)
if(VERBOSE_LARGE_FILES)
message(STATUS "Large file output (_FILE_OFFSET_BITS=64 and _LARGEFILE${SUFFIX_64}_SOURCE):\n${TRY_LARGE_FILES_OUTPUT}")
endif(VERBOSE_LARGE_FILES)
if(LARGE_FILES_SUPPORTED)
set(_FILE_OFFSET_BITS=64 CACHE INTERNAL "C macro _FILE_OFFSET_BITS=64 is required for 64-bit file support")
set(_LARGEFILE${SUFFIX_64}_SOURCE=1 CACHE INTERNAL "C macro _LARGEFILE${SUFFIX_64}_SOURCE is required for 64-bit file support")
endif(LARGE_FILES_SUPPORTED)
endif(NOT LARGE_FILES_SUPPORTED)
if(NOT LARGE_FILES_SUPPORTED)
# Maybe we are using the Windows C standard library
try_compile(LARGE_FILES_SUPPORTED "${CMAKE_BINARY_DIR}"
"${CMAKE_MODULE_PATH}/LargeFilesWindows.c")
endif(NOT LARGE_FILES_SUPPORTED)
if(LARGE_FILES_SUPPORTED)
message(STATUS "Checking if large (64-bit) file support is available - yes")
set(${VARIABLE} 1 CACHE INTERNAL "Is large file support available?")
else(LARGE_FILES_SUPPORTED)
message(STATUS "Checking if large (64-bit) file support is available - no")
set(${VARIABLE} 0 CACHE INTERNAL "Is large file support available?")
endif(LARGE_FILES_SUPPORTED)
endif(NOT DEFINED ${VARIABLE})
endmacro(test_large_files VARIABLE USE_64_SUFFIX)
macro(use_large_files TARGET USE_64_SUFFIX)
test_large_files(USING_LARGE_FILES ${USE_64_SUFFIX})
if(USING_LARGE_FILES)
if(DEFINED _FILE_OFFSET_BITS)
set_property(TARGET ${TARGET}
APPEND PROPERTY COMPILE_DEFINITIONS "-D_FILE_OFFSET_BITS=${_FILE_OFFSET_BITS}")
endif(DEFINED _FILE_OFFSET_BITS)
if(DEFINED _LARGEFILE_SOURCE)
set_property(TARGET ${TARGET}
APPEND PROPERTY COMPILE_DEFINITIONS "-D_LARGEFILE_SOURCE")
endif(DEFINED _LARGEFILE_SOURCE)
if(DEFINED _LARGEFILE64_SOURCE)
set_property(TARGET ${TARGET}
APPEND PROPERTY COMPILE_DEFINITIONS "-D_LARGEFILE64_SOURCE")
endif(DEFINED _LARGEFILE64_SOURCE)
else(USING_LARGE_FILES)
message(FATAL_ERROR "Large file support not available")
endif(USING_LARGE_FILES)
endmacro(use_large_files TARGET USE_64_SUFFIX)

16
cmake/LargeFiles64.c Normal file
View File

@ -0,0 +1,16 @@
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
#define VALID_ARRAY_LENGTH 1
#define INVALID_ARRAY_LENGTH -1
int main(int argc, const char **argv)
{
int a[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? VALID_ARRAY_LENGTH : INVALID_ARRAY_LENGTH];
off64_t offset = ftello64(NULL);
fseeko64(NULL, offset, SEEK_SET);
return 0;
}

View File

@ -0,0 +1,8 @@
#include <stdio.h>
int main()
{
__int64 off = 0;
_fseeki64(NULL, off, SEEK_SET);
return 0;
}

View File

@ -12,8 +12,12 @@ find_package(Qt5Widgets REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
if(APPLE) if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lobjc -framework IOKit -framework CoreFoundation") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lobjc -framework IOKit -framework CoreFoundation")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
endif() endif()
if(MINGW) if(MINGW)
@ -44,38 +48,8 @@ add_executable(heimdall-frontend WIN32
${HEIMDALL_FRONTEND_FORMS} ${HEIMDALL_FRONTEND_FORMS}
${HEIMDALL_FRONTEND_RESOURCES}) ${HEIMDALL_FRONTEND_RESOURCES})
target_compile_features(heimdall-frontend PRIVATE cxx_std_11) include(LargeFiles)
use_large_files(heimdall-frontend YES)
include(CheckSymbolExists)
#
# Large file support on UN*X, a/k/a LFS.
#
# On Windows, we require _fseeki64() and _ftelli64(). Visual Studio
# has had supported them since Visual Studio 2005/MSVCR80.
#
if(NOT WIN32)
include(FindLFS)
if(LFS_FOUND)
#
# Add the required #defines.
#
add_definitions(${LFS_DEFINITIONS})
endif()
#
# Check for fseeko as well.
#
include(FindFseeko)
if(FSEEKO_FOUND)
set(HAVE_FSEEKO ON)
#
# Add the required #defines.
#
add_definitions(${FSEEKO_DEFINITIONS})
endif()
endif()
set_property(TARGET heimdall-frontend set_property(TARGET heimdall-frontend
APPEND PROPERTY COMPILE_DEFINITIONS "QT_LARGEFILE_SUPPORT") APPEND PROPERTY COMPILE_DEFINITIONS "QT_LARGEFILE_SUPPORT")
@ -84,6 +58,7 @@ target_link_libraries(heimdall-frontend pit)
target_link_libraries(heimdall-frontend Qt5::Widgets) target_link_libraries(heimdall-frontend Qt5::Widgets)
target_link_libraries(heimdall-frontend z) target_link_libraries(heimdall-frontend z)
install (TARGETS heimdall-frontend install (TARGETS heimdall-frontend
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
BUNDLE DESTINATION /Applications) BUNDLE DESTINATION /Applications)

View File

@ -114,7 +114,7 @@
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Heimdall Frontend&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Heimdall Frontend&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Version 2.0.2&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Version 1.4.2&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Copyright © 2010-2017 Benjamin Dobell, Glass Echidna&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Copyright © 2010-2017 Benjamin Dobell, Glass Echidna&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt; &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Heimdall (command line)&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Heimdall (command line)&lt;/span&gt;&lt;/p&gt;

View File

@ -8,8 +8,12 @@ set(LIBPIT_INCLUDE_DIRS
../libpit/source) ../libpit/source)
if(APPLE) if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lobjc -framework IOKit -framework CoreFoundation") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lobjc -framework IOKit -framework CoreFoundation")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -D_FILE_OFFSET_BITS=64")
endif() endif()
if(MINGW) if(MINGW)
@ -39,42 +43,13 @@ set(HEIMDALL_SOURCE_FILES
source/Utility.cpp source/Utility.cpp
source/VersionAction.cpp) source/VersionAction.cpp)
include(CheckSymbolExists) include(LargeFiles)
use_large_files(heimdall YES)
#
# Large file support on UN*X, a/k/a LFS.
#
# On Windows, we require _fseeki64() and _ftelli64(). Visual Studio
# has had supported them since Visual Studio 2005/MSVCR80.
#
if(NOT WIN32)
include(FindLFS)
if(LFS_FOUND)
#
# Add the required #defines.
#
add_definitions(${LFS_DEFINITIONS})
endif()
#
# Check for fseeko as well.
#
include(FindFseeko)
if(FSEEKO_FOUND)
set(HAVE_FSEEKO ON)
#
# Add the required #defines.
#
add_definitions(${FSEEKO_DEFINITIONS})
endif()
endif()
add_executable(heimdall ${HEIMDALL_SOURCE_FILES}) add_executable(heimdall ${HEIMDALL_SOURCE_FILES})
target_compile_features(heimdall PRIVATE cxx_std_11)
target_link_libraries(heimdall PRIVATE pit) target_link_libraries(heimdall PRIVATE pit)
target_link_libraries(heimdall PRIVATE ${LIBUSB_LIBRARIES}) target_link_libraries(heimdall PRIVATE ${LIBUSB_LIBRARIES})
install (TARGETS heimdall install (TARGETS heimdall
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@ -20,7 +20,6 @@
// C Standard Library // C Standard Library
#include <cstdio> #include <cstdio>
#include <fstream>
// libusb // libusb
#include <libusb.h> #include <libusb.h>
@ -81,17 +80,16 @@ int BridgeManager::FindDeviceInterface(void)
Interface::Print("Detecting device...\n"); Interface::Print("Detecting device...\n");
struct libusb_device **devices; struct libusb_device **devices;
unsigned int deviceCount = libusb_get_device_list(libusbContext, &devices); int deviceCount = libusb_get_device_list(libusbContext, &devices);
for (unsigned int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
{ {
libusb_device_descriptor descriptor; libusb_device_descriptor descriptor;
libusb_get_device_descriptor(devices[deviceIndex], &descriptor); libusb_get_device_descriptor(devices[deviceIndex], &descriptor);
for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++) for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++)
{ {
if (descriptor.idVendor == supportedDevices[i].vendorId && if (descriptor.idVendor == supportedDevices[i].vendorId && descriptor.idProduct == supportedDevices[i].productId)
descriptor.idProduct == supportedDevices[i].productId)
{ {
heimdallDevice = devices[deviceIndex]; heimdallDevice = devices[deviceIndex];
libusb_ref_device(heimdallDevice); libusb_ref_device(heimdallDevice);
@ -261,20 +259,13 @@ bool BridgeManager::ClaimDeviceInterface(void)
bool BridgeManager::SetupDeviceInterface(void) bool BridgeManager::SetupDeviceInterface(void)
{ {
// if altSettingIndex is 0 there should be no need
// to set alt_setting(?)
if (altSettingIndex == 0)
return (true);
Interface::Print("Setting up interface...\n"); Interface::Print("Setting up interface...\n");
int result = libusb_set_interface_alt_setting(deviceHandle, int result = libusb_set_interface_alt_setting(deviceHandle, interfaceIndex, altSettingIndex);
interfaceIndex,
altSettingIndex);
if (result != LIBUSB_SUCCESS) if (result != LIBUSB_SUCCESS)
{ {
Interface::PrintError("Setting up interface failed!\n"); Interface::PrintError("Setting up interface failed with error code %i!\n", result);
return (false); return (false);
} }
@ -312,20 +303,14 @@ bool BridgeManager::InitialiseProtocol(void)
memcpy(dataBuffer, "ODIN", 4); memcpy(dataBuffer, "ODIN", 4);
memset(dataBuffer + 4, 0, 1); memset(dataBuffer + 4, 0, 1);
#ifdef OS_LINUX if (libusb_reset_device(deviceHandle))
if (IsUbuntu())
{ {
Interface::Print("Resetting device...\n"); Interface::PrintError("Failed to reset device!");
if (libusb_reset_device(deviceHandle))
{
Interface::PrintError("Failed to reset device!\n");
}
} }
#endif
if (!SendBulkTransfer(dataBuffer, 4, 1000)) if (!SendBulkTransfer(dataBuffer, 4, 1000))
{ {
Interface::PrintError("Failed to send handshake!\n"); Interface::PrintError("Failed to send handshake!");
} }
// Expect "LOKE" // Expect "LOKE"
@ -415,8 +400,29 @@ bool BridgeManager::DetectDevice(void)
return (false); return (false);
} }
// Set libusb log level. // Setup libusb log level.
SetUsbLogLevel(usbLogLevel); switch (usbLogLevel)
{
case UsbLogLevel::None:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE);
break;
case UsbLogLevel::Error:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_ERROR);
break;
case UsbLogLevel::Warning:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_WARNING);
break;
case UsbLogLevel::Info:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
break;
case UsbLogLevel::Debug:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
break;
}
// Get handle to Galaxy S device // Get handle to Galaxy S device
struct libusb_device **devices; struct libusb_device **devices;
@ -429,8 +435,7 @@ bool BridgeManager::DetectDevice(void)
for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++) for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++)
{ {
if (descriptor.idVendor == supportedDevices[i].vendorId && if (descriptor.idVendor == supportedDevices[i].vendorId && descriptor.idProduct == supportedDevices[i].productId)
descriptor.idProduct == supportedDevices[i].productId)
{ {
libusb_free_device_list(devices, deviceCount); libusb_free_device_list(devices, deviceCount);
@ -456,12 +461,33 @@ int BridgeManager::Initialise(bool resume)
if (result != LIBUSB_SUCCESS) if (result != LIBUSB_SUCCESS)
{ {
Interface::PrintError("Failed to initialise libusb. libusb error: %d\n", result); Interface::PrintError("Failed to initialise libusb. libusb error: %d\n", result);
Interface::Print("Failed to connect to device!\n"); Interface::Print("Failed to connect to device!");
return (BridgeManager::kInitialiseFailed); return (BridgeManager::kInitialiseFailed);
} }
// Setup libusb log level. // Setup libusb log level.
SetUsbLogLevel(usbLogLevel); switch (usbLogLevel)
{
case UsbLogLevel::None:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE);
break;
case UsbLogLevel::Error:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_ERROR);
break;
case UsbLogLevel::Warning:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_WARNING);
break;
case UsbLogLevel::Info:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
break;
case UsbLogLevel::Debug:
libusb_set_option(libusbContext, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
break;
}
result = FindDeviceInterface(); result = FindDeviceInterface();
@ -716,7 +742,7 @@ bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout, int emptyT
if (receivedSize < 0) if (receivedSize < 0)
return (false); return (false);
if (static_cast<unsigned int>(receivedSize) != packet->GetSize() && !packet->IsSizeVariable()) if (receivedSize != packet->GetSize() && !packet->IsSizeVariable())
{ {
if (verbose) if (verbose)
Interface::PrintError("Incorrect packet size received - expected size = %d, received size = %d.\n", packet->GetSize(), receivedSize); Interface::PrintError("Incorrect packet size received - expected size = %d, received size = %d.\n", packet->GetSize(), receivedSize);
@ -1244,32 +1270,3 @@ void BridgeManager::SetUsbLogLevel(UsbLogLevel usbLogLevel)
} }
} }
} }
#ifdef OS_LINUX
bool BridgeManager::IsUbuntu()
{
std::ifstream os_release("/etc/os-release");
std::string line, entry, os;
int pos;
while (std::getline(os_release, line))
{
pos = line.find("=");
entry = line.substr(0, pos);
if (entry == "ID")
{
os = line.substr(pos+1);
if (verbose)
{
Interface::Print("Linux distro ID: %s\n",
os.c_str());
}
if (os == "ubuntu")
{
return true;
}
break;
}
}
return false;
}
#endif

View File

@ -166,9 +166,7 @@ namespace Heimdall
bool SendFile(FILE *file, unsigned int destination, unsigned int deviceType, unsigned int fileIdentifier = 0xFFFFFFFF) const; bool SendFile(FILE *file, unsigned int destination, unsigned int deviceType, unsigned int fileIdentifier = 0xFFFFFFFF) const;
void SetUsbLogLevel(UsbLogLevel usbLogLevel); void SetUsbLogLevel(UsbLogLevel usbLogLevel);
#ifdef OS_LINUX
bool IsUbuntu(void);
#endif
UsbLogLevel GetUsbLogLevel(void) const UsbLogLevel GetUsbLogLevel(void) const
{ {
return usbLogLevel; return usbLogLevel;

View File

@ -148,7 +148,7 @@ int DownloadPitAction::Execute(int argc, char **argv)
if (fileSize > 0) if (fileSize > 0)
{ {
if (fwrite(pitBuffer, 1, fileSize, outputPitFile) != static_cast<size_t>(fileSize)) if (fwrite(pitBuffer, 1, fileSize, outputPitFile) != fileSize)
{ {
Interface::PrintError("Failed to write PIT data to output file.\n"); Interface::PrintError("Failed to write PIT data to output file.\n");
success = false; success = false;

View File

@ -48,11 +48,10 @@ Arguments:\n\
--repartition --pit <filename> [--<partition name> <filename> ...]\n\ --repartition --pit <filename> [--<partition name> <filename> ...]\n\
[--<partition identifier> <filename> ...] [--verbose] [--no-reboot]\n\ [--<partition identifier> <filename> ...] [--verbose] [--no-reboot]\n\
[--resume] [--stdout-errors] [--usb-log-level <none/error/warning/debug>]\n\ [--resume] [--stdout-errors] [--usb-log-level <none/error/warning/debug>]\n\
[--tflash] [--skip-size-check]\n\ [--tflash]\n\
Description: Flashes one or more firmware files to your phone. Partition names\n\ Description: Flashes one or more firmware files to your phone. Partition names\n\
(or identifiers) can be obtained by executing the print-pit action.\n\ (or identifiers) can be obtained by executing the print-pit action.\n\
T-Flash mode allows to flash the inserted SD-card instead of the internal MMC.\n\ T-Flash mode allows to flash the inserted SD-card instead of the internal MMC.\n\
Use --skip-size-check to not verify that files fit in the specified partition.\n\
Note: --no-reboot causes the device to remain in download mode after the action\n\ Note: --no-reboot causes the device to remain in download mode after the action\n\
is completed. If you wish to perform another action whilst remaining in\n\ is completed. If you wish to perform another action whilst remaining in\n\
download mode, then the following action must specify the --resume flag.\n\ download mode, then the following action must specify the --resume flag.\n\
@ -63,13 +62,11 @@ struct PartitionFile
{ {
const char *argumentName; const char *argumentName;
FILE *file; FILE *file;
unsigned long fileSize;
PartitionFile(const char *argumentName, FILE *file, unsigned long fileSize) PartitionFile(const char *argumentName, FILE *file)
{ {
this->argumentName = argumentName; this->argumentName = argumentName;
this->file = file; this->file = file;
this->fileSize = fileSize;
} }
}; };
@ -116,17 +113,14 @@ static bool openFiles(Arguments& arguments, vector<PartitionFile>& partitionFile
{ {
const StringArgument *stringArgument = static_cast<const StringArgument *>(*it); const StringArgument *stringArgument = static_cast<const StringArgument *>(*it);
FILE *file = FileOpen(stringArgument->GetValue().c_str(), "rb"); FILE *file = FileOpen(stringArgument->GetValue().c_str(), "rb");
if (!file) if (!file)
{ {
Interface::PrintError("Failed to open file \"%s\"\n", stringArgument->GetValue().c_str()); Interface::PrintError("Failed to open file \"%s\"\n", stringArgument->GetValue().c_str());
return (false); return (false);
} }
FileSeek(file, 0, SEEK_END); partitionFiles.push_back(PartitionFile(argumentName.c_str(), file));
unsigned long fileSize = (unsigned long)FileTell(file);
FileRewind(file);
partitionFiles.push_back(PartitionFile(argumentName.c_str(), file, fileSize));
} }
} }
@ -157,7 +151,9 @@ static bool sendTotalTransferSize(BridgeManager *bridgeManager, const vector<Par
for (vector<PartitionFile>::const_iterator it = partitionFiles.begin(); it != partitionFiles.end(); it++) for (vector<PartitionFile>::const_iterator it = partitionFiles.begin(); it != partitionFiles.end(); it++)
{ {
totalBytes += it->fileSize; FileSeek(it->file, 0, SEEK_END);
totalBytes += (unsigned long)FileTell(it->file);
FileRewind(it->file);
} }
if (repartition) if (repartition)
@ -288,7 +284,7 @@ static bool flashFile(BridgeManager *bridgeManager, const PartitionFlashInfo& pa
} }
} }
static bool flashPartitions(BridgeManager *bridgeManager, const vector<PartitionFile>& partitionFiles, const PitData *pitData, bool repartition, bool skip_size_check) static bool flashPartitions(BridgeManager *bridgeManager, const vector<PartitionFile>& partitionFiles, const PitData *pitData, bool repartition)
{ {
vector<PartitionFlashInfo> partitionFlashInfos; vector<PartitionFlashInfo> partitionFlashInfos;
@ -296,28 +292,6 @@ static bool flashPartitions(BridgeManager *bridgeManager, const vector<Partition
if (!setupPartitionFlashInfo(partitionFiles, pitData, partitionFlashInfos)) if (!setupPartitionFlashInfo(partitionFiles, pitData, partitionFlashInfos))
return (false); return (false);
/* Verify that the files we want to flash fit in partitions */
if (!skip_size_check)
{
for (vector<PartitionFile>::const_iterator it = partitionFiles.begin(); it != partitionFiles.end(); it++)
{
const PitEntry *part = pitData->FindEntry(it->argumentName);
if (part->GetDeviceType() != PitEntry::kDeviceTypeMMC &&
part->GetDeviceType() != PitEntry::kDeviceTypeUFS)
continue;
unsigned long partitionSize = part->GetBlockCount();
unsigned int blockSize = 512;
if (part->GetDeviceType() == PitEntry::kDeviceTypeUFS)
blockSize = 4096;
if (partitionSize > 0 && it->fileSize > partitionSize*blockSize)
{
Interface::PrintError("%s partition is too small for given file. Use --skip-size-check to flash anyways.\n",
it->argumentName);
return (false);
}
}
}
// If we're repartitioning then we need to flash the PIT file first (if it is listed in the PIT file). // If we're repartitioning then we need to flash the PIT file first (if it is listed in the PIT file).
if (repartition) if (repartition)
{ {
@ -457,7 +431,6 @@ int FlashAction::Execute(int argc, char **argv)
argumentTypes["stdout-errors"] = kArgumentTypeFlag; argumentTypes["stdout-errors"] = kArgumentTypeFlag;
argumentTypes["usb-log-level"] = kArgumentTypeString; argumentTypes["usb-log-level"] = kArgumentTypeString;
argumentTypes["tflash"] = kArgumentTypeFlag; argumentTypes["tflash"] = kArgumentTypeFlag;
argumentTypes["skip-size-check"] = kArgumentTypeFlag;
argumentTypes["pit"] = kArgumentTypeString; argumentTypes["pit"] = kArgumentTypeString;
shortArgumentAliases["pit"] = "pit"; shortArgumentAliases["pit"] = "pit";
@ -486,7 +459,6 @@ int FlashAction::Execute(int argc, char **argv)
bool resume = arguments.GetArgument("resume") != nullptr; bool resume = arguments.GetArgument("resume") != nullptr;
bool verbose = arguments.GetArgument("verbose") != nullptr; bool verbose = arguments.GetArgument("verbose") != nullptr;
bool tflash = arguments.GetArgument("tflash") != nullptr; bool tflash = arguments.GetArgument("tflash") != nullptr;
bool skip_size_check = arguments.GetArgument("skip-size-check") != nullptr;
if (arguments.GetArgument("stdout-errors") != nullptr) if (arguments.GetArgument("stdout-errors") != nullptr)
Interface::SetStdoutErrors(true); Interface::SetStdoutErrors(true);
@ -588,9 +560,7 @@ int FlashAction::Execute(int argc, char **argv)
PitData *pitData = getPitData(bridgeManager, pitFile, repartition); PitData *pitData = getPitData(bridgeManager, pitFile, repartition);
if (pitData) if (pitData)
success = flashPartitions(bridgeManager, partitionFiles, success = flashPartitions(bridgeManager, partitionFiles, pitData, repartition);
pitData, repartition,
skip_size_check);
else else
success = false; success = false;

View File

@ -54,10 +54,12 @@
#endif #endif
#if defined(_MSC_VER) && (_MSC_VER < 1700) #if (!(defined _MSC_VER) || (_MSC_VER < 1700))
# ifndef nullptr
# define nullptr 0 #ifndef nullptr
# endif #define nullptr 0
#endif
#endif #endif
#endif #endif

View File

@ -42,7 +42,7 @@ using namespace Heimdall;
map<string, Interface::ActionInfo> actionMap; map<string, Interface::ActionInfo> actionMap;
bool stdoutErrors = false; bool stdoutErrors = false;
const char *version = "v2.0.2"; const char *version = "v1.4.2";
const char *actionUsage = "Usage: heimdall <action> <action arguments>\n"; const char *actionUsage = "Usage: heimdall <action> <action arguments>\n";
const char *releaseInfo = "Heimdall %s\n\n\ const char *releaseInfo = "Heimdall %s\n\n\
@ -207,11 +207,16 @@ void Interface::PrintDeviceDetectionFailed(void)
void Interface::PrintPit(const PitData *pitData) void Interface::PrintPit(const PitData *pitData)
{ {
Interface::Print("--- PIT Header ---\n");
Interface::Print("Entry Count: %d\n", pitData->GetEntryCount()); Interface::Print("Entry Count: %d\n", pitData->GetEntryCount());
Interface::Print("Unknown string: %s\n", pitData->GetComTar2());
Interface::Print("CPU/bootloader tag: %s\n", pitData->GetCpuBlId()); Interface::Print("Unknown 1: %d\n", pitData->GetUnknown1());
Interface::Print("Logic unit count: %d\n", pitData->GetLUCount()); Interface::Print("Unknown 2: %d\n", pitData->GetUnknown2());
Interface::Print("Unknown 3: %d\n", pitData->GetUnknown3());
Interface::Print("Unknown 4: %d\n", pitData->GetUnknown4());
Interface::Print("Unknown 5: %d\n", pitData->GetUnknown5());
Interface::Print("Unknown 6: %d\n", pitData->GetUnknown6());
Interface::Print("Unknown 7: %d\n", pitData->GetUnknown7());
Interface::Print("Unknown 8: %d\n", pitData->GetUnknown8());
for (unsigned int i = 0; i < pitData->GetEntryCount(); i++) for (unsigned int i = 0; i < pitData->GetEntryCount(); i++)
{ {
@ -257,10 +262,6 @@ void Interface::PrintPit(const PitData *pitData)
Interface::Print("All (?)"); Interface::Print("All (?)");
break; break;
case PitEntry::kDeviceTypeUFS:
Interface::Print("UFS");
break;
default: default:
Interface::Print("Unknown"); Interface::Print("Unknown");
break; break;

View File

@ -45,7 +45,7 @@ namespace Heimdall
memset(data, 0, size); memset(data, 0, size);
} }
virtual ~Packet() ~Packet()
{ {
delete [] data; delete [] data;
} }

View File

@ -1,9 +1,11 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.0.0)
project(libpit) project(libpit)
if(NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
endif()
set(LIBPIT_SOURCE_FILES set(LIBPIT_SOURCE_FILES
source/libpit.cpp) source/libpit.cpp)
add_library(pit STATIC ${LIBPIT_SOURCE_FILES}) add_library(pit STATIC ${LIBPIT_SOURCE_FILES})
target_compile_features(pit PRIVATE cxx_std_11)

View File

@ -66,10 +66,17 @@ PitData::PitData()
{ {
entryCount = 0; entryCount = 0;
com_tar2[0] = '\0'; unknown1 = 0;
cpu_bl_id[0] = '\0'; unknown2 = 0;
luCount = 0; unknown3 = 0;
unknown4 = 0;
unknown5 = 0;
unknown6 = 0;
unknown7 = 0;
unknown8 = 0;
} }
PitData::~PitData() PitData::~PitData()
@ -91,14 +98,17 @@ bool PitData::Unpack(const unsigned char *data)
entries.resize(entryCount); entries.resize(entryCount);
if (!memcpy(com_tar2, &data[8], 8)) unknown1 = PitData::UnpackInteger(data, 8);
return (false); unknown2 = PitData::UnpackInteger(data, 12);
com_tar2[8]='\0';
if (!memcpy(cpu_bl_id, &data[16], 8))
return (false);
cpu_bl_id[8]='\0';
luCount = PitData::UnpackShort(data, 24); unknown3 = PitData::UnpackShort(data, 16);
unknown4 = PitData::UnpackShort(data, 18);
unknown5 = PitData::UnpackShort(data, 20);
unknown6 = PitData::UnpackShort(data, 22);
unknown7 = PitData::UnpackShort(data, 24);
unknown8 = PitData::UnpackShort(data, 26);
unsigned int integerValue; unsigned int integerValue;
unsigned int entryOffset; unsigned int entryOffset;
@ -150,10 +160,17 @@ void PitData::Pack(unsigned char *data) const
PitData::PackInteger(data, 4, entryCount); PitData::PackInteger(data, 4, entryCount);
memcpy(&data[8], com_tar2, 8); PitData::PackInteger(data, 8, unknown1);
memcpy(&data[16], cpu_bl_id, 8); PitData::PackInteger(data, 12, unknown2);
PitData::PackShort(data, 24, luCount); PitData::PackShort(data, 16, unknown3);
PitData::PackShort(data, 18, unknown4);
PitData::PackShort(data, 20, unknown5);
PitData::PackShort(data, 22, unknown6);
PitData::PackShort(data, 24, unknown7);
PitData::PackShort(data, 26, unknown8);
int entryOffset; int entryOffset;
@ -184,10 +201,9 @@ void PitData::Pack(unsigned char *data) const
bool PitData::Matches(const PitData *otherPitData) const bool PitData::Matches(const PitData *otherPitData) const
{ {
if (entryCount == otherPitData->entryCount && if (entryCount == otherPitData->entryCount && unknown1 == otherPitData->unknown1 && unknown2 == otherPitData->unknown2
(strncmp(com_tar2, otherPitData->com_tar2, 8) == 0) && && unknown3 == otherPitData->unknown3 && unknown4 == otherPitData->unknown4 && unknown5 == otherPitData->unknown5
(strncmp(cpu_bl_id, otherPitData->cpu_bl_id, 8) == 0) && && unknown6 == otherPitData->unknown6 && unknown7 == otherPitData->unknown7 && unknown8 == otherPitData->unknown8)
luCount == otherPitData->luCount)
{ {
for (unsigned int i = 0; i < entryCount; i++) for (unsigned int i = 0; i < entryCount; i++)
{ {
@ -207,11 +223,17 @@ void PitData::Clear(void)
{ {
entryCount = 0; entryCount = 0;
com_tar2[0] = '\0'; unknown1 = 0;
unknown2 = 0;
cpu_bl_id[0] = '\0'; unknown3 = 0;
unknown4 = 0;
luCount = 0; unknown5 = 0;
unknown6 = 0;
unknown7 = 0;
unknown8 = 0;
for (unsigned int i = 0; i < entries.size(); i++) for (unsigned int i = 0; i < entries.size(); i++)
delete entries[i]; delete entries[i];

View File

@ -25,10 +25,12 @@
#pragma warning(disable : 4996) #pragma warning(disable : 4996)
#endif #endif
#if defined(_MSC_VER) && (_MSC_VER < 1700) #if (!(defined _MSC_VER) || (_MSC_VER < 1700))
# ifndef nullptr
# define nullptr 0 #ifndef nullptr
# endif #define nullptr 0
#endif
#endif #endif
// C/C++ Standard Library // C/C++ Standard Library
@ -61,15 +63,14 @@ namespace libpit
kDeviceTypeOneNand = 0, kDeviceTypeOneNand = 0,
kDeviceTypeFile, // FAT kDeviceTypeFile, // FAT
kDeviceTypeMMC, kDeviceTypeMMC,
kDeviceTypeAll, // ? kDeviceTypeAll // ?
kDeviceTypeUFS = 8
}; };
enum enum
{ {
kAttributeWrite = 1, kAttributeWrite = 1,
kAttributeSTL = 1 << 1 kAttributeSTL = 1 << 1/*,
/* kAttributeBML = 1 << 2 */ // ??? kAttributeBML = 1 << 2*/ // ???
}; };
enum enum
@ -262,11 +263,17 @@ namespace libpit
private: private:
unsigned int entryCount; // 0x04 unsigned int entryCount; // 0x04
char com_tar2[8+1]; // 0x08 unsigned int unknown1; // 0x08
unsigned int unknown2; // 0x0C
char cpu_bl_id[8+1]; // 0x10 unsigned short unknown3; // 0x10
unsigned short unknown4; // 0x12
unsigned short luCount; // 0x18 unsigned short unknown5; // 0x14
unsigned short unknown6; // 0x16
unsigned short unknown7; // 0x18
unsigned short unknown8; // 0x1A
// Entries start at 0x1C // Entries start at 0x1C
std::vector<PitEntry *> entries; std::vector<PitEntry *> entries;
@ -365,19 +372,44 @@ namespace libpit
return paddedSize; return paddedSize;
} }
const char * GetComTar2(void) const unsigned int GetUnknown1(void) const
{ {
return com_tar2; return unknown1;
} }
const char * GetCpuBlId(void) const unsigned int GetUnknown2(void) const
{ {
return cpu_bl_id; return unknown2;
} }
unsigned int GetLUCount(void) const unsigned short GetUnknown3(void) const
{ {
return luCount; return unknown3;
}
unsigned short GetUnknown4(void) const
{
return unknown4;
}
unsigned short GetUnknown5(void) const
{
return unknown5;
}
unsigned short GetUnknown6(void) const
{
return unknown6;
}
unsigned short GetUnknown7(void) const
{
return unknown7;
}
unsigned short GetUnknown8(void) const
{
return unknown8;
} }
}; };
} }