From f7b988906eb58d9718eb21c8a28620f6c4481be4 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Wed, 28 Dec 2022 10:46:02 +0100 Subject: [PATCH] fix: Saving projects to unicode paths not working correctly --- lib/external/microtar/include/microtar.h | 1 + lib/external/microtar/source/microtar.c | 35 ++++++++++++++++++++++++ lib/libimhex/source/helpers/tar.cpp | 27 ++++++++++++------ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/lib/external/microtar/include/microtar.h b/lib/external/microtar/include/microtar.h index 2e73e919a..5798a8074 100644 --- a/lib/external/microtar/include/microtar.h +++ b/lib/external/microtar/include/microtar.h @@ -71,6 +71,7 @@ struct mtar_t { const char *mtar_strerror(int err); int mtar_open(mtar_t *tar, const char *filename, const char *mode); +int mtar_wopen(mtar_t *tar, const wchar_t *filename, const wchar_t *mode); int mtar_close(mtar_t *tar); int mtar_seek(mtar_t *tar, unsigned pos); diff --git a/lib/external/microtar/source/microtar.c b/lib/external/microtar/source/microtar.c index a1f720578..15a64233c 100644 --- a/lib/external/microtar/source/microtar.c +++ b/lib/external/microtar/source/microtar.c @@ -207,6 +207,41 @@ int mtar_open(mtar_t *tar, const char *filename, const char *mode) { return MTAR_ESUCCESS; } +#if defined (_WIN32) +int mtar_wopen(mtar_t *tar, const wchar_t *filename, const wchar_t *mode) { + int err; + mtar_header_t h; + + /* Init tar struct and functions */ + memset(tar, 0, sizeof(*tar)); + tar->write = file_write; + tar->read = file_read; + tar->seek = file_seek; + tar->close = file_close; + + /* Assure mode is always binary */ + if ( filename[0] == L'r' ) mode = L"rb"; + if ( filename[0] == L'w' ) mode = L"wb"; + if ( filename[0] == L'a' ) mode = L"ab"; + /* Open file */ + tar->stream = _wfopen(filename, mode); + if (!tar->stream) { + return MTAR_EOPENFAIL; + } + /* Read first header to check it is valid if mode is `r` */ + if (*mode == L'r') { + err = mtar_read_header(tar, &h); + if (err != MTAR_ESUCCESS) { + mtar_close(tar); + return err; + } + } + + /* Return ok */ + return MTAR_ESUCCESS; +} +#endif + int mtar_close(mtar_t *tar) { return tar->close(tar); diff --git a/lib/libimhex/source/helpers/tar.cpp b/lib/libimhex/source/helpers/tar.cpp index 033bdbfa5..e8f441dcd 100644 --- a/lib/libimhex/source/helpers/tar.cpp +++ b/lib/libimhex/source/helpers/tar.cpp @@ -9,14 +9,25 @@ namespace hex { Tar::Tar(const std::fs::path &path, Mode mode) { int error = MTAR_ESUCCESS; - if (mode == Tar::Mode::Read) - error = mtar_open(&this->m_ctx, path.string().c_str(), "r"); - else if (mode == Tar::Mode::Write) - error = mtar_open(&this->m_ctx, path.string().c_str(), "a"); - else if (mode == Tar::Mode::Create) - error = mtar_open(&this->m_ctx, path.string().c_str(), "w"); - else - error = MTAR_EFAILURE; + #if defined (OS_WINDOWS) + if (mode == Tar::Mode::Read) + error = mtar_wopen(&this->m_ctx, path.c_str(), L"r"); + else if (mode == Tar::Mode::Write) + error = mtar_wopen(&this->m_ctx, path.c_str(), L"a"); + else if (mode == Tar::Mode::Create) + error = mtar_wopen(&this->m_ctx, path.c_str(), L"w"); + else + error = MTAR_EFAILURE; + #else + if (mode == Tar::Mode::Read) + error = mtar_open(&this->m_ctx, path.c_str(), "r"); + else if (mode == Tar::Mode::Write) + error = mtar_open(&this->m_ctx, path.c_str(), "a"); + else if (mode == Tar::Mode::Create) + error = mtar_open(&this->m_ctx, path.c_str(), "w"); + else + error = MTAR_EFAILURE; + #endif this->m_valid = (error == MTAR_ESUCCESS); }