Fix crashes on Windows when configuration directory could not be created. Fix problems when configuration directory path contains special characters.
git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@2015 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
9610c0f63d
commit
7cc8825ef1
@ -9,6 +9,11 @@
|
|||||||
(inspired by a patch from Yura Siamashka).
|
(inspired by a patch from Yura Siamashka).
|
||||||
* src/plugindata.h, src/plugins.c:
|
* src/plugindata.h, src/plugins.c:
|
||||||
Add document_set_text_changed() to the plugin API.
|
Add document_set_text_changed() to the plugin API.
|
||||||
|
* src/main.c, src/utils.c, src/utils.h, src/win32.c, src/win32.h:
|
||||||
|
Fix crashes on Windows when configuration directory could not be
|
||||||
|
created.
|
||||||
|
Fix problems when configuration directory path contains special
|
||||||
|
characters.
|
||||||
|
|
||||||
|
|
||||||
2007-11-02 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
|
2007-11-02 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
|
||||||
|
|||||||
@ -500,7 +500,7 @@ static gint setup_config_dir()
|
|||||||
app->configdir = utils_get_locale_from_utf8(app->configdir);
|
app->configdir = utils_get_locale_from_utf8(app->configdir);
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
|
|
||||||
mkdir_result = utils_make_settings_dir(app->configdir, app->datadir, app->docdir);
|
mkdir_result = utils_make_settings_dir();
|
||||||
if (mkdir_result != 0)
|
if (mkdir_result != 0)
|
||||||
{
|
{
|
||||||
if (! dialogs_show_question(
|
if (! dialogs_show_question(
|
||||||
|
|||||||
55
src/utils.c
55
src/utils.c
@ -727,26 +727,33 @@ gchar *utils_get_hostname()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gint utils_make_settings_dir(const gchar *dir, const gchar *data_dir, const gchar *doc_dir)
|
gint utils_make_settings_dir()
|
||||||
{
|
{
|
||||||
gint error_nr = 0;
|
gint saved_errno = 0;
|
||||||
gchar *conf_file = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "geany.conf", NULL);
|
gchar *conf_file = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "geany.conf", NULL);
|
||||||
gchar *filedefs_dir = g_strconcat(dir, G_DIR_SEPARATOR_S,
|
gchar *filedefs_dir = g_strconcat(app->configdir, G_DIR_SEPARATOR_S,
|
||||||
GEANY_FILEDEFS_SUBDIR, G_DIR_SEPARATOR_S, NULL);
|
GEANY_FILEDEFS_SUBDIR, G_DIR_SEPARATOR_S, NULL);
|
||||||
|
|
||||||
gchar *templates_dir = g_strconcat(dir, G_DIR_SEPARATOR_S,
|
gchar *templates_dir = g_strconcat(app->configdir, G_DIR_SEPARATOR_S,
|
||||||
GEANY_TEMPLATES_SUBDIR, G_DIR_SEPARATOR_S, NULL);
|
GEANY_TEMPLATES_SUBDIR, G_DIR_SEPARATOR_S, NULL);
|
||||||
|
|
||||||
if (! g_file_test(dir, G_FILE_TEST_EXISTS))
|
if (! g_file_test(app->configdir, G_FILE_TEST_EXISTS))
|
||||||
{
|
{
|
||||||
geany_debug("creating config directory %s", dir);
|
geany_debug("creating config directory %s", app->configdir);
|
||||||
error_nr = utils_mkdir(dir, FALSE);
|
saved_errno = utils_mkdir(app->configdir, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error_nr == 0 && ! g_file_test(conf_file, G_FILE_TEST_EXISTS))
|
if (saved_errno == 0 && ! g_file_test(conf_file, G_FILE_TEST_EXISTS))
|
||||||
{ // try to write geany.conf
|
{ // check whether geany.conf can be written
|
||||||
error_nr = access(app->configdir, W_OK);
|
#ifdef G_OS_WIN32
|
||||||
|
// use _waccess on Windows, access() doesn't accept special characters
|
||||||
|
saved_errno = win32_check_write_permission(app->configdir);
|
||||||
|
#else
|
||||||
|
access(app->configdir, R_OK | W_OK);
|
||||||
|
#endif
|
||||||
|
saved_errno = errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
# define DIR_SEP "\\" // on Windows we need an additional dir separator
|
# define DIR_SEP "\\" // on Windows we need an additional dir separator
|
||||||
#else
|
#else
|
||||||
@ -754,21 +761,21 @@ gint utils_make_settings_dir(const gchar *dir, const gchar *data_dir, const gcha
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// make subdir for filetype definitions
|
// make subdir for filetype definitions
|
||||||
if (error_nr == 0)
|
if (saved_errno == 0)
|
||||||
{
|
{
|
||||||
gchar *filedefs_readme = g_strconcat(dir, G_DIR_SEPARATOR_S, GEANY_FILEDEFS_SUBDIR,
|
gchar *filedefs_readme = g_strconcat(app->configdir, G_DIR_SEPARATOR_S,
|
||||||
G_DIR_SEPARATOR_S, "filetypes.README", NULL);
|
GEANY_FILEDEFS_SUBDIR, G_DIR_SEPARATOR_S, "filetypes.README", NULL);
|
||||||
|
|
||||||
if (! g_file_test(filedefs_dir, G_FILE_TEST_EXISTS))
|
if (! g_file_test(filedefs_dir, G_FILE_TEST_EXISTS))
|
||||||
{
|
{
|
||||||
error_nr = utils_mkdir(filedefs_dir, FALSE);
|
saved_errno = utils_mkdir(filedefs_dir, FALSE);
|
||||||
}
|
}
|
||||||
if (error_nr == 0 && ! g_file_test(filedefs_readme, G_FILE_TEST_EXISTS))
|
if (saved_errno == 0 && ! g_file_test(filedefs_readme, G_FILE_TEST_EXISTS))
|
||||||
{
|
{
|
||||||
gchar *text = g_strconcat(
|
gchar *text = g_strconcat(
|
||||||
"Copy files from ", data_dir, " to this directory to overwrite "
|
"Copy files from ", app->datadir, " to this directory to overwrite "
|
||||||
"them. To use the defaults, just delete the file in this directory.\nFor more information read "
|
"them. To use the defaults, just delete the file in this directory.\nFor more information read "
|
||||||
"the documentation (in ", doc_dir, DIR_SEP "index.html or visit " GEANY_HOMEPAGE ").", NULL);
|
"the documentation (in ", app->docdir, DIR_SEP "index.html or visit " GEANY_HOMEPAGE ").", NULL);
|
||||||
utils_write_file(filedefs_readme, text);
|
utils_write_file(filedefs_readme, text);
|
||||||
g_free(text);
|
g_free(text);
|
||||||
}
|
}
|
||||||
@ -776,20 +783,20 @@ gint utils_make_settings_dir(const gchar *dir, const gchar *data_dir, const gcha
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make subdir for template files
|
// make subdir for template files
|
||||||
if (error_nr == 0)
|
if (saved_errno == 0)
|
||||||
{
|
{
|
||||||
gchar *templates_readme = g_strconcat(dir, G_DIR_SEPARATOR_S, GEANY_TEMPLATES_SUBDIR,
|
gchar *templates_readme = g_strconcat(app->configdir, G_DIR_SEPARATOR_S,
|
||||||
G_DIR_SEPARATOR_S, "templates.README", NULL);
|
GEANY_TEMPLATES_SUBDIR, G_DIR_SEPARATOR_S, "templates.README", NULL);
|
||||||
|
|
||||||
if (! g_file_test(templates_dir, G_FILE_TEST_EXISTS))
|
if (! g_file_test(templates_dir, G_FILE_TEST_EXISTS))
|
||||||
{
|
{
|
||||||
error_nr = utils_mkdir(templates_dir, FALSE);
|
saved_errno = utils_mkdir(templates_dir, FALSE);
|
||||||
}
|
}
|
||||||
if (error_nr == 0 && ! g_file_test(templates_readme, G_FILE_TEST_EXISTS))
|
if (saved_errno == 0 && ! g_file_test(templates_readme, G_FILE_TEST_EXISTS))
|
||||||
{
|
{
|
||||||
gchar *text = g_strconcat(
|
gchar *text = g_strconcat(
|
||||||
"There are several template files in this directory. For these templates you can use wildcards.\n\
|
"There are several template files in this directory. For these templates you can use wildcards.\n\
|
||||||
For more information read the documentation (in ", doc_dir, DIR_SEP "index.html or visit " GEANY_HOMEPAGE ").",
|
For more information read the documentation (in ", app->docdir, DIR_SEP "index.html or visit " GEANY_HOMEPAGE ").",
|
||||||
NULL);
|
NULL);
|
||||||
utils_write_file(templates_readme, text);
|
utils_write_file(templates_readme, text);
|
||||||
g_free(text);
|
g_free(text);
|
||||||
@ -801,7 +808,7 @@ For more information read the documentation (in ", doc_dir, DIR_SEP "index.html
|
|||||||
g_free(templates_dir);
|
g_free(templates_dir);
|
||||||
g_free(conf_file);
|
g_free(conf_file);
|
||||||
|
|
||||||
return error_nr;
|
return saved_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -97,7 +97,7 @@ gchar utils_brace_opposite(gchar ch);
|
|||||||
|
|
||||||
gchar *utils_get_hostname();
|
gchar *utils_get_hostname();
|
||||||
|
|
||||||
gint utils_make_settings_dir(const gchar *dir, const gchar *data_dir, const gchar *doc_dir);
|
gint utils_make_settings_dir();
|
||||||
|
|
||||||
|
|
||||||
gboolean utils_string_replace_all(GString *str, const gchar *needle, const gchar *replace);
|
gboolean utils_string_replace_all(GString *str, const gchar *needle, const gchar *replace);
|
||||||
|
|||||||
28
src/win32.c
28
src/win32.c
@ -34,6 +34,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -492,6 +493,7 @@ gboolean win32_message_dialog(GtkWidget *parent, GtkMessageType type, const gcha
|
|||||||
gint rc;
|
gint rc;
|
||||||
guint t;
|
guint t;
|
||||||
const gchar *title;
|
const gchar *title;
|
||||||
|
HWND parent_hwnd = NULL;
|
||||||
static wchar_t w_msg[512];
|
static wchar_t w_msg[512];
|
||||||
static wchar_t w_title[512];
|
static wchar_t w_title[512];
|
||||||
|
|
||||||
@ -528,11 +530,13 @@ gboolean win32_message_dialog(GtkWidget *parent, GtkMessageType type, const gcha
|
|||||||
MultiByteToWideChar(CP_UTF8, 0, msg, -1, w_msg, G_N_ELEMENTS(w_msg));
|
MultiByteToWideChar(CP_UTF8, 0, msg, -1, w_msg, G_N_ELEMENTS(w_msg));
|
||||||
MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, G_N_ELEMENTS(w_title));
|
MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, G_N_ELEMENTS(w_title));
|
||||||
|
|
||||||
// display the message box
|
if (parent != NULL)
|
||||||
if (parent == NULL)
|
parent_hwnd = GDK_WINDOW_HWND(parent->window);
|
||||||
parent = app->window;
|
else if (app->window != NULL)
|
||||||
|
parent_hwnd = GDK_WINDOW_HWND(app->window->window);
|
||||||
|
|
||||||
rc = MessageBoxW(GDK_WINDOW_HWND(parent->window), w_msg, w_title, t);
|
// display the message box
|
||||||
|
rc = MessageBoxW(parent_hwnd, w_msg, w_title, t);
|
||||||
|
|
||||||
if (type == GTK_MESSAGE_QUESTION && rc != IDYES)
|
if (type == GTK_MESSAGE_QUESTION && rc != IDYES)
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
@ -541,18 +545,32 @@ gboolean win32_message_dialog(GtkWidget *parent, GtkMessageType type, const gcha
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Little wrapper for _waccess(), returns errno or 0 if there was no error */
|
||||||
|
gint win32_check_write_permission(const gchar *dir)
|
||||||
|
{
|
||||||
|
static wchar_t w_dir[512];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, app->configdir, -1, w_dir, sizeof w_dir);
|
||||||
|
_waccess(w_dir, R_OK | W_OK);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Special dialog to ask for an action when closing an unsaved file */
|
/* Special dialog to ask for an action when closing an unsaved file */
|
||||||
gint win32_message_dialog_unsaved(const gchar *msg)
|
gint win32_message_dialog_unsaved(const gchar *msg)
|
||||||
{
|
{
|
||||||
static wchar_t w_msg[512];
|
static wchar_t w_msg[512];
|
||||||
static wchar_t w_title[512];
|
static wchar_t w_title[512];
|
||||||
|
HWND parent_hwnd = NULL;
|
||||||
gint ret;
|
gint ret;
|
||||||
|
|
||||||
// convert the Unicode chars to wide chars
|
// convert the Unicode chars to wide chars
|
||||||
MultiByteToWideChar(CP_UTF8, 0, msg, -1, w_msg, G_N_ELEMENTS(w_msg));
|
MultiByteToWideChar(CP_UTF8, 0, msg, -1, w_msg, G_N_ELEMENTS(w_msg));
|
||||||
MultiByteToWideChar(CP_UTF8, 0, _("Question"), -1, w_title, G_N_ELEMENTS(w_title));
|
MultiByteToWideChar(CP_UTF8, 0, _("Question"), -1, w_title, G_N_ELEMENTS(w_title));
|
||||||
|
|
||||||
ret = MessageBoxW(GDK_WINDOW_HWND(app->window->window), w_msg, w_title, MB_YESNOCANCEL | MB_ICONQUESTION);
|
if (app->window != NULL)
|
||||||
|
parent_hwnd = GDK_WINDOW_HWND(app->window->window);
|
||||||
|
|
||||||
|
ret = MessageBoxW(parent_hwnd, w_msg, w_title, MB_YESNOCANCEL | MB_ICONQUESTION);
|
||||||
switch(ret)
|
switch(ret)
|
||||||
{
|
{
|
||||||
case IDYES: ret = GTK_RESPONSE_YES; break;
|
case IDYES: ret = GTK_RESPONSE_YES; break;
|
||||||
|
|||||||
@ -53,4 +53,6 @@ gchar *win32_show_project_open_dialog(const gchar *title, const gchar *initial_d
|
|||||||
* The selected folder name is returned. */
|
* The selected folder name is returned. */
|
||||||
gchar *win32_show_project_folder_dialog(const gchar *title, const gchar *initial_dir);
|
gchar *win32_show_project_folder_dialog(const gchar *title, const gchar *initial_dir);
|
||||||
|
|
||||||
|
gint win32_check_write_permission(const gchar *dir);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user