fix memory corruption with windows file dialogs for load core/content

This commit is contained in:
Brad Parker 2016-12-16 21:11:08 -05:00
parent c1d9f6c30c
commit 1d2600f5f3
2 changed files with 40 additions and 17 deletions

View File

@ -24,6 +24,9 @@
#pragma comment( lib, "comctl32" ) #pragma comment( lib, "comctl32" )
#endif #endif
#define TITLE_MAX PATH_MAX
#define FULLPATH_MAX 32768
#define IDI_ICON 1 #define IDI_ICON 1
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
@ -36,6 +39,7 @@
#include <commctrl.h> #include <commctrl.h>
#include <retro_inline.h> #include <retro_inline.h>
#include <retro_miscellaneous.h>
#include <file/file_path.h> #include <file/file_path.h>
#include "../ui_companion_driver.h" #include "../ui_companion_driver.h"
@ -508,25 +512,36 @@ static bool win32_browser(
const char *initial_dir) const char *initial_dir)
{ {
bool result = false; bool result = false;
char empty[1] = {0};
const ui_browser_window_t *browser = const ui_browser_window_t *browser =
ui_companion_driver_get_browser_window_ptr(); ui_companion_driver_get_browser_window_ptr();
if (browser) if (browser)
{ {
ui_browser_window_state_t browser_state; ui_browser_window_state_t browser_state;
/* OPENFILENAME.lpstrFilter requires a null separated list of name/ext pairs terminated by a second null at the end. */
char *all_files[] = {"All Files", "*.*", ""};
browser_state.filters = strdup(extensions); /* These need to be big enough to hold the path/name of any file the user may select.
browser_state.title = strdup(title); * FIXME: We should really handle the error case when this isn't big enough. */
browser_state.startdir = strdup(initial_dir); char new_title[TITLE_MAX] = {0};
browser_state.path = strdup(filename); char new_file[FULLPATH_MAX] = {0};
if (title && *title)
strlcpy(new_title, title, sizeof(new_title));
if (filename && *filename)
strlcpy(new_file, filename, sizeof(new_file));
browser_state.filters = all_files[0];
browser_state.title = new_title;
browser_state.startdir = (initial_dir && *initial_dir) ? strdup(initial_dir) : strdup(empty);
browser_state.path = new_file;
browser_state.window = owner; browser_state.window = owner;
result = browser->open(&browser_state); result = browser->open(&browser_state);
free(browser_state.filters);
free(browser_state.title);
free(browser_state.startdir); free(browser_state.startdir);
free(browser_state.path);
} }
return result; return result;
@ -545,9 +560,12 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam)
case ID_M_LOAD_CONTENT: case ID_M_LOAD_CONTENT:
{ {
char win32_file[PATH_MAX_LENGTH] = {0}; char win32_file[PATH_MAX_LENGTH] = {0};
wchar_t title_wide[PATH_MAX] = {0};
char title_cp[PATH_MAX] = {0};
const char *extensions = NULL; const char *extensions = NULL;
const char *title = NULL; const char *title = NULL;
const char *initial_dir = NULL; const char *initial_dir = NULL;
size_t converted = 0;
switch (mode) switch (mode)
{ {
@ -564,8 +582,13 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam)
break; break;
} }
/* Convert UTF8 to UTF16, then back to the local code page.
* This is needed for proper multi-byte string display until Unicode is fully supported. */
MultiByteToWideChar(CP_UTF8, 0, title, -1, title_wide, sizeof(title_wide) / sizeof(title_wide[0]));
wcstombs_s(&converted, title_cp, sizeof(title_cp), title_wide, sizeof(title_cp) - 1);
if (!win32_browser(owner, win32_file, if (!win32_browser(owner, win32_file,
extensions, title, initial_dir)) extensions, title_cp, initial_dir))
break; break;
switch (mode) switch (mode)

View File

@ -37,9 +37,9 @@ static bool ui_browser_window_win32_core(ui_browser_window_state_t *state, bool
ofn.nMaxFile = PATH_MAX; ofn.nMaxFile = PATH_MAX;
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
if ( save && !GetOpenFileName(&ofn)) if (!save && !GetOpenFileName(&ofn))
return false; return false;
if (!save && !GetSaveFileName(&ofn)) if ( save && !GetSaveFileName(&ofn))
return false; return false;
return true; return true;