talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 0d164d3e260c44584e96f95df12fbea4b3466867
parent e0f1b46602c713c91d84c4e1929e30dbb9a01720
Author: Jonathan Boeing <jonathan@claws-mail.org>
Date:   Tue, 14 Sep 2021 02:04:45 -0700

Update Windows registry code

Diffstat:
Msrc/common/Makefile.am | 2+-
Msrc/common/w32_reg.c | 225++++++++++++++++++++++++++++++++-----------------------------------------------
Asrc/common/w32_reg.h | 40++++++++++++++++++++++++++++++++++++++++
Dsrc/common/w32lib.h | 82-------------------------------------------------------------------------------
Msrc/mainwindow.c | 130+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/procmime.c | 13+++++++++----
6 files changed, 221 insertions(+), 271 deletions(-)

diff --git a/src/common/Makefile.am b/src/common/Makefile.am @@ -15,7 +15,7 @@ noinst_LTLIBRARIES = libclawscommon.la if OS_WIN32 arch_sources = w32_reg.c -arch_headers = w32lib.h +arch_headers = w32_reg.h else arch_files = arch_header = diff --git a/src/common/w32_reg.c b/src/common/w32_reg.c @@ -1,172 +1,127 @@ -/* w32_reg.c - Posix emulation layer for Sylpheed (Claws) +/* + * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2021 the Claws Mail team and Hiroyuki Yamamoto * - * This file is part of w32lib. - * - * w32lib is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * w32lib is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For more information and a list of changes, see w32lib.h */ -#include <windows.h> +#include "w32_reg.h" #include "utils.h" -#include "w32lib.h" - -static HKEY get_root_key_from_str(char *parent) -{ - HKEY rootKey = NULL; - if (!parent || !strlen(parent)) - rootKey = HKEY_CURRENT_USER ; - else if (!strcmp(parent, "HKCR") || !strcmp(parent,"HKEY_CLASSES_ROOT")) - rootKey = HKEY_CLASSES_ROOT ; - else if (!strcmp(parent, "HKCU") || !strcmp(parent,"HKEY_CURRENT_USER")) - rootKey = HKEY_CURRENT_USER ; - else if (!strcmp(parent, "HKLM") || !strcmp(parent,"HKEY_LOCAL_MACHINE")) - rootKey = HKEY_LOCAL_MACHINE ; - else if (!strcmp(parent, "HKU") || !strcmp(parent,"HKEY_USERS")) - rootKey = HKEY_USERS ; - else if (!strcmp(parent, "HKCC") || !strcmp(parent,"HKEY_CURRENT_CONFIG")) - rootKey = HKEY_CURRENT_CONFIG ; - return rootKey; -} - -int write_w32_registry_string( char *parent, char *section, char *value, char *data ) +gboolean reg_set_value(HKEY root, + const gchar *subkey, + const gchar *value, + DWORD type, + const BYTE *data, + DWORD data_size) { - HKEY hKey, rootKey; - int ret; + DWORD ret; + HKEY key; + gchar *tmp; - rootKey = get_root_key_from_str(parent); - ret = RegCreateKeyEx(rootKey, section, 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL); + ret = RegCreateKeyEx(root, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL); if (ret != ERROR_SUCCESS) { - debug_print("can't write key %s\\%s: %d\n", parent, section, ret); - return -1; + tmp = g_win32_error_message(ret); + debug_print("RegCreateKeyEx %p \"%s\" had error: \"%s\"\n", root, subkey, tmp); + g_free(tmp); + return FALSE; } - ret = RegSetValueEx(hKey, value, 0, REG_SZ, (LPVOID)data, strlen(data)+1); + + ret = RegSetValueEx(key, value, 0, type, data, data_size); if (ret != ERROR_SUCCESS) { - RegCloseKey(hKey); - debug_print("can't write key %s\\%s: %d\n", parent, section, ret); - return -1; + tmp = g_win32_error_message(ret); + debug_print("RegSetValueEx %p \"%s\" had error: \"%s\"\n", root, subkey, tmp); + g_free(tmp); } - RegCloseKey(hKey); - return 0; + + RegCloseKey(key); + return (ret == ERROR_SUCCESS); } -int write_w32_registry_dword( char *parent, char *section, char *value, int data ) +gboolean write_w32_registry_string(HKEY root, + const gchar *subkey, + const gchar *value, + const gchar *data) { - HKEY hKey, rootKey; - int ret; - - rootKey = get_root_key_from_str(parent); - ret = RegCreateKeyEx(rootKey, section, 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL); - if (ret != ERROR_SUCCESS) { - debug_print("can't write key %s\\%s: %d\n", parent, section, ret); - return -1; - } - ret = RegSetValueEx(hKey, value, 0, REG_DWORD, (LPBYTE)&data, sizeof(data)); - if (ret != ERROR_SUCCESS) { - RegCloseKey(hKey); - debug_print("can't write key %s\\%s: %d\n", parent, section, ret); - return -1; - } - RegCloseKey(hKey); - return 0; + return reg_set_value(root, subkey, value, REG_SZ, (BYTE *)data, strlen(data) + 1); } -char *read_w32_registry_string( char *parent, char *section, char *key ) +gboolean write_w32_registry_dword(HKEY root, + const gchar *subkey, + const gchar *value, + DWORD data) { - HKEY hKey, rootKey; - char *str; - int ret; - - char buf[ MAX_PATH ]; - DWORD bufsiz = sizeof( buf ); - - rootKey = get_root_key_from_str(parent); - - if (!rootKey) - return NULL; - - str = NULL; - ret = RegOpenKeyEx( rootKey, section, 0, KEY_READ, &hKey ); - if ( ERROR_SUCCESS == ret ){ - ret = RegQueryValueEx( hKey, key, 0, NULL, - (LPBYTE)buf, &bufsiz ); - if ( ERROR_SUCCESS == ret ){ - str = strdup( buf ); - } - RegCloseKey( hKey ); - } - return str; + return reg_set_value(root, subkey, value, REG_DWORD, (BYTE *)&data, sizeof(DWORD)); } -char *get_content_type_from_registry_with_ext( char *ext ) +gchar *read_w32_registry_string(HKEY root, const gchar *subkey, const gchar *value) { - HKEY hKey, parent; - int ret; - char buf[ MAX_PATH ]; - DWORD bufsiz; - char *section, *key, *value; - - if (ext == NULL) + HKEY hkey; + DWORD ret; + DWORD type; + BYTE *data; + DWORD data_size; + gchar *tmp; + + if (subkey == NULL) return NULL; - // parent : HKEY_CLASSES_ROOT - // section : ".txt" - parent = HKEY_CLASSES_ROOT; - section = malloc ( 1 + strlen (ext) + 1); - if (!section) - return NULL; - *section = '.'; - strcpy (section+1, ext); - - value = NULL; - while ( 1 ) { - ret = RegOpenKeyEx( parent, section, 0, KEY_READ, &hKey ); - if ( ERROR_SUCCESS != ret ) { - // If section is not found... - value = NULL; - break; - } - - // key : "Content Type" - key = "Content Type"; - bufsiz = sizeof( buf ); - ret = RegQueryValueEx( hKey, key, 0, NULL, (LPBYTE)buf, &bufsiz ); - if ( ERROR_SUCCESS == ret ) { - // If value is found! - RegCloseKey( hKey ); - value = strdup( buf ); - break; - } + ret = RegOpenKeyEx(root, subkey, 0, KEY_READ, &hkey); + if (ret != ERROR_SUCCESS) { + tmp = g_win32_error_message(ret); + debug_print("RegOpenKeyEx %p \"%s\" had error: \"%s\"\n", root, subkey, tmp); + g_free(tmp); + return NULL; + } - key = ""; - bufsiz = sizeof( buf ); - ret = RegQueryValueEx( hKey, key, 0, NULL, (LPBYTE)buf, &bufsiz ); - if ( ERROR_SUCCESS != ret ) { - RegCloseKey( hKey ); - value = NULL; - break; - } + // Get the needed buffer size + ret = RegQueryValueEx(hkey, value, 0, &type, NULL, &data_size); + if (ret != ERROR_SUCCESS) { + tmp = g_win32_error_message(ret); + debug_print("RegQueryValueEx %p \"%s\" \"%s\" had error: \"%s\" when getting buffer size\n", + root, subkey, value, tmp); + RegCloseKey(hkey); + g_free(tmp); + return NULL; + } else if (type != REG_SZ) { + debug_print("RegQueryValueEx %p \"%s\" \"%s\" returned type %lu instead of REG_SZ\n", + root, subkey, value, type); + RegCloseKey(hkey); + return NULL; + } else if (data_size == 0) { + debug_print("RegQueryValueEx %p \"%s\" \"%s\" returned data size 0\n", + root, subkey, value); + RegCloseKey(hkey); + return NULL; + } - RegCloseKey( hKey ); - free( section ); - section = strdup( buf ); - break; //XXX:tm-gtk2 + // The raw value is not necessarily NUL-terminated + data = g_malloc(data_size + 1); + + ret = RegQueryValueEx(hkey, value, 0, NULL, data, &data_size); + if (ret == ERROR_SUCCESS) { + data[data_size] = '\0'; + } else { + tmp = g_win32_error_message(ret); + debug_print("RegQueryValueEx %p \"%s\" \"%s\" had error: \"%s\"\n", + root, subkey, value, tmp); + RegCloseKey(hkey); + g_free(data); + g_free(tmp); + return NULL; } - free( section ); - return value; + RegCloseKey(hkey); + return (gchar *)data; } diff --git a/src/common/w32_reg.h b/src/common/w32_reg.h @@ -0,0 +1,40 @@ +/* + * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2021 the Claws Mail team and Hiroyuki Yamamoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __W32_REG_H__ +#define __W32_REG_H__ + +#include <windows.h> +#include <glib.h> + +gboolean write_w32_registry_string(HKEY root, + const gchar *subkey, + const gchar *value, + const gchar *data); + +gboolean write_w32_registry_dword(HKEY root, + const gchar *subkey, + const gchar *value, + DWORD data); + +// Caller should deallocate the return value with g_free() +gchar *read_w32_registry_string(HKEY root, + const gchar *subkey, + const gchar *value); + +#endif diff --git a/src/common/w32lib.h b/src/common/w32lib.h @@ -1,82 +0,0 @@ -/* w32lib.h - Posix emulation layer for Sylpheed (Claws) - * - * This file is part of w32lib. - * - * w32lib is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * w32lib is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * The code has been taken from the package - * http://claws.sylpheed.org/win32/sylpheed/w32lib-dev-2004.2.3.0.zip - * on 2005-11-17 by Werner Koch <wk@gnupg.org>. There are no regular - * copyright notices but the file version.rc from the ZIP archive - * claims: - * - * #define FILEVER "2004.2.3.0\0" - * #define PRODVER "2004.2.3\0" - * - * [...] - * VALUE "FileDescription", "Posix emulation layer for Sylpheed (Claws)\0" - * VALUE "FileVersion", FILEVER - * VALUE "ProductVersion", PRODVER - * VALUE "LegalCopyright", "GPL\0" - * VALUE "CompanyName", "GNU / Free Software Foundation\0" - * VALUE "ProductName", "w32lib\0" - * - * Along with the fact that Sylpheed is under the GPL we can assume - * that this code is under the GPL. No author information or - * changelogs have been found. - * Files taken form the package are: - * w32_dirent.c w32_reg.c w32_stat.c w32_stdlib.c w32_time.c w32_wait.c - * w32_gettext.c w32_signal.c w32_stdio.c w32_string.c w32_unistd.c - */ - -/* Changes are: - -2007-05-21 Werner Koch <wk@g10code.com> - - * src/common/w32_account.c: New. - - * src/common/w32lib.h: Undef "interface". - -2005-11-17 Werner Koch <wk@g10code.com> - - Add boilerplate text to all files and explain legal status. - - * w32_reg.c: Replaced g_free and g_strdup by regular C functions. - (get_content_type_from_registry_with_ext): Ditto. - * w32_dirent.c (readdir): Ditto. - (opendir): Ditto. - (closedir): Reformatted. - (readdir): Reformatted, replaced use of g_strdup_printf and other - g-style malloc function by regular ones. Use DIR structure from mingw. - * w32lib.h: Don't define finddata_t for mingw. Replaced replacement - DIR structure by the one form mingw. Allocate filename in dirent - statically to match the defintion ussed by mingw. - * w32_reg.c (read_w32_registry_string): Return error for invalid root - key. - - */ - - -#ifndef _W32LIB_H_ -#define _W32LIB_H_ - -#include <windows.h> - -/*** misc ***/ -int write_w32_registry_string( char *parent, char *section, char *value, char *data ); -int write_w32_registry_dword( char *parent, char *section, char *value, int data ); -char *read_w32_registry_string( char *parent, char *section, char *key ); -char *get_content_type_from_registry_with_ext( char *ext ); - -#endif diff --git a/src/mainwindow.c b/src/mainwindow.c @@ -98,7 +98,7 @@ #include "printing.h" #include "send_message.h" #ifdef G_OS_WIN32 -#include "w32lib.h" +#include "w32_reg.h" #endif #define AC_LABEL_WIDTH 240 @@ -5205,7 +5205,7 @@ static void set_default_client_cb(GtkAction *action, gpointer data) gchar *binary_icon = NULL; gchar *binary_compose = NULL; gchar *binary_run = NULL; - int r = 0; + gboolean r; if ( !GetModuleFileNameA (0, exename, sizeof (exename)) ) { alertpanel_error(_("Can not register as default client: impossible to get executable path.")); return; @@ -5215,56 +5215,88 @@ static void set_default_client_cb(GtkAction *action, gpointer data) binary_run = g_strconcat(exename, NULL); /* Try to set the Mail Start menu item to Claws. It may fail if we're not root; we don't care */ - r = write_w32_registry_string("HKLM", "Software\\Clients\\Mail", - "", "Claws Mail"); + r = write_w32_registry_string(HKEY_LOCAL_MACHINE, + "Software\\Clients\\Mail", + "", + "Claws Mail"); - r = write_w32_registry_string("HKCU", "Software\\Clients\\Mail\\Claws Mail", - "", "Claws Mail"); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Clients\\Mail\\Claws Mail", - "DLLPath", ""); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto", - "", "URL:MailTo-Protocol"); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto", - "URL Protocol", ""); - if (!r) - r = write_w32_registry_dword ("HKCU", "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto", - "EditFlags", 2); - if (!r) - r = write_w32_registry_string ("HKCU", "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto", - "FriendlyTypeName", "Claws-Mail URL"); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto\\DefaultIcon", - "", binary_icon); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto\\shell\\open\\command", - "", binary_compose); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Clients\\Mail\\Claws Mail\\shell\\open\\command", - "", binary_run); + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail", + "", + "Claws Mail"); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail", + "DLLPath", + ""); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto", + "", + "URL:MailTo-Protocol"); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto", + "URL Protocol", + ""); + if (r) + r = write_w32_registry_dword (HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto", + "EditFlags", + 2); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto", + "FriendlyTypeName", + "Claws-Mail URL"); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto\\DefaultIcon", + "", + binary_icon); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail\\Protocols\\mailto\\shell\\open\\command", + "", + binary_compose); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Clients\\Mail\\Claws Mail\\shell\\open\\command", + "", + binary_run); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Classes\\mailto", - "", "URL:MailTo-Protocol"); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Classes\\mailto", - "URL Protocol", ""); - if (!r) - r = write_w32_registry_dword ("HKCU", "Software\\Classes\\mailto", - "EditFlags", 2); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Classes\\mailto", - "FriendlyTypeName", "Claws-Mail URL"); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Classes\\mailto\\DefaultIcon", - "", binary_icon); - if (!r) - r = write_w32_registry_string("HKCU", "Software\\Classes\\mailto\\shell\\open\\command", - "", binary_compose); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Classes\\mailto", + "", + "URL:MailTo-Protocol"); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Classes\\mailto", + "URL Protocol", + ""); + if (r) + r = write_w32_registry_dword (HKEY_CURRENT_USER, + "Software\\Classes\\mailto", + "EditFlags", + 2); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Classes\\mailto", + "FriendlyTypeName", + "Claws-Mail URL"); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Classes\\mailto\\DefaultIcon", + "", + binary_icon); + if (r) + r = write_w32_registry_string(HKEY_CURRENT_USER, + "Software\\Classes\\mailto\\shell\\open\\command", + "", + binary_compose); - if (!r) { + if (r) { SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Software\\Clients\\Mail"); alertpanel_notice(_("Claws Mail has been registered as default client.")); } else { diff --git a/src/procmime.c b/src/procmime.c @@ -55,7 +55,8 @@ #include "file-utils.h" #ifdef G_OS_WIN32 -#include "w32lib.h" +#include "w32_reg.h" +#define REG_MIME_TYPE_VALUE "Content Type" #endif static GHashTable *procmime_get_mime_type_table (void); @@ -1047,6 +1048,7 @@ gchar *procmime_get_mime_type(const gchar *filename) const gchar *p; gchar *ext = NULL; gchar *base; + gchar *str; #ifndef G_OS_WIN32 static GHashTable *mime_type_table = NULL; MimeType *mime_type; @@ -1062,7 +1064,11 @@ gchar *procmime_get_mime_type(const gchar *filename) base = g_path_get_basename(filename); if ((p = strrchr(base, '.')) != NULL) +#ifndef G_OS_WIN32 ext = g_utf8_strdown(p + 1, -1); +#else + ext = g_utf8_strdown(p, -1); +#endif else ext = g_utf8_strdown(base, -1); g_free(base); @@ -1071,7 +1077,6 @@ gchar *procmime_get_mime_type(const gchar *filename) mime_type = g_hash_table_lookup(mime_type_table, ext); if (mime_type) { - gchar *str; str = g_strconcat(mime_type->type, "/", mime_type->sub_type, NULL); debug_print("got type %s for %s\n", str, ext); @@ -1081,8 +1086,8 @@ gchar *procmime_get_mime_type(const gchar *filename) g_free(ext); return NULL; #else - gchar *str = get_content_type_from_registry_with_ext(ext); - + str = read_w32_registry_string(HKEY_CLASSES_ROOT, ext, REG_MIME_TYPE_VALUE); + debug_print("got type %s for %s\n", str, ext); g_free(ext); return str; #endif