From 795f4eb106d877ba6f2bd30524cc871404e9e42a Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Tue, 13 Dec 2016 10:33:02 -0800 Subject: Qt+Win32: Make software updates more friendly. Add WinSparkle can_shutdown and shutdown_request callbacks which are called prior to running the installer. Reject updates when we have unsaved information. Add notes about possible improvements. Ping-Bug: 9687 Ping-Bug: 12989 Change-Id: Ia126244b311417aa3105ea8136f186adc2745445 Reviewed-on: https://code.wireshark.org/review/19244 Reviewed-by: Gerald Combs Petri-Dish: Gerald Combs Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman --- wsutil/file_util.c | 632 +++++++++++++++++++++++++++-------------------------- wsutil/file_util.h | 4 + 2 files changed, 323 insertions(+), 313 deletions(-) (limited to 'wsutil') diff --git a/wsutil/file_util.c b/wsutil/file_util.c index cdbe0a4f01..abd4ccab03 100644 --- a/wsutil/file_util.c +++ b/wsutil/file_util.c @@ -96,27 +96,25 @@ static gchar *npcap_path = NULL; * Since: 2.6 */ int -ws_stdio_open (const gchar *filename, - int flags, - int mode) +ws_stdio_open (const gchar *filename, int flags, int mode) { - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } - retval = _wopen (wfilename, flags, mode); - save_errno = errno; + retval = _wopen (wfilename, flags, mode); + save_errno = errno; - g_free (wfilename); + g_free (wfilename); - errno = save_errno; - return retval; + errno = save_errno; + return retval; } @@ -138,36 +136,35 @@ ws_stdio_open (const gchar *filename, * Since: 2.6 */ int -ws_stdio_rename (const gchar *oldfilename, - const gchar *newfilename) +ws_stdio_rename (const gchar *oldfilename, const gchar *newfilename) { - wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL); - wchar_t *wnewfilename; - int retval; - int save_errno = 0; - - if (woldfilename == NULL) - { - errno = EINVAL; - return -1; - } - - wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL); - - if (wnewfilename == NULL) - { - g_free (woldfilename); - errno = EINVAL; - return -1; - } - - if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING)) + wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL); + wchar_t *wnewfilename; + int retval; + int save_errno = 0; + + if (woldfilename == NULL) + { + errno = EINVAL; + return -1; + } + + wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL); + + if (wnewfilename == NULL) + { + g_free (woldfilename); + errno = EINVAL; + return -1; + } + + if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING)) retval = 0; - else + else + { + retval = -1; + switch (GetLastError ()) { - retval = -1; - switch (GetLastError ()) - { #define CASE(a,b) case ERROR_##a: save_errno = b; break CASE (FILE_NOT_FOUND, ENOENT); CASE (PATH_NOT_FOUND, ENOENT); @@ -179,14 +176,14 @@ ws_stdio_rename (const gchar *oldfilename, CASE (ALREADY_EXISTS, EEXIST); #undef CASE default: save_errno = EIO; - } } + } - g_free (woldfilename); - g_free (wnewfilename); + g_free (woldfilename); + g_free (wnewfilename); - errno = save_errno; - return retval; + errno = save_errno; + return retval; } /** @@ -205,26 +202,25 @@ ws_stdio_rename (const gchar *oldfilename, * Since: 2.6 */ int -ws_stdio_mkdir (const gchar *filename, - int mode) +ws_stdio_mkdir (const gchar *filename, int mode) { - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } - retval = _wmkdir (wfilename); - save_errno = errno; + retval = _wmkdir (wfilename); + save_errno = errno; - g_free (wfilename); + g_free (wfilename); - errno = save_errno; - return retval; + errno = save_errno; + return retval; } /** @@ -244,34 +240,33 @@ ws_stdio_mkdir (const gchar *filename, * Since: 2.6 */ int -ws_stdio_stat64 (const gchar *filename, - ws_statb64 *buf) +ws_stdio_stat64 (const gchar *filename, ws_statb64 *buf) { - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - size_t len; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - len = wcslen (wfilename); - while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1])) + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + size_t len; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + len = wcslen (wfilename); + while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1])) len--; - if (len > 0 && - (!g_path_is_absolute (filename) || len > (size_t) (g_path_skip_root (filename) - filename))) + if (len > 0 && + (!g_path_is_absolute (filename) || len > (size_t) (g_path_skip_root (filename) - filename))) wfilename[len] = '\0'; - retval = _wstati64 (wfilename, buf); - save_errno = errno; + retval = _wstati64 (wfilename, buf); + save_errno = errno; - g_free (wfilename); + g_free (wfilename); - errno = save_errno; - return retval; + errno = save_errno; + return retval; } /** * g_unlink: @@ -295,23 +290,23 @@ ws_stdio_stat64 (const gchar *filename, int ws_stdio_unlink (const gchar *filename) { - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } - retval = _wunlink (wfilename); - save_errno = errno; + retval = _wunlink (wfilename); + save_errno = errno; - g_free (wfilename); + g_free (wfilename); - errno = save_errno; - return retval; + errno = save_errno; + return retval; } /** @@ -343,25 +338,25 @@ ws_stdio_unlink (const gchar *filename) int ws_stdio_remove (const gchar *filename) { - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wremove (wfilename); - if (retval == -1) + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wremove (wfilename); + if (retval == -1) retval = _wrmdir (wfilename); - save_errno = errno; + save_errno = errno; - g_free (wfilename); + g_free (wfilename); - errno = save_errno; - return retval; + errno = save_errno; + return retval; } /** @@ -381,37 +376,36 @@ ws_stdio_remove (const gchar *filename) * Since: 2.6 */ FILE * -ws_stdio_fopen (const gchar *filename, - const gchar *mode) +ws_stdio_fopen (const gchar *filename, const gchar *mode) { - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - wchar_t *wmode; - FILE *retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return NULL; - } - - wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); - - if (wmode == NULL) - { - g_free (wfilename); - errno = EINVAL; - return NULL; - } - - retval = _wfopen (wfilename, wmode); - save_errno = errno; - - g_free (wfilename); - g_free (wmode); - - errno = save_errno; - return retval; + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + wchar_t *wmode; + FILE *retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return NULL; + } + + wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); + + if (wmode == NULL) + { + g_free (wfilename); + errno = EINVAL; + return NULL; + } + + retval = _wfopen (wfilename, wmode); + save_errno = errno; + + g_free (wfilename); + g_free (wmode); + + errno = save_errno; + return retval; } /** @@ -432,38 +426,36 @@ ws_stdio_fopen (const gchar *filename, * Since: 2.6 */ FILE * -ws_stdio_freopen (const gchar *filename, - const gchar *mode, - FILE *stream) +ws_stdio_freopen (const gchar *filename, const gchar *mode, FILE *stream) { - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - wchar_t *wmode; - FILE *retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return NULL; - } - - wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); - - if (wmode == NULL) - { - g_free (wfilename); - errno = EINVAL; - return NULL; - } - - retval = _wfreopen (wfilename, wmode, stream); - save_errno = errno; - - g_free (wfilename); - g_free (wmode); - - errno = save_errno; - return retval; + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + wchar_t *wmode; + FILE *retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return NULL; + } + + wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); + + if (wmode == NULL) + { + g_free (wfilename); + errno = EINVAL; + return NULL; + } + + retval = _wfreopen (wfilename, wmode, stream); + save_errno = errno; + + g_free (wfilename); + g_free (wmode); + + errno = save_errno; + return retval; } @@ -471,74 +463,74 @@ ws_stdio_freopen (const gchar *filename, static gboolean init_dll_load_paths() { - TCHAR path_w[MAX_PATH]; + TCHAR path_w[MAX_PATH]; - if (program_path && system_path && npcap_path) - return TRUE; + if (program_path && system_path && npcap_path) + return TRUE; - /* XXX - Duplicate code in filesystem.c:init_progfile_dir */ - if (GetModuleFileName(NULL, path_w, MAX_PATH) == 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - return FALSE; - } + /* XXX - Duplicate code in filesystem.c:init_progfile_dir */ + if (GetModuleFileName(NULL, path_w, MAX_PATH) == 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + return FALSE; + } - if (!program_path) { - gchar *app_path; - app_path = g_utf16_to_utf8(path_w, -1, NULL, NULL, NULL); - /* We could use PathRemoveFileSpec here but we'd have to link to Shlwapi.dll */ - program_path = g_path_get_dirname(app_path); - g_free(app_path); - } + if (!program_path) { + gchar *app_path; + app_path = g_utf16_to_utf8(path_w, -1, NULL, NULL, NULL); + /* We could use PathRemoveFileSpec here but we'd have to link to Shlwapi.dll */ + program_path = g_path_get_dirname(app_path); + g_free(app_path); + } - if (GetSystemDirectory(path_w, MAX_PATH) == 0) { - return FALSE; - } + if (GetSystemDirectory(path_w, MAX_PATH) == 0) { + return FALSE; + } - if (!system_path) { - system_path = g_utf16_to_utf8(path_w, -1, NULL, NULL, NULL); - } + if (!system_path) { + system_path = g_utf16_to_utf8(path_w, -1, NULL, NULL, NULL); + } - _tcscat_s(path_w, MAX_PATH, _T("\\Npcap")); + _tcscat_s(path_w, MAX_PATH, _T("\\Npcap")); - if (!npcap_path) { - npcap_path = g_utf16_to_utf8(path_w, -1, NULL, NULL, NULL); - } + if (!npcap_path) { + npcap_path = g_utf16_to_utf8(path_w, -1, NULL, NULL, NULL); + } - if (program_path && system_path && npcap_path) - return TRUE; + if (program_path && system_path && npcap_path) + return TRUE; - return FALSE; + return FALSE; } gboolean ws_init_dll_search_path() { - gboolean dll_dir_set = FALSE; - wchar_t *program_path_w; - wchar_t npcap_path_w[MAX_PATH]; - unsigned int retval; - - typedef BOOL (WINAPI *SetDllDirectoryHandler)(LPCTSTR); - SetDllDirectoryHandler PSetDllDirectory; - - PSetDllDirectory = (SetDllDirectoryHandler) GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "SetDllDirectoryW"); - if (PSetDllDirectory) { - dll_dir_set = PSetDllDirectory(_T("")); - if (dll_dir_set) { - retval = GetSystemDirectoryW(npcap_path_w, MAX_PATH); - if (0 < retval && retval <= MAX_PATH) { - wcscat_s(npcap_path_w, MAX_PATH, L"\\Npcap"); - dll_dir_set = PSetDllDirectory(npcap_path_w); - } + gboolean dll_dir_set = FALSE; + wchar_t *program_path_w; + wchar_t npcap_path_w[MAX_PATH]; + unsigned int retval; + + typedef BOOL (WINAPI *SetDllDirectoryHandler)(LPCTSTR); + SetDllDirectoryHandler PSetDllDirectory; + + PSetDllDirectory = (SetDllDirectoryHandler) GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "SetDllDirectoryW"); + if (PSetDllDirectory) { + dll_dir_set = PSetDllDirectory(_T("")); + if (dll_dir_set) { + retval = GetSystemDirectoryW(npcap_path_w, MAX_PATH); + if (0 < retval && retval <= MAX_PATH) { + wcscat_s(npcap_path_w, MAX_PATH, L"\\Npcap"); + dll_dir_set = PSetDllDirectory(npcap_path_w); } - } + } + } - if (!dll_dir_set && init_dll_load_paths()) { - program_path_w = g_utf8_to_utf16(program_path, -1, NULL, NULL, NULL); - SetCurrentDirectory(program_path_w); - g_free(program_path_w); - } + if (!dll_dir_set && init_dll_load_paths()) { + program_path_w = g_utf8_to_utf16(program_path, -1, NULL, NULL, NULL); + SetCurrentDirectory(program_path_w); + g_free(program_path_w); + } - return dll_dir_set; + return dll_dir_set; } /* @@ -551,85 +543,85 @@ ws_init_dll_search_path() void * ws_load_library(const gchar *library_name) { - gchar *full_path; - wchar_t *full_path_w; - HMODULE dll_h; - - if (!init_dll_load_paths() || !library_name) - return NULL; - - /* First try the program directory */ - full_path = g_module_build_path(program_path, library_name); - full_path_w = g_utf8_to_utf16(full_path, -1, NULL, NULL, NULL); - - if (full_path && full_path_w) { - dll_h = LoadLibraryW(full_path_w); - if (dll_h) { - g_free(full_path); - g_free(full_path_w); - return dll_h; - } - } - - /* Next try the system directory */ - full_path = g_module_build_path(system_path, library_name); - full_path_w = g_utf8_to_utf16(full_path, -1, NULL, NULL, NULL); - - if (full_path && full_path_w) { - dll_h = LoadLibraryW(full_path_w); - if (dll_h) { - g_free(full_path); - g_free(full_path_w); - return dll_h; - } - } + gchar *full_path; + wchar_t *full_path_w; + HMODULE dll_h; + + if (!init_dll_load_paths() || !library_name) + return NULL; + + /* First try the program directory */ + full_path = g_module_build_path(program_path, library_name); + full_path_w = g_utf8_to_utf16(full_path, -1, NULL, NULL, NULL); + + if (full_path && full_path_w) { + dll_h = LoadLibraryW(full_path_w); + if (dll_h) { + g_free(full_path); + g_free(full_path_w); + return dll_h; + } + } + + /* Next try the system directory */ + full_path = g_module_build_path(system_path, library_name); + full_path_w = g_utf8_to_utf16(full_path, -1, NULL, NULL, NULL); + + if (full_path && full_path_w) { + dll_h = LoadLibraryW(full_path_w); + if (dll_h) { + g_free(full_path); + g_free(full_path_w); + return dll_h; + } + } - return NULL; + return NULL; } GModule * ws_module_open(gchar *module_name, GModuleFlags flags) { - gchar *full_path; - GModule *mod; + gchar *full_path; + GModule *mod; - if (!init_dll_load_paths() || !module_name) - return NULL; + if (!init_dll_load_paths() || !module_name) + return NULL; - /* First try the program directory */ - full_path = g_module_build_path(program_path, module_name); + /* First try the program directory */ + full_path = g_module_build_path(program_path, module_name); - if (full_path) { - mod = g_module_open(full_path, flags); - if (mod) { - g_free(full_path); - return mod; - } - } + if (full_path) { + mod = g_module_open(full_path, flags); + if (mod) { + g_free(full_path); + return mod; + } + } - /* Next try the system directory */ - full_path = g_module_build_path(system_path, module_name); + /* Next try the system directory */ + full_path = g_module_build_path(system_path, module_name); - if (full_path) { - mod = g_module_open(full_path, flags); - if (mod) { - g_free(full_path); - return mod; - } - } + if (full_path) { + mod = g_module_open(full_path, flags); + if (mod) { + g_free(full_path); + return mod; + } + } - /* At last try the Npcap directory */ - full_path = g_module_build_path(npcap_path, module_name); + /* At last try the Npcap directory */ + full_path = g_module_build_path(npcap_path, module_name); - if (full_path) { - mod = g_module_open(full_path, flags); - if (mod) { - g_free(full_path); - return mod; - } - } + if (full_path) { + mod = g_module_open(full_path, flags); + if (mod) { + g_free(full_path); + return mod; + } + } - return NULL; + return NULL; } /** Create or open a "Wireshark is running" mutex. @@ -638,38 +630,52 @@ ws_module_open(gchar *module_name, GModuleFlags flags) static SECURITY_ATTRIBUTES *sec_attributes_; +static HANDLE local_running_mutex = NULL; +static HANDLE global_running_mutex = NULL; + void create_app_running_mutex() { - SECURITY_ATTRIBUTES *sa = NULL; + SECURITY_ATTRIBUTES *sa = NULL; - if (!sec_attributes_) sec_attributes_ = g_new0(SECURITY_ATTRIBUTES, 1); + if (!sec_attributes_) sec_attributes_ = g_new0(SECURITY_ATTRIBUTES, 1); - sec_attributes_->nLength = sizeof(SECURITY_ATTRIBUTES); - sec_attributes_->lpSecurityDescriptor = g_new0(SECURITY_DESCRIPTOR, 1); - sec_attributes_->bInheritHandle = TRUE; - if (InitializeSecurityDescriptor(sec_attributes_->lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { - if (SetSecurityDescriptorDacl(sec_attributes_->lpSecurityDescriptor, TRUE, NULL, FALSE)) { - sa = sec_attributes_; - } - } - - if (!sa) { - g_free(sec_attributes_->lpSecurityDescriptor); - g_free(sec_attributes_); - sec_attributes_ = NULL; - } - CreateMutex(sa, FALSE, _T("Wireshark-is-running-{") _T(WIRESHARK_IS_RUNNING_UUID) _T("}")); - CreateMutex(sa, FALSE, _T("Global\\Wireshark-is-running-{") _T(WIRESHARK_IS_RUNNING_UUID) _T("}")); + sec_attributes_->nLength = sizeof(SECURITY_ATTRIBUTES); + sec_attributes_->lpSecurityDescriptor = g_new0(SECURITY_DESCRIPTOR, 1); + sec_attributes_->bInheritHandle = TRUE; + if (InitializeSecurityDescriptor(sec_attributes_->lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { + if (SetSecurityDescriptorDacl(sec_attributes_->lpSecurityDescriptor, TRUE, NULL, FALSE)) { + sa = sec_attributes_; + } + } + + if (!sa) { + g_free(sec_attributes_->lpSecurityDescriptor); + g_free(sec_attributes_); + sec_attributes_ = NULL; + } + local_running_mutex = CreateMutex(sa, FALSE, _T("Wireshark-is-running-{") _T(WIRESHARK_IS_RUNNING_UUID) _T("}")); + global_running_mutex = CreateMutex(sa, FALSE, _T("Global\\Wireshark-is-running-{") _T(WIRESHARK_IS_RUNNING_UUID) _T("}")); +} + +void close_app_running_mutex() { + if (local_running_mutex) { + CloseHandle(local_running_mutex); + local_running_mutex = NULL; + } + if (global_running_mutex) { + CloseHandle(global_running_mutex); + global_running_mutex = NULL; + } } /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * - * Local variables: - * c-basic-offset: 6 + * Local Variables: + * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * - * vi: set shiftwidth=6 tabstop=8 expandtab: - * :indentSize=6:tabSize=8:noTabs=true: + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: */ diff --git a/wsutil/file_util.h b/wsutil/file_util.h index 5c8c0c41c6..fc13f4c6c3 100644 --- a/wsutil/file_util.h +++ b/wsutil/file_util.h @@ -168,6 +168,10 @@ GModule *ws_module_open(gchar *module_name, GModuleFlags flags); */ WS_DLL_PUBLIC void create_app_running_mutex(); +/** Close our "Wireshark is running" mutex. + */ +WS_DLL_PUBLIC void close_app_running_mutex(); + #else /* _WIN32 */ /* -- cgit v1.2.1