Fix CID 1491401 and 1491402: (possible) modulo by zero.
[claws.git] / src / common / w32_reg.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2021 the Claws Mail team and Hiroyuki Yamamoto
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "w32_reg.h"
20 #include "utils.h"
21
22 gboolean reg_set_value(HKEY root,
23         const gchar *subkey,
24         const gchar *value,
25         DWORD type,
26         const BYTE *data,
27         DWORD data_size)
28 {
29         DWORD ret;
30         HKEY key;
31         gchar *tmp;
32
33         ret = RegCreateKeyEx(root, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL);
34         if (ret != ERROR_SUCCESS) {
35                 tmp = g_win32_error_message(ret);
36                 debug_print("RegCreateKeyEx %p \"%s\" had error: \"%s\"\n", root, subkey, tmp);
37                 g_free(tmp);
38                 return FALSE;
39         }
40
41         ret = RegSetValueEx(key, value, 0, type, data, data_size);
42         if (ret != ERROR_SUCCESS) {
43                 tmp = g_win32_error_message(ret);
44                 debug_print("RegSetValueEx %p \"%s\" had error: \"%s\"\n", root, subkey, tmp);
45                 g_free(tmp);
46         }
47
48         RegCloseKey(key);
49         return (ret == ERROR_SUCCESS);
50 }
51
52 gboolean write_w32_registry_string(HKEY root,
53         const gchar *subkey,
54         const gchar *value,
55         const gchar *data)
56 {
57         return reg_set_value(root, subkey, value, REG_SZ, (BYTE *)data, strlen(data) + 1);
58 }
59
60 gboolean write_w32_registry_dword(HKEY root,
61         const gchar *subkey,
62         const gchar *value,
63         DWORD data)
64 {
65         return reg_set_value(root, subkey, value, REG_DWORD, (BYTE *)&data, sizeof(DWORD));
66 }
67
68 gchar *read_w32_registry_string(HKEY root, const gchar *subkey, const gchar *value)
69 {
70         HKEY hkey;
71         DWORD ret;
72         DWORD type;
73         BYTE *data;
74         DWORD data_size;
75         gchar *tmp;
76
77         if (subkey == NULL)
78                 return NULL;
79
80         ret = RegOpenKeyEx(root, subkey, 0, KEY_READ, &hkey);
81         if (ret != ERROR_SUCCESS) {
82                 tmp = g_win32_error_message(ret);
83                 debug_print("RegOpenKeyEx %p \"%s\" had error: \"%s\"\n", root, subkey, tmp);
84                 g_free(tmp);
85                 return NULL;
86         }
87
88         // Get the needed buffer size
89         ret = RegQueryValueEx(hkey, value, 0, &type, NULL, &data_size);
90         if (ret != ERROR_SUCCESS) {
91                 tmp = g_win32_error_message(ret);
92                 debug_print("RegQueryValueEx %p \"%s\" \"%s\" had error: \"%s\" when getting buffer size\n",
93                         root, subkey, value, tmp);
94                 RegCloseKey(hkey);
95                 g_free(tmp);
96                 return NULL;
97         } else if (type != REG_SZ) {
98                 debug_print("RegQueryValueEx %p \"%s\" \"%s\" returned type %lu instead of REG_SZ\n",
99                         root, subkey, value, type);
100                 RegCloseKey(hkey);
101                 return NULL;
102         } else if (data_size == 0) {
103                 debug_print("RegQueryValueEx %p \"%s\" \"%s\" returned data size 0\n",
104                         root, subkey, value);
105                 RegCloseKey(hkey);
106                 return NULL;
107         }
108
109         // The raw value is not necessarily NUL-terminated
110         data = g_malloc(data_size + 1);
111
112         ret = RegQueryValueEx(hkey, value, 0, NULL, data, &data_size);
113         if (ret == ERROR_SUCCESS) {
114                 data[data_size] = '\0';
115         } else {
116                 tmp = g_win32_error_message(ret);
117                 debug_print("RegQueryValueEx %p \"%s\" \"%s\" had error: \"%s\"\n",
118                         root, subkey, value, tmp);
119                 RegCloseKey(hkey);
120                 g_free(data);
121                 g_free(tmp);
122                 return NULL;
123         }
124
125         RegCloseKey(hkey);
126         return (gchar *)data;
127 }