diff options
Diffstat (limited to 'windows.c')
-rw-r--r-- | windows.c | 70 |
1 files changed, 52 insertions, 18 deletions
@@ -15,7 +15,7 @@ static int get_from_registry(HKEY hkey, const char *key) LONG success; success = RegQueryValueEx(hkey, (LPCTSTR)TEXT(key), NULL, NULL, - (LPBYTE) &value, (LPDWORD)&len ); + (LPBYTE) &value, (LPDWORD)&len ); if (success != ERROR_SUCCESS) return FALSE; /* that's what happens the first time we start */ return value; @@ -26,8 +26,8 @@ void subsurface_open_conf(void) LONG success; success = RegCreateKeyEx(HKEY_CURRENT_USER, (LPCTSTR)TEXT("Software\\subsurface"), - 0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, - NULL, &hkey, NULL); + 0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, + NULL, &hkey, NULL); if (success != ERROR_SUCCESS) printf("CreateKey Software\\subsurface failed %ld\n", success); } @@ -40,39 +40,73 @@ void subsurface_set_conf(char *name, pref_type_t type, const void *value) * calls to RegSetValueEx needs to pass &value (when we want * to pass the boolean value), the other one passes value (the * address of the string. */ + int wlen; + wchar_t *wname = NULL, *wstring = NULL; + + wname = (wchar_t *)g_utf8_to_utf16(name, -1, NULL, NULL, NULL); + if (!wname) + return; switch (type) { case PREF_BOOL: /* we simply store the value as DWORD */ - RegSetValueEx(hkey, (LPCTSTR)TEXT(name), 0, REG_DWORD, (const BYTE *)&value, 4); + RegSetValueExW(hkey, (LPCWSTR)wname, 0, REG_DWORD, (const BYTE *)&value, 4); break; case PREF_STRING: - RegSetValueEx(hkey, (LPCTSTR)TEXT(name), 0, REG_SZ, (const BYTE *)value, strlen(value)); + wlen = g_utf8_strlen((char *)value, -1); + wstring = (wchar_t *)g_utf8_to_utf16((char *)value, -1, NULL, NULL, NULL); + if (!wstring || !wlen) { + free(wname); + return; + } + RegSetValueExW(hkey, (LPCWSTR)wname, 0, REG_SZ, (const BYTE *)wstring, + wlen * sizeof(wchar_t)); + free(wstring); } + free(wname); } const void *subsurface_get_conf(char *name, pref_type_t type) { - LONG success; - char *string; - int len; + const int csize = 64; + int blen = 0; + LONG ret = ERROR_MORE_DATA; + wchar_t *wstring = NULL, *wname = NULL; + char *utf8_string; switch (type) { case PREF_BOOL: return get_from_registry(hkey, name) ? (void *) 1 : NULL; case PREF_STRING: - string = malloc(80); - len = 80; - success = RegQueryValueEx(hkey, (LPCTSTR)TEXT(name), NULL, NULL, - (LPBYTE) string, (LPDWORD)&len ); - if (success != ERROR_SUCCESS) { - /* that's what happens the first time we start - just return NULL */ - free(string); + wname = (wchar_t *)g_utf8_to_utf16(name, -1, NULL, NULL, NULL); + if (!wname) + return NULL; + blen = 0; + /* lest try to load the string in chunks of 'csize' bytes until it fits */ + while(ret == ERROR_MORE_DATA) { + blen += csize; + wstring = (wchar_t *)realloc(wstring, blen * sizeof(wchar_t)); + ret = RegQueryValueExW(hkey, (LPCWSTR)wname, NULL, NULL, + (LPBYTE)wstring, (LPDWORD)&blen); + } + /* that's what happens the first time we start - just return NULL */ + if (ret != ERROR_SUCCESS) { + free(wname); + free(wstring); + return NULL; + } + /* convert the returned string into utf-8 */ + utf8_string = g_utf16_to_utf8(wstring, -1, NULL, NULL, NULL); + free(wstring); + free(wname); + if (!utf8_string) + return NULL; + if (!g_utf8_validate(utf8_string, -1, NULL)) { + free(utf8_string); return NULL; } - return string; + return utf8_string; } - /* we shouldn't get here */ - return NULL; + return NULL; /* we shouldn't get here */ } void subsurface_flush_conf(void) |