mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-20 23:58:54 +02:00
registrybackend: more cleanups
This commit is contained in:
@@ -335,7 +335,7 @@ registry_value_dump (RegistryValue value)
|
|||||||
if (value.type == REG_DWORD)
|
if (value.type == REG_DWORD)
|
||||||
return g_strdup_printf ("%i", value.dword);
|
return g_strdup_printf ("%i", value.dword);
|
||||||
else if (value.type == REG_QWORD)
|
else if (value.type == REG_QWORD)
|
||||||
return g_strdup_printf ("%I64i", value.ptr==NULL? 0: *(DWORDLONG *)value.ptr);
|
return g_strdup_printf ("%I64i", value.ptr == NULL ? 0: *(DWORDLONG *)value.ptr);
|
||||||
else if (value.type == REG_SZ)
|
else if (value.type == REG_SZ)
|
||||||
return g_strdup_printf ("%s", (char *)value.ptr);
|
return g_strdup_printf ("%s", (char *)value.ptr);
|
||||||
else if (value.type == REG_NONE)
|
else if (value.type == REG_NONE)
|
||||||
@@ -349,6 +349,7 @@ registry_value_free (RegistryValue value)
|
|||||||
{
|
{
|
||||||
if (value.type == REG_SZ || value.type == REG_QWORD)
|
if (value.type == REG_SZ || value.type == REG_QWORD)
|
||||||
g_free (value.ptr);
|
g_free (value.ptr);
|
||||||
|
|
||||||
value.type = REG_NONE;
|
value.type = REG_NONE;
|
||||||
value.ptr = NULL;
|
value.ptr = NULL;
|
||||||
}
|
}
|
||||||
@@ -420,10 +421,12 @@ static void
|
|||||||
_ref_down (GNode *node)
|
_ref_down (GNode *node)
|
||||||
{
|
{
|
||||||
RegistryCacheItem *item = node->data;
|
RegistryCacheItem *item = node->data;
|
||||||
|
|
||||||
g_node_children_foreach (node, G_TRAVERSE_ALL,
|
g_node_children_foreach (node, G_TRAVERSE_ALL,
|
||||||
(GNodeForeachFunc)_ref_down, NULL);
|
(GNodeForeachFunc)_ref_down, NULL);
|
||||||
item->ref_count ++;
|
item->ref_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
registry_cache_ref_tree (GNode *tree)
|
registry_cache_ref_tree (GNode *tree)
|
||||||
{
|
{
|
||||||
@@ -437,7 +440,7 @@ registry_cache_ref_tree (GNode *tree)
|
|||||||
g_node_children_foreach (tree, G_TRAVERSE_ALL,
|
g_node_children_foreach (tree, G_TRAVERSE_ALL,
|
||||||
(GNodeForeachFunc)_ref_down, NULL);
|
(GNodeForeachFunc)_ref_down, NULL);
|
||||||
|
|
||||||
for (node=tree->parent; node; node=node->parent)
|
for (node=tree->parent; node; node = node->parent)
|
||||||
{
|
{
|
||||||
item = node->data;
|
item = node->data;
|
||||||
item->ref_count ++;
|
item->ref_count ++;
|
||||||
@@ -542,6 +545,7 @@ registry_cache_find_compare (GNode *node,
|
|||||||
search->result = node;
|
search->result = node;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,7 +583,7 @@ registry_cache_get_node_for_key_recursive (GNode *node,
|
|||||||
*/
|
*/
|
||||||
item = node->data;
|
item = node->data;
|
||||||
if (item->subscription_count > 0)
|
if (item->subscription_count > 0)
|
||||||
n_parent_watches ++;
|
n_parent_watches ++;
|
||||||
|
|
||||||
child = registry_cache_find_immediate_child (node, component);
|
child = registry_cache_find_immediate_child (node, component);
|
||||||
if (child == NULL && create_if_not_found)
|
if (child == NULL && create_if_not_found)
|
||||||
@@ -597,12 +601,11 @@ registry_cache_get_node_for_key_recursive (GNode *node,
|
|||||||
/* We are done if there are no more path components. Allow for a trailing /. */
|
/* We are done if there are no more path components. Allow for a trailing /. */
|
||||||
if (child==NULL || c == NULL || *(c+1)==0)
|
if (child==NULL || c == NULL || *(c+1)==0)
|
||||||
return child;
|
return child;
|
||||||
else
|
|
||||||
{
|
trace ("get node for key recursive: next: %s.\n", c + 1);
|
||||||
trace ("get node for key recursive: next: %s.\n", c+1);
|
return registry_cache_get_node_for_key_recursive (child, c + 1,
|
||||||
return registry_cache_get_node_for_key_recursive
|
create_if_not_found,
|
||||||
(child, c+1, create_if_not_found, n_parent_watches);
|
n_parent_watches);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look up a GSettings key in the cache. */
|
/* Look up a GSettings key in the cache. */
|
||||||
@@ -642,10 +645,11 @@ registry_cache_get_node_for_key (GNode *root,
|
|||||||
|
|
||||||
if (c == NULL)
|
if (c == NULL)
|
||||||
result = root;
|
result = root;
|
||||||
else if (*(c+1)==0)
|
else if (*(c + 1)==0)
|
||||||
result = child;
|
result = child;
|
||||||
else if (child != NULL)
|
else if (child != NULL)
|
||||||
result = registry_cache_get_node_for_key_recursive (child, c+1, create_if_not_found, 0);
|
result = registry_cache_get_node_for_key_recursive (child, c + 1,
|
||||||
|
create_if_not_found, 0);
|
||||||
|
|
||||||
g_free (component);
|
g_free (component);
|
||||||
|
|
||||||
@@ -773,10 +777,10 @@ registry_read (HKEY hpath,
|
|||||||
|
|
||||||
result = RegQueryValueExA (hpath, value_name, 0, &p_value->type, NULL, &value_data_size);
|
result = RegQueryValueExA (hpath, value_name, 0, &p_value->type, NULL, &value_data_size);
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
handle_read_error (result, path_name, value_name);
|
handle_read_error (result, path_name, value_name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_value->type == REG_SZ && value_data_size == 0)
|
if (p_value->type == REG_SZ && value_data_size == 0)
|
||||||
{
|
{
|
||||||
@@ -807,7 +811,6 @@ g_registry_backend_read (GSettingsBackend *backend,
|
|||||||
gboolean default_value)
|
gboolean default_value)
|
||||||
{
|
{
|
||||||
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
|
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
|
||||||
|
|
||||||
GNode *cache_node;
|
GNode *cache_node;
|
||||||
RegistryValue registry_value;
|
RegistryValue registry_value;
|
||||||
GVariant *gsettings_value = NULL;
|
GVariant *gsettings_value = NULL;
|
||||||
@@ -841,35 +844,43 @@ g_registry_backend_read (GSettingsBackend *backend,
|
|||||||
/* The registry is user-editable, so we need to be fault-tolerant here. */
|
/* The registry is user-editable, so we need to be fault-tolerant here. */
|
||||||
switch (gsettings_type[0])
|
switch (gsettings_type[0])
|
||||||
{
|
{
|
||||||
case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
|
case 'b':
|
||||||
if (registry_value.type == REG_DWORD)
|
case 'y':
|
||||||
gsettings_value = g_variant_new (gsettings_type, registry_value.dword);
|
case 'n':
|
||||||
break;
|
case 'q':
|
||||||
|
case 'i':
|
||||||
|
case 'u':
|
||||||
|
if (registry_value.type == REG_DWORD)
|
||||||
|
gsettings_value = g_variant_new (gsettings_type, registry_value.dword);
|
||||||
|
break;
|
||||||
|
|
||||||
case 't': case 'x':
|
case 't':
|
||||||
if (registry_value.type == REG_QWORD)
|
case 'x':
|
||||||
{
|
if (registry_value.type == REG_QWORD)
|
||||||
DWORDLONG qword_value = *(DWORDLONG *)registry_value.ptr;
|
{
|
||||||
gsettings_value = g_variant_new (gsettings_type, qword_value);
|
DWORDLONG qword_value = *(DWORDLONG *)registry_value.ptr;
|
||||||
}
|
gsettings_value = g_variant_new (gsettings_type, qword_value);
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (registry_value.type == REG_SZ)
|
if (registry_value.type == REG_SZ)
|
||||||
{
|
{
|
||||||
if (gsettings_type[0]=='s')
|
if (gsettings_type[0] == 's')
|
||||||
gsettings_value = g_variant_new_string ((char *)registry_value.ptr);
|
gsettings_value = g_variant_new_string ((char *)registry_value.ptr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gsettings_value = g_variant_parse (expected_type, registry_value.ptr, NULL, NULL, &error);
|
|
||||||
|
|
||||||
if (error != NULL)
|
gsettings_value = g_variant_parse (expected_type, registry_value.ptr,
|
||||||
|
NULL, NULL, &error);
|
||||||
|
|
||||||
|
if (error != NULL)
|
||||||
g_message ("gregistrysettingsbackend: error parsing key %s: %s",
|
g_message ("gregistrysettingsbackend: error parsing key %s: %s",
|
||||||
key_name, error->message);
|
key_name, error->message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (gsettings_type);
|
g_free (gsettings_type);
|
||||||
@@ -913,14 +924,20 @@ g_registry_backend_write_one (const char *key_name,
|
|||||||
|
|
||||||
switch (type_string[0])
|
switch (type_string[0])
|
||||||
{
|
{
|
||||||
case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
|
case 'b':
|
||||||
|
case 'y':
|
||||||
|
case 'n':
|
||||||
|
case 'q':
|
||||||
|
case 'i':
|
||||||
|
case 'u':
|
||||||
value.type = REG_DWORD;
|
value.type = REG_DWORD;
|
||||||
value.dword = g_variant_get_as_dword (variant);
|
value.dword = g_variant_get_as_dword (variant);
|
||||||
value_data_size = 4;
|
value_data_size = 4;
|
||||||
value_data = &value.dword;
|
value_data = &value.dword;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x': case 't':
|
case 'x':
|
||||||
|
case 't':
|
||||||
value.type = REG_QWORD;
|
value.type = REG_QWORD;
|
||||||
value.ptr = g_malloc (8);
|
value.ptr = g_malloc (8);
|
||||||
*(DWORDLONG *)value.ptr = g_variant_get_as_qword (variant);
|
*(DWORDLONG *)value.ptr = g_variant_get_as_qword (variant);
|
||||||
@@ -930,7 +947,7 @@ g_registry_backend_write_one (const char *key_name,
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
value.type = REG_SZ;
|
value.type = REG_SZ;
|
||||||
if (type_string[0]=='s')
|
if (type_string[0] == 's')
|
||||||
{
|
{
|
||||||
gsize length;
|
gsize length;
|
||||||
value.ptr = g_strdup (g_variant_get_string (variant, &length));
|
value.ptr = g_strdup (g_variant_get_string (variant, &length));
|
||||||
@@ -975,7 +992,8 @@ g_registry_backend_write_one (const char *key_name,
|
|||||||
result = RegCreateKeyExA (hroot, path_name, 0, NULL, 0, KEY_WRITE, NULL, &hpath, NULL);
|
result = RegCreateKeyExA (hroot, path_name, 0, NULL, 0, KEY_WRITE, NULL, &hpath, NULL);
|
||||||
if (result != ERROR_SUCCESS)
|
if (result != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
g_message_win32_error (result, "gregistrybackend: opening key %s failed", path_name+1);
|
g_message_win32_error (result, "gregistrybackend: opening key %s failed",
|
||||||
|
path_name + 1);
|
||||||
registry_value_free (value);
|
registry_value_free (value);
|
||||||
g_free (path_name);
|
g_free (path_name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -1117,7 +1135,6 @@ g_registry_backend_get_permission (GSettingsBackend *backend,
|
|||||||
return g_simple_permission_new (TRUE);
|
return g_simple_permission_new (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Spot-the-difference engine
|
* Spot-the-difference engine
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
@@ -1250,7 +1267,6 @@ registry_cache_update (GRegistryBackend *self,
|
|||||||
null_value, n_watches);
|
null_value, n_watches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
registry_cache_update (self, hsubpath, prefix, buffer, subkey_node,
|
registry_cache_update (self, hsubpath, prefix, buffer, subkey_node,
|
||||||
n_watches, changes);
|
n_watches, changes);
|
||||||
child_item = subkey_node->data;
|
child_item = subkey_node->data;
|
||||||
@@ -1336,7 +1352,8 @@ registry_cache_update (GRegistryBackend *self,
|
|||||||
|
|
||||||
/* Called by watch thread. Apply for notifications on a registry key and its subkeys. */
|
/* Called by watch thread. Apply for notifications on a registry key and its subkeys. */
|
||||||
static DWORD
|
static DWORD
|
||||||
registry_watch_key (HKEY hpath, HANDLE event)
|
registry_watch_key (HKEY hpath,
|
||||||
|
HANDLE event)
|
||||||
{
|
{
|
||||||
return RegNotifyChangeKeyValue (hpath, TRUE,
|
return RegNotifyChangeKeyValue (hpath, TRUE,
|
||||||
REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
|
REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
|
||||||
@@ -1430,7 +1447,9 @@ watch_thread_handle_message (WatchThreadState *self)
|
|||||||
{
|
{
|
||||||
RegistryWatch *watch = &self->message.watch;
|
RegistryWatch *watch = &self->message.watch;
|
||||||
LONG result;
|
LONG result;
|
||||||
|
|
||||||
result = registry_watch_key (watch->hpath, watch->event);
|
result = registry_watch_key (watch->hpath, watch->event);
|
||||||
|
|
||||||
if (result == ERROR_SUCCESS)
|
if (result == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
g_ptr_array_add (self->events, watch->event);
|
g_ptr_array_add (self->events, watch->event);
|
||||||
@@ -1457,7 +1476,7 @@ watch_thread_handle_message (WatchThreadState *self)
|
|||||||
RegistryCacheItem *cache_item;
|
RegistryCacheItem *cache_item;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
for (i=1; i<self->prefixes->len; i++)
|
for (i = 1; i < self->prefixes->len; i++)
|
||||||
if (strcmp (g_ptr_array_index (self->prefixes, i),
|
if (strcmp (g_ptr_array_index (self->prefixes, i),
|
||||||
self->message.watch.prefix) == 0)
|
self->message.watch.prefix) == 0)
|
||||||
break;
|
break;
|
||||||
@@ -1484,7 +1503,7 @@ watch_thread_handle_message (WatchThreadState *self)
|
|||||||
/* There may be more than one GSettings object subscribed to this
|
/* There may be more than one GSettings object subscribed to this
|
||||||
* path, only free the watch when the last one unsubscribes.
|
* path, only free the watch when the last one unsubscribes.
|
||||||
*/
|
*/
|
||||||
cache_item->subscription_count --;
|
cache_item->subscription_count--;
|
||||||
if (cache_item->subscription_count > 0)
|
if (cache_item->subscription_count > 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1501,7 +1520,7 @@ watch_thread_handle_message (WatchThreadState *self)
|
|||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
/* Free any remaining cache and watch handles */
|
/* Free any remaining cache and watch handles */
|
||||||
for (i=1; i<self->events->len; i++)
|
for (i = 1; i < self->events->len; i++)
|
||||||
_free_watch (self, i, g_ptr_array_index (self->cache_nodes, i));
|
_free_watch (self, i, g_ptr_array_index (self->cache_nodes, i));
|
||||||
|
|
||||||
SetEvent (self->message_received_event);
|
SetEvent (self->message_received_event);
|
||||||
@@ -1588,6 +1607,7 @@ watch_thread_function (LPVOID parameter)
|
|||||||
*/
|
*/
|
||||||
if (result != ERROR_KEY_DELETED)
|
if (result != ERROR_KEY_DELETED)
|
||||||
g_message_win32_error (result, "watch thread: failed to watch %s", prefix);
|
g_message_win32_error (result, "watch thread: failed to watch %s", prefix);
|
||||||
|
|
||||||
_free_watch (self, notify_index, cache_node);
|
_free_watch (self, notify_index, cache_node);
|
||||||
g_atomic_int_inc (&self->watches_remaining);
|
g_atomic_int_inc (&self->watches_remaining);
|
||||||
continue;
|
continue;
|
||||||
@@ -1599,11 +1619,11 @@ watch_thread_function (LPVOID parameter)
|
|||||||
cache_item = cache_node->data;
|
cache_item = cache_node->data;
|
||||||
if (cache_item->block_count)
|
if (cache_item->block_count)
|
||||||
{
|
{
|
||||||
cache_item->block_count --;
|
cache_item->block_count--;
|
||||||
trace ("Watch thread: notify blocked at %s\n", prefix);
|
trace ("Watch thread: notify blocked at %s\n", prefix);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we update our stored cache from registry data, and find which keys have
|
/* Now we update our stored cache from registry data, and find which keys have
|
||||||
* actually changed. If more changes happen while we are processing, we will get
|
* actually changed. If more changes happen while we are processing, we will get
|
||||||
* another event because we have reapplied for change notifications already.
|
* another event because we have reapplied for change notifications already.
|
||||||
@@ -1769,9 +1789,9 @@ watch_add_notify (GRegistryBackend *self,
|
|||||||
|
|
||||||
EnterCriticalSection (watch->message_lock);
|
EnterCriticalSection (watch->message_lock);
|
||||||
watch->message.type = WATCH_THREAD_ADD_WATCH;
|
watch->message.type = WATCH_THREAD_ADD_WATCH;
|
||||||
watch->message.watch.event = event;
|
watch->message.watch.event = event;
|
||||||
watch->message.watch.hpath = hpath;
|
watch->message.watch.hpath = hpath;
|
||||||
watch->message.watch.prefix = gsettings_prefix;
|
watch->message.watch.prefix = gsettings_prefix;
|
||||||
watch->message.watch.cache_node = cache_node;
|
watch->message.watch.cache_node = cache_node;
|
||||||
|
|
||||||
SetEvent (watch->message_sent_event);
|
SetEvent (watch->message_sent_event);
|
||||||
@@ -1799,7 +1819,7 @@ watch_remove_notify (GRegistryBackend *self,
|
|||||||
const gchar *key_name)
|
const gchar *key_name)
|
||||||
{
|
{
|
||||||
WatchThreadState *watch = self->watch;
|
WatchThreadState *watch = self->watch;
|
||||||
LONG result;
|
LONG result;
|
||||||
|
|
||||||
if (self->watch == NULL)
|
if (self->watch == NULL)
|
||||||
/* Here we assume that the unsubscribe message is for somewhere that was
|
/* Here we assume that the unsubscribe message is for somewhere that was
|
||||||
@@ -1842,9 +1862,8 @@ g_registry_backend_subscribe (GSettingsBackend *backend,
|
|||||||
HANDLE event;
|
HANDLE event;
|
||||||
LONG result;
|
LONG result;
|
||||||
|
|
||||||
if (self->watch == NULL)
|
if (self->watch == NULL && !watch_start (self))
|
||||||
if (!watch_start (self))
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (g_atomic_int_dec_and_test (&self->watch->watches_remaining))
|
if (g_atomic_int_dec_and_test (&self->watch->watches_remaining))
|
||||||
{
|
{
|
||||||
@@ -1901,7 +1920,6 @@ g_registry_backend_unsubscribe (GSettingsBackend *backend,
|
|||||||
watch_remove_notify (G_REGISTRY_BACKEND (backend), key_name);
|
watch_remove_notify (G_REGISTRY_BACKEND (backend), key_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Object management junk
|
* Object management junk
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
Reference in New Issue
Block a user