From 54e7ec8e7917b6d74bc290b90acd4cfdd48c6489 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 2 Jan 2018 20:21:55 -0500 Subject: [PATCH] win32: use Unicode file I/O for 7zip archives when available --- CHANGES.md | 2 +- libretro-common/file/archive_file_7z.c | 47 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 4e7c7080db..83effa6e63 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,7 +20,7 @@ - NSW: Initial Nintendo Switch port, based on libtransistor SDK. - PS3: Enable Cheevos. - PSP: Enable threading support through pthreads. -- WINDOWS: Improved Unicode support (for cores/directory creation). +- WINDOWS: Improved Unicode support (for cores/directory creation and 7zip archives). - WINDOWS: Show progress meter on taskbar for downloads (Windows 7 and up). - WIIU: Overlay support. - WIIU: Transparency support in menu + overlays. diff --git a/libretro-common/file/archive_file_7z.c b/libretro-common/file/archive_file_7z.c index 502e873c94..73a04f9336 100644 --- a/libretro-common/file/archive_file_7z.c +++ b/libretro-common/file/archive_file_7z.c @@ -39,6 +39,13 @@ #define SEVENZIP_MAGIC "7z\xBC\xAF\x27\x1C" #define SEVENZIP_MAGIC_LEN 6 +/* Assume W-functions do not work below Win2K and Xbox platforms */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) +#ifndef LEGACY_WIN32 +#define LEGACY_WIN32 +#endif +#endif + struct sevenzip_context_t { CFileInStream archiveStream; CLookToRead lookStream; @@ -127,6 +134,9 @@ static int sevenzip_file_read( CSzArEx db; uint8_t *output = 0; long outsize = -1; +#ifndef LEGACY_WIN32 + wchar_t *pathW = NULL; +#endif /*These are the allocation routines. * Currently using the non-standard 7zip choices. */ @@ -135,10 +145,28 @@ static int sevenzip_file_read( allocTempImp.Alloc = sevenzip_stream_alloc_tmp_impl; allocTempImp.Free = sevenzip_stream_free_impl; +#ifdef LEGACY_WIN32 /* Could not open 7zip archive? */ if (InFile_Open(&archiveStream.file, path)) return -1; +#else + if (!string_is_empty(path)) + { + pathW = utf8_to_utf16_string_alloc(path); + if (pathW) + { + /* Could not open 7zip archive? */ + if (InFile_OpenW(&archiveStream.file, pathW)) + { + free(pathW); + return -1; + } + + free(pathW); + } + } +#endif FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, false); lookStream.realStream = &archiveStream.s; @@ -325,6 +353,9 @@ static int sevenzip_parse_file_init(file_archive_transfer_t *state, { struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)sevenzip_stream_new(); +#ifndef LEGACY_WIN32 + wchar_t *fileW = NULL; +#endif if (state->archive_size < SEVENZIP_MAGIC_LEN) goto error; @@ -334,9 +365,25 @@ static int sevenzip_parse_file_init(file_archive_transfer_t *state, state->stream = sevenzip_context; +#ifdef LEGACY_WIN32 /* could not open 7zip archive? */ if (InFile_Open(&sevenzip_context->archiveStream.file, file)) goto error; +#else + fileW = utf8_to_utf16_string_alloc(file); + + if (fileW) + { + /* could not open 7zip archive? */ + if (InFile_OpenW(&sevenzip_context->archiveStream.file, fileW)) + { + free(fileW); + goto error; + } + + free(fileW); + } +#endif FileInStream_CreateVTable(&sevenzip_context->archiveStream); LookToRead_CreateVTable(&sevenzip_context->lookStream, false);