From 46236aad99212af60c179fee176effeade629e26 Mon Sep 17 00:00:00 2001 From: TheFloW Date: Mon, 1 Jan 2018 20:10:45 +0100 Subject: [PATCH] Fixed bug where archives > 2GB couldn't be opened --- CMakeLists.txt | 2 +- README.md | 3 + archive.c | 93 +++++++++++++++++++++- main.h | 2 +- pkg/sce_sys/livearea/contents/template.xml | 2 +- resources/changeinfo.txt | 5 ++ 6 files changed, 101 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19661151..6a193c11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ project(VitaShell) include("${VITASDK}/share/vita.cmake" REQUIRED) set(VITA_APP_NAME "VitaShell") set(VITA_TITLEID "VITASHELL") -set(VITA_VERSION "01.77") +set(VITA_VERSION "01.78") # Flags and includes set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -Wno-unused-variable -Wno-unused-but-set-variable -Wno-format-truncation -fno-lto") diff --git a/README.md b/README.md index 38838c61..3b367fea 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,9 @@ The english language file is provided in **'VitaShellCustomization.rar'** and av * sakya for Lightmp3 * Everybody who contributed on vitasdk +### Changelog 1.78 ### +- Fixed bug where archives > 2GB couldn't be opened. + ### Changelog 1.77 ### - Added archive support for .7z, .tar.gz, .tar.bz2 and more by using libarchive. - Improved archive file system (opening archives should now be much faster). diff --git a/archive.c b/archive.c index 00a605f0..29dc0285 100644 --- a/archive.c +++ b/archive.c @@ -34,6 +34,93 @@ void waitpid() {} void __archive_create_child() {} void __archive_check_child() {} +struct archive_data { + const char *filename; + SceUID fd; + void *buffer; + int block_size; +}; + +static int file_open(struct archive *a, void *client_data) { + struct archive_data *archive_data = client_data; + + archive_data->fd = sceIoOpen(archive_data->filename, SCE_O_RDONLY, 0); + if (archive_data->fd < 0) + return ARCHIVE_FATAL; + + archive_data->buffer = malloc(TRANSFER_SIZE); + archive_data->block_size = TRANSFER_SIZE; + + return ARCHIVE_OK; +} + +static ssize_t file_read(struct archive *a, void *client_data, const void **buff) { + struct archive_data *archive_data = client_data; + *buff = archive_data->buffer; + return sceIoRead(archive_data->fd, archive_data->buffer, archive_data->block_size); +} + +static int64_t file_skip(struct archive *a, void *client_data, int64_t request) { + struct archive_data *archive_data = client_data; + int64_t old_offset, new_offset; + + if ((old_offset = sceIoLseek(archive_data->fd, 0, SCE_SEEK_CUR)) >= 0 && + (new_offset = sceIoLseek(archive_data->fd, request, SCE_SEEK_CUR)) >= 0) + return new_offset - old_offset; + + return -1; +} + +static int64_t file_seek(struct archive *a, void *client_data, int64_t request, int whence) { + struct archive_data *archive_data = client_data; + int64_t r; + + r = sceIoLseek(archive_data->fd, request, whence); + if (r >= 0) + return r; + + return ARCHIVE_FATAL; +} + +static int file_close2(struct archive *a, void *client_data) { + struct archive_data *archive_data = client_data; + + if (archive_data->fd >= 0) { + sceIoClose(archive_data->fd); + archive_data->fd = -1; + } + + free(archive_data->buffer); + archive_data->buffer = NULL; + + return ARCHIVE_OK; +} + +static int file_close(struct archive *a, void *client_data) { + struct archive_data *archive_data = client_data; + file_close2(a, client_data); + free(archive_data); + return ARCHIVE_OK; +} + +static int file_switch(struct archive *a, void *client_data1, void *client_data2) { + file_close2(a, client_data1); + return file_open(a, client_data2); +} + +int open_archive(struct archive *a, const char *filename) { + struct archive_data *archive_data = malloc(sizeof(struct archive_data)); + archive_data->filename = filename; + archive_read_append_callback_data(a, archive_data); + archive_read_set_open_callback(a, file_open); + archive_read_set_read_callback(a, file_read); + archive_read_set_skip_callback(a, file_skip); + archive_read_set_close_callback(a, file_close); + archive_read_set_switch_callback(a, file_switch); + archive_read_set_seek_callback(a, file_seek); + return archive_read_open1(a); +} + typedef struct ArchiveFileNode { struct ArchiveFileNode *parent; struct ArchiveFileNode *child; @@ -217,7 +304,7 @@ int archiveCheckFilesForUnsafeFself() { archive_read_support_format_all(archive); // Open archive file - res = archive_read_open_filename(archive, archive_file, 10240); + res = open_archive(archive, archive_file); if (res) return 0; @@ -549,7 +636,7 @@ int archiveFileOpen(const char *file, int flags, SceMode mode) { archive_read_support_format_all(archive_fd); // Open archive file - res = archive_read_open_filename(archive_fd, archive_file, 10240); + res = open_archive(archive_fd, archive_file); if (res) return -1; @@ -623,7 +710,7 @@ int archiveOpen(const char *file) { archive_read_support_format_all(archive); // Open archive file - res = archive_read_open_filename(archive, file, 10240); + res = open_archive(archive, file); if (res) return -1; diff --git a/main.h b/main.h index 297b4d1a..b40e1d01 100644 --- a/main.h +++ b/main.h @@ -53,7 +53,7 @@ // VitaShell version major.minor #define VITASHELL_VERSION_MAJOR 0x01 -#define VITASHELL_VERSION_MINOR 0x77 +#define VITASHELL_VERSION_MINOR 0x78 #define VITASHELL_VERSION ((VITASHELL_VERSION_MAJOR << 0x18) | (VITASHELL_VERSION_MINOR << 0x10)) diff --git a/pkg/sce_sys/livearea/contents/template.xml b/pkg/sce_sys/livearea/contents/template.xml index aa4b642f..ca250a2a 100644 --- a/pkg/sce_sys/livearea/contents/template.xml +++ b/pkg/sce_sys/livearea/contents/template.xml @@ -28,7 +28,7 @@ - v1.77 + v1.78 diff --git a/resources/changeinfo.txt b/resources/changeinfo.txt index 4080d6c8..a9137c4f 100644 --- a/resources/changeinfo.txt +++ b/resources/changeinfo.txt @@ -323,4 +323,9 @@ - Fixed Electron theme visual glitch and added new settings look (thanks to Acemad).
]]> + + 2GB couldn't be opened.
+ ]]> +