[kdbus] Remove some debug. Set proper error code when service is not known.
[platform/upstream/glib.git] / gio / gregistrysettingsbackend.c
1 /*
2  * Copyright © 2009-10 Sam Thursfield
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the licence, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  *
17  * Author: Sam Thursfield <ssssam@gmail.com>
18  */
19
20 /* GRegistryBackend implementation notes:
21  *
22  *   - All settings are stored under the path:
23  *       HKEY_CURRENT_USER\Software\GSettings\
24  *     This means all settings are per-user. Permissions and system-wide
25  *     defaults are not implemented and will probably always be out of scope of
26  *     the Windows port of GLib.
27  *
28  *   - The registry type system is limited. Most GVariant types are stored as
29  *     literals via g_variant_print/parse(). Strings are stored without the
30  *     quotes that GVariant requires. Integer types are stored as native
31  *     REG_DWORD or REG_QWORD. The REG_MULTI_SZ (string array) type could be
32  *     used to avoid flattening container types.
33  *
34  *   - Notifications are handled; the change event is watched for in a separate
35  *     thread (Windows does not provide a callback API) which sends them with
36  *     g_idle_add to the GLib main loop. The threading is done using Windows
37  *     API functions, so there is no dependence on GThread.
38  *
39  *   - Windows doesn't tell us which value has changed. This means we have to
40  *     maintain a cache of every stored value so we can play spot the
41  *     difference. This should not be a performance issue because if you are
42  *     storing thousands of values in GSettings, you are probably using it
43  *     wrong.
44  *
45  *   - The cache stores the value as a registry type. Because many variants are
46  *     stored as string representations, values which have changed equality but
47  *     not equivalence may trigger spurious change notifications. GSettings
48  *     users must already deal with this possibility and converting all data to
49  *     GVariant values would be more effort.
50  *
51  *   - Because we have to cache every registry value locally, reads are done
52  *     from the cache rather than directly from the registry. Writes update
53  *     both. This means that the backend will not work if the watch thread is
54  *     not running. A GSettings object always subscribes to changes so we can
55  *     be sure that the watch thread will be running, but if for some reason
56  *     the backend is being used directly you should bear that in mind.
57  *
58  *   - The registry is totally user-editable, so we are very forgiving about
59  *     errors in the data we get.
60  *
61  *   - The registry uses backslashes as path separators. GSettings keys only
62  *     allow [A-Za-z\-] so no escaping is needed. No attempt is made to solve
63  *     clashes between keys differing only in case.
64  *
65  *   - RegCreateKeyA is used - Windows can also handle UTF16LE strings.
66  *     GSettings doesn't pay any attention to encoding, so by using ANSI we
67  *     hopefully avoid passing any invalid Unicode.
68  *
69  *   - The Windows registry has the following limitations: a key may not exceed
70  *     255 characters, an entry's value may not exceed 16,383 characters, and
71  *     all the values of a key may not exceed 65,535 characters.
72  *
73  *   - Terminology:
74  *     * in GSettings, a 'key' is eg. /desktop/gnome/background/primary-color
75  *     * in the registry, the 'key' is path, which contains some 'values'.
76  *     * in this file, any GSettings key is a 'key', while a registry key is
77  *       termed a 'path', which contains 'values'.
78  *
79  *   - My set of tests for this backend are currently at:
80  *       http://gitorious.org/gsettings-gtk/gsettings-test.git
81  *
82  *   - There is an undocumented function in ntdll.dll which might be more
83  *     than RegNotifyChangeKeyValue(), NtNotifyChangeKey:
84  *       http://source.winehq.org/source/dlls/ntdll/reg.c#L618
85  *       http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Key/NtNotifyChangeKey.html
86  *
87  *   - If updating the cache ever becomes a performance issue it may make sense
88  *     to use a red-black tree, but I don't currently think it's worth the time
89  */
90
91 #include "config.h"
92
93 #include "gregistrysettingsbackend.h"
94 #include "gsimplepermission.h"
95 #include "gsettingsbackend.h"
96 #include "giomodule.h"
97
98 #include <windows.h>
99
100 //#define TRACE
101
102 /* GSettings' limit */
103 #define MAX_KEY_NAME_LENGTH   32
104
105 /* Testing (on Windows XP SP3) shows that WaitForMultipleObjects fails with
106  * "The parameter is incorrect" after 64 watches. We need one for the
107  * message_sent cond, which is allowed for in the way the watches_remaining
108  * variable is used.
109  */
110 #define MAX_WATCHES   64
111
112 /* A watch on one registry path and its subkeys */
113 typedef struct
114 {
115   HANDLE event;
116   HKEY   hpath;
117   char  *prefix;
118   GNode *cache_node;
119 } RegistryWatch;
120
121
122 /* Simple message passing for the watch thread. Not enough traffic to
123  * justify a queue.
124  */
125 typedef enum
126 {
127   WATCH_THREAD_NONE,
128   WATCH_THREAD_ADD_WATCH,
129   WATCH_THREAD_REMOVE_WATCH,
130   WATCH_THREAD_STOP
131 } WatchThreadMessageType;
132
133 typedef struct
134 {
135   WatchThreadMessageType type;
136   RegistryWatch watch;
137 } WatchThreadMessage;
138
139
140 typedef struct
141 {
142   GSettingsBackend *owner;
143   HANDLE           *thread;
144
145   /* Details of the things we are watching. */
146   int watches_remaining;
147   GPtrArray *events, *handles, *prefixes, *cache_nodes;
148
149   /* Communication with the main thread. Only one message is stored at a time,
150    * to make sure that messages are acknowledged before being overwritten we
151    * create two events - one is signalled when a new message is set, the
152    * other is signalled by the thread when it has processed the message.
153    */
154   WatchThreadMessage message;
155   CRITICAL_SECTION *message_lock;
156   HANDLE message_sent_event, message_received_event;
157 } WatchThreadState;
158
159
160 #define G_TYPE_REGISTRY_BACKEND      (g_registry_backend_get_type ())
161 #define G_REGISTRY_BACKEND(inst)     (G_TYPE_CHECK_INSTANCE_CAST ((inst),         \
162                                       G_TYPE_REGISTRY_BACKEND, GRegistryBackend))
163 #define G_IS_REGISTRY_BACKEND(inst)  (G_TYPE_CHECK_INSTANCE_TYPE ((inst),         \
164                                       G_TYPE_REGISTRY_BACKEND))
165
166
167 typedef GSettingsBackendClass GRegistryBackendClass;
168
169 typedef struct {
170   GSettingsBackend  parent_instance;
171
172   char             *base_path;
173
174   /* A stored copy of the whole tree being watched. When we receive a change notification
175    * we have to check against this to see what has changed ... every time ...*/
176   CRITICAL_SECTION *cache_lock;
177   GNode            *cache_root;
178
179   WatchThreadState *watch;
180 } GRegistryBackend;
181
182 G_DEFINE_TYPE_WITH_CODE (GRegistryBackend,
183                          g_registry_backend,
184                          G_TYPE_SETTINGS_BACKEND,
185                          g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
186                                                          g_define_type_id, "registry", 90))
187
188
189 /**********************************************************************************
190  * Utility functions
191  **********************************************************************************/
192
193 #include <stdio.h>
194 static void
195 trace (const char *format, ...)
196 {
197   #ifdef TRACE
198   va_list va; va_start (va, format);
199   vprintf (format, va); fflush (stdout);
200   va_end (va);
201   #endif
202 };
203
204 /* g_message including a windows error message. It is not useful to have an
205  * equivalent function for g_warning because none of the registry errors can
206  * result from programmer error (Microsoft programmers don't count), instead
207  * they will mostly occur from people messing with the registry by hand. */
208 static void
209 g_message_win32_error (DWORD result_code,
210                        const gchar *format,
211                       ...)
212 {
213   va_list va;
214   gint pos;
215   gchar win32_message[1024];
216
217   if (result_code == 0)
218     result_code = GetLastError ();
219
220   va_start (va, format);
221   pos = g_vsnprintf (win32_message, 512, format, va);
222
223   win32_message[pos++] = ':'; win32_message[pos++] = ' ';
224
225   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, result_code, 0, (LPTSTR)(win32_message+pos),
226                 1023 - pos, NULL);
227
228   if (result_code == ERROR_KEY_DELETED)
229     trace ("(%s)", win32_message);
230   else
231     g_message (win32_message);
232 };
233
234
235 /* Make gsettings key into a registry path & value pair. 
236  * 
237  * Note that the return value *only* needs freeing - registry_value_name
238  * is a pointer to further inside the same block of memory.
239  */
240 static gchar *
241 parse_key (const gchar  *key_name,
242            const gchar  *registry_prefix,
243            gchar       **value_name)
244 {
245   gchar *path_name, *c;
246
247   /* All key paths are treated as absolute; gsettings doesn't seem to enforce a
248    * preceding /.
249    */
250   if (key_name[0] == '/')
251     key_name ++;
252
253   if (registry_prefix == NULL)
254       path_name = g_strdup (key_name);
255   else
256       path_name = g_strjoin ("/", registry_prefix, key_name, NULL);
257
258   /* Prefix is expected to be in registry format (\ separators) so don't escape that. */
259   for (c=path_name+(registry_prefix?strlen(registry_prefix):0); *c!=0; c++)
260       if (*c == '/')
261         {
262           *c = '\\';
263           (*value_name) = c;
264         }
265
266   **value_name = 0; (*value_name)++;
267   return path_name;
268 };
269
270
271 static DWORD
272 g_variant_get_as_dword (GVariant *variant)
273 {
274   switch (g_variant_get_type_string (variant)[0])
275     {
276       case 'b': return g_variant_get_boolean (variant);
277       case 'y': return g_variant_get_byte (variant);
278       case 'n': return g_variant_get_int16 (variant);
279       case 'q': return g_variant_get_uint16 (variant);
280       case 'i': return g_variant_get_int32 (variant);
281       case 'u': return g_variant_get_uint32 (variant);
282       default:  g_warn_if_reached ();
283     }
284   return 0;
285 }
286
287 static DWORDLONG
288 g_variant_get_as_qword (GVariant *variant)
289 {
290   switch (g_variant_get_type_string (variant)[0])
291     {
292       case 'x': return g_variant_get_int64 (variant);
293       case 't': return g_variant_get_uint64 (variant);
294       default:  g_warn_if_reached ();
295     }
296   return 0;
297 }
298
299
300 static void
301 handle_read_error (LONG         result,
302                    const gchar *path_name,
303                    const gchar *value_name)
304 {
305   /* file not found means key value not set, this isn't an error for us. */
306   if (result != ERROR_FILE_NOT_FOUND)
307       g_message_win32_error (result, "Unable to query value %s/%s: %s.\n",
308                              path_name, value_name);
309 }
310
311 /***************************************************************************
312  * Cache of registry values
313  ***************************************************************************/
314
315 /* Generic container for registry values */
316 typedef struct {
317   DWORD type;
318
319   union {
320     gint  dword;  /* FIXME: could inline QWORD on 64-bit systems too */
321     void *ptr;
322   };
323 } RegistryValue;
324
325 static char *
326 registry_value_dump (RegistryValue value)
327 {
328   if (value.type == REG_DWORD)
329     return g_strdup_printf ("%i", value.dword);
330   else if (value.type == REG_QWORD)
331     return g_strdup_printf ("%I64i", value.ptr==NULL? 0: *(DWORDLONG *)value.ptr);
332   else if (value.type == REG_SZ)
333     return g_strdup_printf ("%s", (char *)value.ptr);
334   else if (value.type == REG_NONE)
335     return g_strdup_printf ("<empty>");
336   else
337     return g_strdup_printf ("<invalid>");
338 }
339
340 static void
341 registry_value_free (RegistryValue value)
342 {
343   if (value.type == REG_SZ || value.type == REG_QWORD)
344     g_free (value.ptr);
345   value.type = REG_NONE;
346   value.ptr = NULL;
347 }
348
349
350 /* The registry cache is stored as a tree, for easy traversal. Right now we
351  * don't sort it in a clever way. Each node corresponds to a path element
352  * ('key' in registry terms) or a value.
353  *
354  * Each subscription uses the same cache. Because GSettings can subscribe to
355  * the tree at any node any number of times, we need to reference count the
356  * nodes.
357  */
358 typedef struct
359 {
360   /* Component of path that this node represents */
361   gchar *name;           
362
363   /* If a watch is subscribed at this point (subscription_count > 0) we can
364    * block its next notification. This is useful because if two watches cover
365    * the same path, both will trigger when it changes. It also allows changes
366    * done by the application to be ignored by the watch thread.
367    */
368   gint32 block_count        : 8;
369
370   /* Number of times g_settings_subscribe has been called for this location
371    * (I guess you can't subscribe more than 16383 times) */
372   gint32 subscription_count : 14;
373   
374   gint32 ref_count          : 9;
375
376   gint32 touched            : 1;
377   RegistryValue value;
378 } RegistryCacheItem;
379
380
381
382 static GNode *
383 registry_cache_add_item (GNode        *parent,
384                          gchar        *name,
385                          RegistryValue value,
386                          gint          ref_count)
387 {
388   RegistryCacheItem *item = g_slice_new (RegistryCacheItem);
389   GNode *cache_node;
390
391   g_return_val_if_fail (name != NULL, NULL);
392   g_return_val_if_fail (parent != NULL, NULL);
393
394   /* Ref count should be the number of watch points above this node */
395   item->ref_count = ref_count;
396
397   item->name = g_strdup (name);
398   item->value = value;
399   item->subscription_count = 0;
400   item->block_count = 0;
401   item->touched = FALSE;
402   trace ("\treg cache: adding %s to %s\n", name, ((RegistryCacheItem *)parent->data)->name);
403
404   cache_node = g_node_new (item);
405   g_node_append (parent, cache_node);
406   return cache_node;
407 }
408
409 /* The reference counting of cache tree nodes works like this: when a node is
410  * subscribed to (GSettings wants us to watch that path and everything below
411  * it) the reference count of that node and everything below is increased, as
412  * well as each parent up to the root.
413  */
414
415
416 static void
417 _ref_down (GNode *node)
418 {
419   RegistryCacheItem *item = node->data;
420   g_node_children_foreach (node, G_TRAVERSE_ALL,
421                            (GNodeForeachFunc)_ref_down, NULL);
422   item->ref_count ++;
423 }
424 static void
425 registry_cache_ref_tree (GNode *tree)
426 {
427   RegistryCacheItem *item = tree->data;
428   GNode *node = tree->parent;
429
430   g_return_if_fail (tree != NULL);
431
432   item->ref_count ++;
433
434   g_node_children_foreach (tree, G_TRAVERSE_ALL,
435                            (GNodeForeachFunc)_ref_down, NULL);
436
437   for (node=tree->parent; node; node=node->parent)
438     {
439       item = node->data;
440       item->ref_count ++;
441     }
442 }
443
444 static void
445 _free_cache_item (RegistryCacheItem *item)
446 {
447   trace ("\t -- Free node %s\n", item->name);
448   g_free (item->name);
449   registry_value_free (item->value);
450   g_slice_free (RegistryCacheItem, item);
451 }
452
453 /* Unreferencing has to be done bottom-up */
454 static void
455 _unref_node (GNode *node)
456 {
457   RegistryCacheItem *item = node->data;
458
459   item->ref_count --;
460
461   g_warn_if_fail (item->ref_count >= 0);
462
463   if (item->ref_count == 0)
464     {
465       _free_cache_item (item);
466       g_node_destroy (node);
467     }
468 }
469
470 static void
471 _unref_down (GNode *node)
472 {
473   g_node_children_foreach (node, G_TRAVERSE_ALL,
474                            (GNodeForeachFunc)_unref_down, NULL);
475   _unref_node (node);
476 }
477
478 static void
479 registry_cache_unref_tree (GNode *tree)
480 {
481   GNode *parent = tree->parent, *next_parent;
482
483   _unref_down (tree);
484
485   while (parent)
486     {
487       next_parent = parent->parent;
488       _unref_node (parent);
489       parent = next_parent;
490     }
491 }
492
493 #if 0
494 static void
495 registry_cache_dump (GNode    *cache_node,
496                      gpointer  data)
497 {
498   RegistryCacheItem *item = cache_node->data;
499
500   int depth     = GPOINTER_TO_INT(data),
501       new_depth = depth+1,
502       i;
503
504   g_return_if_fail (cache_node != NULL);
505
506   for (i=0; i<depth; i++)
507     g_print ("  ");
508   if (item == NULL)
509     g_print ("*root*\n");
510   else
511     g_print ("'%s'  [%i] @ %x = %s\n", item->name, item->ref_count, (guint)cache_node,
512              registry_value_dump (item->value));
513   g_node_children_foreach (cache_node, G_TRAVERSE_ALL, registry_cache_dump,
514                            GINT_TO_POINTER (new_depth));
515 }
516 #endif
517
518 typedef struct
519 {
520   gchar *name;
521   GNode *result;
522 } RegistryCacheSearch;
523
524 static gboolean
525 registry_cache_find_compare (GNode    *node,
526                              gpointer  data)
527 {
528   RegistryCacheSearch *search = data;
529   RegistryCacheItem *item = node->data;
530
531   if (item == NULL)  /* root node */
532     return FALSE;
533
534   g_return_val_if_fail (search->name != NULL, FALSE);
535   g_return_val_if_fail (item->name != NULL, FALSE);
536
537   if (strcmp (search->name, item->name) == 0)
538     {
539       search->result = node;
540       return TRUE;
541     }
542   return FALSE;
543 }
544
545 static GNode *
546 registry_cache_find_immediate_child (GNode *node,
547                                      gchar *name)
548 {
549   RegistryCacheSearch search;
550   search.result = NULL;
551   search.name = name;
552   g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, 2,
553                    registry_cache_find_compare, &search);
554   return search.result;  
555 }
556
557
558 static GNode *
559 registry_cache_get_node_for_key_recursive (GNode    *node,
560                                            gchar    *key_name,
561                                            gboolean  create_if_not_found,
562                                            gint      n_parent_watches)
563 {
564   RegistryCacheItem *item;
565   gchar *component = key_name,
566         *c         = strchr (component, '/');
567   GNode *child;
568
569   if (c != NULL)
570     *c = 0;
571
572   /* We count up how many watch points we travel through finding this node,
573    * because a new node should have as many references as there are watches at
574    * points above it in the tree.
575    */
576   item = node->data;
577   if (item->subscription_count > 0)
578     n_parent_watches ++;  
579
580   child = registry_cache_find_immediate_child (node, component);
581   if (child == NULL && create_if_not_found)
582     {
583       item = g_slice_new (RegistryCacheItem);
584       item->name = g_strdup (component);
585       item->value.type = REG_NONE;
586       item->value.ptr = NULL;
587       item->ref_count = n_parent_watches;
588       child = g_node_new (item);
589       g_node_append (node, child);
590       trace ("\tget node for key recursive: new %x = %s.\n", node, item->name);
591     }
592
593   /* We are done if there are no more path components. Allow for a trailing /. */
594   if (child==NULL || c == NULL || *(c+1)==0)
595     return child;
596   else
597     {
598       trace ("get node for key recursive: next: %s.\n", c+1);
599       return registry_cache_get_node_for_key_recursive
600                (child, c+1, create_if_not_found, n_parent_watches);
601     }
602 }
603
604 /* Look up a GSettings key in the cache. */
605 static GNode *
606 registry_cache_get_node_for_key (GNode       *root,
607                                  const gchar *key_name,
608                                  gboolean     create_if_not_found)
609 {
610   GNode *child = NULL,
611         *result = NULL;
612   gchar *component, *c;
613
614   g_return_val_if_fail (key_name != NULL, NULL);
615
616   if (key_name[0] == '/')
617     key_name ++;
618
619   /* Ignore preceding / */
620   component = g_strdup (key_name);
621   c = strchr (component, '/');
622   if (c != NULL)
623     *c = 0;
624
625   child = registry_cache_find_immediate_child (root, component);
626   if (child == NULL && create_if_not_found)
627     {
628       /* Reference count is set to 0, tree should be referenced by the caller */
629       RegistryCacheItem *item = g_slice_new (RegistryCacheItem);
630       item->value.type = REG_NONE;
631       item->value.ptr = NULL;
632       item->name = g_strdup (component);
633       item->ref_count = 0;
634       trace ("get_node_for_key: New node for component '%s'\n", item->name);
635       child = g_node_new (item);
636       g_node_append (root, child);
637     }
638
639   if (c == NULL)
640     result = root;
641   else if (*(c+1)==0)
642     result = child;
643   else if (child != NULL)
644     result = registry_cache_get_node_for_key_recursive (child, c+1, create_if_not_found, 0);
645
646   g_free (component);
647
648   return result;
649 }
650
651 /* Check the cache node against the registry key it represents. Return TRUE if
652  * they differ, and update the cache with the new value.
653  */
654 static gboolean
655 registry_cache_update_node (GNode        *cache_node,
656                             RegistryValue registry_value)
657 {
658   RegistryCacheItem *cache_item = cache_node->data;
659
660   g_return_val_if_fail (cache_node != NULL, FALSE);
661   g_return_val_if_fail (cache_item != NULL, FALSE);
662
663   if (registry_value.type != cache_item->value.type)
664     {
665       /* The type has changed. Update cache item and register it as changed.
666        * Either the schema has changed and this is entirely legitimate, or
667        * whenever the app reads the key it will get the default value due to
668        * the type mismatch.
669        */
670       cache_item->value = registry_value;
671       return TRUE;
672     }
673  
674   switch (registry_value.type)
675     {
676       case REG_DWORD:
677         {
678           if (cache_item->value.dword == registry_value.dword)
679             return FALSE;
680           else
681             {
682               cache_item->value.dword = registry_value.dword;
683               return TRUE;
684             }
685         }
686       case REG_QWORD:
687         {
688           g_return_val_if_fail (registry_value.ptr != NULL &&
689                                 cache_item->value.ptr != NULL, FALSE);
690
691           if (memcmp (registry_value.ptr, cache_item->value.ptr, 8)==0)
692             {
693               g_free (registry_value.ptr);
694               return FALSE;
695             }
696           else
697             {
698               g_free (cache_item->value.ptr);
699               cache_item->value.ptr = registry_value.ptr;
700               return TRUE;
701             }
702         }
703       case REG_SZ:
704         {
705           /* Value should not exist if it is NULL, an empty string is "" */
706           g_return_val_if_fail (cache_item->value.ptr != NULL, FALSE);
707           g_return_val_if_fail (registry_value.ptr != NULL, FALSE);
708
709           if (strcmp (registry_value.ptr, cache_item->value.ptr) == 0)
710             {
711               g_free (registry_value.ptr);
712               return FALSE;
713             }
714           else
715             {
716               g_free (cache_item->value.ptr);
717               cache_item->value.ptr = registry_value.ptr;
718               return TRUE;
719             }
720         }
721       default:
722         g_warning ("gregistrybackend: registry_cache_update_node: Unhandled value type :(");
723         return FALSE;
724     }
725 }
726
727 /* Blocking notifications is a useful optimisation. When a change is made
728  * through GSettings we update the cache manually, but a notifcation is
729  * triggered as well. This function is also used for nested notifications,
730  * eg. if /test and /test/foo are watched, and /test/foo/value is changed then
731  * we will get notified both for /test/foo and /test and it is helpful to block
732  * the second.
733  */
734 static void
735 registry_cache_block_notification (GNode *node)
736 {
737   RegistryCacheItem *item = node->data;
738
739   g_return_if_fail (node != NULL);
740
741   if (item->subscription_count > 0)
742     item->block_count ++;
743
744   if (node->parent != NULL)
745     registry_cache_block_notification (node->parent);
746 }
747
748 static void
749 registry_cache_destroy_tree (GNode            *node,
750                              WatchThreadState *self);
751
752 /***************************************************************************
753  * Reading and writing
754  ***************************************************************************/
755
756 static gboolean
757 registry_read (HKEY           hpath,
758                const gchar   *path_name,
759                const gchar   *value_name,
760                RegistryValue *p_value)
761 {
762   LONG      result;
763   DWORD     value_data_size;
764   gpointer *buffer;
765
766   g_return_val_if_fail (p_value != NULL, FALSE);
767
768   p_value->type = REG_NONE;
769   p_value->ptr = NULL;
770
771   result = RegQueryValueExA (hpath, value_name, 0, &p_value->type, NULL, &value_data_size);
772   if (result != ERROR_SUCCESS)
773      {
774       handle_read_error (result, path_name, value_name);
775       return FALSE;
776      }
777
778   if (p_value->type == REG_SZ && value_data_size == 0)
779     {
780       p_value->ptr = g_strdup ("");
781       return TRUE;
782     }
783
784   if (p_value->type == REG_DWORD)
785     /* REG_DWORD is inlined */
786     buffer = (void *)&p_value->dword;
787   else
788     buffer = p_value->ptr = g_malloc (value_data_size);
789
790   result = RegQueryValueExA (hpath, value_name, 0, NULL, (LPBYTE)buffer, &value_data_size);
791   if (result != ERROR_SUCCESS)
792     {
793       handle_read_error (result, path_name, value_name);
794       return FALSE;
795     }
796
797   return TRUE;
798 }
799
800
801 static GVariant *
802 g_registry_backend_read (GSettingsBackend   *backend,
803                          const gchar        *key_name,
804                          const GVariantType *expected_type,
805                          gboolean            default_value)
806 {
807   GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
808
809   GNode         *cache_node;
810   RegistryValue  registry_value;
811   GVariant      *gsettings_value = NULL;
812   gchar         *gsettings_type;
813
814   g_return_val_if_fail (expected_type != NULL, NULL);
815
816   if (default_value)
817     return NULL;
818
819   /* Simply read from the cache, which is updated from the registry by the
820    * watch thread as soon as changes can propagate. Any changes not yet in the
821    * cache will have the 'changed' signal emitted after this function returns.
822    */
823   EnterCriticalSection (self->cache_lock);
824   cache_node = registry_cache_get_node_for_key (self->cache_root, key_name, FALSE);
825   LeaveCriticalSection (self->cache_lock);
826
827   trace ("Reading key %s, cache node %x\n", key_name, cache_node);
828
829   /* Maybe it's not set, we can return to default */
830   if (cache_node == NULL)
831     return NULL;
832
833   trace ("\t- cached value %s\n", registry_value_dump (((RegistryCacheItem *)cache_node->data)->value));
834
835   registry_value = ((RegistryCacheItem *)cache_node->data)->value;
836
837   gsettings_type = g_variant_type_dup_string (expected_type);
838
839   /* The registry is user-editable, so we need to be fault-tolerant here. */
840   switch (gsettings_type[0])
841     {
842       case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
843         if (registry_value.type == REG_DWORD)
844           gsettings_value = g_variant_new (gsettings_type, registry_value.dword);
845         break;
846
847       case 't': case 'x':
848         if (registry_value.type == REG_QWORD)
849           {
850             DWORDLONG qword_value = *(DWORDLONG *)registry_value.ptr;
851             gsettings_value = g_variant_new (gsettings_type, qword_value);
852           }
853         break;
854
855       default:
856         if (registry_value.type == REG_SZ)
857           {
858             if (gsettings_type[0]=='s')
859               gsettings_value = g_variant_new_string ((char *)registry_value.ptr);
860             else
861               {
862                 GError *error = NULL;
863                 gsettings_value = g_variant_parse (expected_type, registry_value.ptr, NULL, NULL, &error);
864
865                 if (error != NULL)
866                 g_message ("gregistrysettingsbackend: error parsing key %s: %s\n",
867                            key_name, error->message);
868               }
869           }
870           break;
871     }
872
873   g_free (gsettings_type);
874
875   return gsettings_value;
876 }
877
878
879 typedef struct
880 {
881   GRegistryBackend  *self;
882   HKEY               hroot;
883 } RegistryWrite;
884
885 static gboolean
886 g_registry_backend_write_one (const char *key_name,
887                               GVariant   *variant,
888                               gpointer    user_data)
889 {
890   GRegistryBackend *self;
891   RegistryWrite    *action;
892   RegistryValue     value;
893
894   HKEY    hroot, hpath;
895   gchar  *path_name, *value_name = NULL;
896   DWORD   value_data_size;
897   LPVOID  value_data;
898   LONG    result;
899
900   GNode    *node;
901   gboolean  changed;
902
903   const gchar *type_string = g_variant_get_type_string (variant);
904
905   action = user_data;
906   self = G_REGISTRY_BACKEND (action->self);
907   hroot = action->hroot;
908
909   value.type = REG_NONE;
910   value.ptr = NULL;
911
912   switch (type_string[0])
913     {
914       case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
915         value.type = REG_DWORD;
916         value.dword = g_variant_get_as_dword (variant);
917         value_data_size = 4;
918         value_data = &value.dword;
919         break;
920
921       case 'x': case 't':
922         value.type = REG_QWORD;
923         value.ptr = g_malloc (8);
924         *(DWORDLONG *)value.ptr = g_variant_get_as_qword (variant);
925         value_data_size = 8;
926         value_data = value.ptr;
927         break;
928
929       default:
930         value.type = REG_SZ;
931         if (type_string[0]=='s')
932           {
933             gsize length;
934             value.ptr = g_strdup (g_variant_get_string (variant, &length));
935             value_data_size = length + 1;
936             value_data = value.ptr;
937           }
938         else
939           {
940             GString *value_string;
941             value_string = g_variant_print_string (variant, NULL, FALSE);
942             value_data_size = value_string->len+1;
943             value.ptr = value_data = g_string_free (value_string, FALSE);
944           }
945         break;
946     }
947
948   /* First update the cache, because the value may not have changed and we can
949    * save a write.
950    * 
951    * If 'value' has changed then its memory will not be freed by update_node(),
952    * because it will be stored in the node.
953    */
954   EnterCriticalSection (self->cache_lock);
955   node = registry_cache_get_node_for_key (self->cache_root, key_name, TRUE);
956   changed = registry_cache_update_node (node, value);
957   LeaveCriticalSection (self->cache_lock);
958
959   if (!changed)
960     return FALSE;
961
962   /* Block the next notification to any watch points above this location,
963    * because they will each get triggered on a change that is already updated
964    * in the cache.
965    */
966   registry_cache_block_notification (node);
967
968   path_name = parse_key (key_name, NULL, &value_name);
969
970   trace ("Set key: %s / %s\n", path_name, value_name);
971
972   /* Store the value in the registry */
973   result = RegCreateKeyExA (hroot, path_name, 0, NULL, 0, KEY_WRITE, NULL, &hpath, NULL);
974   if (result != ERROR_SUCCESS)
975     {
976       g_message_win32_error (result, "gregistrybackend: opening key %s failed", path_name+1);
977       registry_value_free (value);
978       g_free (path_name);
979       return FALSE;
980     }
981
982   result = RegSetValueExA (hpath, value_name, 0, value.type, value_data, value_data_size);
983   if (result != ERROR_SUCCESS)
984       g_message_win32_error (result, "gregistrybackend: setting value %s\\%s\\%s failed.\n",
985                              self->base_path, path_name, value_name);
986
987   /* If the write fails then it will seem like the value has changed until the
988    * next execution (because we wrote to the cache first). There's no reason
989    * for it to fail unless something is weirdly broken, however.
990    */
991
992   RegCloseKey (hpath);
993   g_free (path_name);
994
995   return FALSE;
996 };
997
998 /* The dconf write policy is to do the write while making out it succeeded, 
999  * and then backtrack if it didn't. The registry functions are synchronous so
1000  * we can't do that. */
1001
1002 static gboolean
1003 g_registry_backend_write (GSettingsBackend *backend,
1004                           const gchar      *key_name,
1005                           GVariant         *value,
1006                           gpointer          origin_tag)
1007 {
1008   GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
1009   LONG result;
1010   HKEY hroot;
1011   RegistryWrite action;
1012
1013   result = RegCreateKeyExA (HKEY_CURRENT_USER, self->base_path, 0, NULL, 0,
1014                             KEY_WRITE, NULL, &hroot, NULL);
1015   if (result != ERROR_SUCCESS) {
1016     trace ("Error opening/creating key %s.\n", self->base_path);
1017     return FALSE;
1018   }
1019
1020   action.self = self;
1021   action.hroot = hroot;
1022   g_registry_backend_write_one (key_name, value, &action);
1023   g_settings_backend_changed (backend, key_name, origin_tag);
1024
1025   RegCloseKey (hroot);
1026
1027   return TRUE;
1028 }
1029
1030 static gboolean
1031 g_registry_backend_write_tree (GSettingsBackend *backend,
1032                                GTree            *values,
1033                                gpointer          origin_tag)
1034 {
1035   GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
1036   LONG result;
1037   HKEY hroot;
1038   RegistryWrite action;
1039
1040   result = RegCreateKeyExA (HKEY_CURRENT_USER, self->base_path, 0, NULL, 0,
1041                             KEY_WRITE, NULL, &hroot, NULL);
1042   if (result != ERROR_SUCCESS) {
1043     trace ("Error opening/creating key %s.\n", self->base_path);
1044     return FALSE;
1045   }
1046
1047   action.self =  self;
1048   action.hroot = hroot;
1049   g_tree_foreach (values, (GTraverseFunc)g_registry_backend_write_one,
1050                   &action);
1051
1052   g_settings_backend_changed_tree (backend, values, origin_tag);
1053   RegCloseKey (hroot);
1054
1055   return TRUE;
1056 }
1057
1058 static void
1059 g_registry_backend_reset (GSettingsBackend *backend,
1060                           const gchar      *key_name,
1061                           gpointer          origin_tag)
1062 {
1063   GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
1064   gchar *path_name, *value_name = NULL;
1065   GNode *cache_node;
1066   LONG result;
1067   HKEY hpath;
1068
1069   /* Remove from cache */
1070   EnterCriticalSection (self->cache_lock);
1071   cache_node = registry_cache_get_node_for_key (self->cache_root, key_name, FALSE);
1072   if (cache_node)
1073     registry_cache_destroy_tree (cache_node, self->watch);
1074   LeaveCriticalSection (self->cache_lock);
1075
1076   /* Remove from the registry */
1077   path_name = parse_key (key_name, self->base_path, &value_name);
1078
1079   result = RegOpenKeyExA (HKEY_CURRENT_USER, path_name, 0, KEY_SET_VALUE, &hpath);
1080   if (result != ERROR_SUCCESS)
1081     {
1082       g_message_win32_error (result, "Registry: resetting key '%s'", path_name);
1083       g_free (path_name);
1084       return;
1085     }
1086
1087   result = RegDeleteValueA (hpath, value_name);
1088   RegCloseKey (hpath);
1089
1090   if (result != ERROR_SUCCESS)
1091     {
1092       g_message_win32_error (result, "Registry: resetting key '%s'", path_name);
1093       g_free (path_name);
1094       return;
1095     }
1096
1097   g_free (path_name);
1098
1099
1100   g_settings_backend_changed (backend, key_name, origin_tag);
1101 }
1102
1103 /* Not implemented and probably beyond the scope of this backend */
1104 static gboolean
1105 g_registry_backend_get_writable (GSettingsBackend *backend,
1106                                  const gchar      *key_name)
1107 {
1108   return TRUE;
1109 }
1110
1111 static GPermission *
1112 g_registry_backend_get_permission (GSettingsBackend *backend,
1113                                    const gchar      *key_name)
1114 {
1115   return g_simple_permission_new (TRUE);
1116 }
1117
1118
1119 /********************************************************************************
1120  * Spot-the-difference engine
1121  ********************************************************************************/
1122
1123 static void
1124 _free_watch (WatchThreadState *self,
1125              gint              index,
1126              GNode            *cache_node);
1127
1128 static void
1129 registry_cache_item_reset_touched (GNode    *node,
1130                                    gpointer  data)
1131 {
1132   RegistryCacheItem *item = node->data;
1133   item->touched = FALSE;
1134 }
1135
1136 /* Delete a node and any children, for when it has been deleted from the registry */
1137 static void
1138 registry_cache_destroy_tree (GNode            *node,
1139                              WatchThreadState *self)
1140 {
1141   RegistryCacheItem *item = node->data;
1142
1143   g_node_children_foreach (node, G_TRAVERSE_ALL,
1144                            (GNodeForeachFunc)registry_cache_destroy_tree, self);
1145
1146   if (item->subscription_count > 0)
1147     {
1148           gint i;
1149       /* There must be some watches active if this node is a watch point */
1150       g_warn_if_fail (self->cache_nodes->len > 1);
1151
1152       /* This is a watch point that has been deleted. Let's free the watch! */
1153       for (i=1; i<self->cache_nodes->len; i++)
1154         if (g_ptr_array_index (self->cache_nodes, i) == node)
1155           break;
1156       if (i >= self->cache_nodes->len)
1157         g_warning ("watch thread: a watch point was deleted, but unable to "
1158                    "find '%s' in the list of %i watch nodes\n", item->name,
1159                    self->cache_nodes->len-1);
1160       else
1161         {
1162           _free_watch (self, i, node);
1163           g_atomic_int_inc (&self->watches_remaining);
1164         }
1165     }
1166   _free_cache_item (node->data);
1167   g_node_destroy (node);
1168 }
1169
1170 static void
1171 registry_cache_remove_deleted (GNode    *node,
1172                                gpointer  data)
1173 {
1174   RegistryCacheItem *item = node->data;
1175
1176   if (!item->touched)
1177     registry_cache_destroy_tree (node, data);
1178 }
1179
1180 /* Update cache from registry, and optionally report on the changes.
1181  * 
1182  * This function is sometimes called from the watch thread, with no locking. It
1183  * does call g_registry_backend functions, but this is okay because they only
1184  * access self->base which is constant.
1185  *
1186  * When looking at this code bear in mind the terminology: in the registry, keys
1187  * are containers that contain values, and other keys. Keys have a 'default'
1188  * value which we always ignore.
1189  *
1190  * n_parent_watches: a counter used to set the reference count of any new nodes
1191  *                   that are created - they should have as many references as
1192  *                   there are notifications that are watching them.
1193  */
1194 static void
1195 registry_cache_update (GRegistryBackend *self,
1196                        HKEY              hpath,
1197                        const gchar      *prefix,
1198                        const gchar      *partial_key_name,
1199                        GNode            *cache_node,
1200                        int               n_watches, 
1201                        GPtrArray        *changes)
1202 {
1203   gchar  buffer[MAX_KEY_NAME_LENGTH + 1];
1204   gchar *key_name;
1205   gint   i;
1206   LONG   result;
1207
1208   RegistryCacheItem *item = cache_node->data;
1209
1210   if (item->subscription_count > 0)
1211     n_watches ++;
1212
1213   /* prefix is the level that all changes occur below; partial_key_name should
1214    * be NULL on the first call to this function */
1215   key_name = g_build_path ("/", prefix, partial_key_name, NULL);
1216
1217   trace ("registry cache update: %s. Node %x has %i children\n", key_name,
1218          cache_node, g_node_n_children (cache_node));
1219
1220   /* Start by zeroing 'touched' flag. When the registry traversal is done, any untouched nodes
1221    * must have been deleted from the registry.
1222    */
1223   g_node_children_foreach (cache_node, G_TRAVERSE_ALL,
1224                            registry_cache_item_reset_touched, NULL);
1225
1226   /* Recurse into each subpath at the current level, if any */
1227   i = 0;
1228   while (1)
1229     {
1230       DWORD buffer_size = MAX_KEY_NAME_LENGTH;
1231       HKEY  hsubpath;
1232
1233       result = RegEnumKeyEx (hpath, i++, buffer, &buffer_size, NULL, NULL, NULL, NULL);
1234       if (result != ERROR_SUCCESS)
1235         break;
1236
1237       result = RegOpenKeyEx (hpath, buffer, 0, KEY_READ, &hsubpath);
1238       if (result == ERROR_SUCCESS)
1239         {
1240           GNode             *subkey_node;
1241           RegistryCacheItem *child_item;
1242
1243           subkey_node = registry_cache_find_immediate_child (cache_node, buffer);
1244           if (subkey_node == NULL)
1245             {
1246               RegistryValue null_value = {REG_NONE, {0}};
1247               subkey_node = registry_cache_add_item (cache_node, buffer,
1248                                                      null_value, n_watches);
1249             }
1250
1251
1252           registry_cache_update (self, hsubpath, prefix, buffer, subkey_node,
1253                                  n_watches, changes);
1254           child_item = subkey_node->data;
1255           child_item->touched = TRUE;
1256         }
1257       RegCloseKey (hsubpath);
1258     }
1259
1260   if (result != ERROR_NO_MORE_ITEMS)
1261     g_message_win32_error (result, "gregistrybackend: error enumerating subkeys for cache.");
1262
1263   /* Enumerate each value at 'path' and check if it has changed */
1264   i = 0;
1265   while (1)
1266     {
1267       DWORD              buffer_size = MAX_KEY_NAME_LENGTH;
1268       GNode             *cache_child_node;
1269       RegistryCacheItem *child_item;
1270       RegistryValue      value;
1271       gboolean           changed = FALSE;
1272
1273       result = RegEnumValue (hpath, i++, buffer, &buffer_size, NULL, NULL, NULL, NULL);
1274       if (result != ERROR_SUCCESS)
1275         break;
1276
1277       if (buffer[0]==0)
1278         /* This is the key's 'default' value, for which we have no use. */
1279         continue;
1280
1281       cache_child_node = registry_cache_find_immediate_child (cache_node, buffer);
1282
1283       if (!registry_read (hpath, key_name, buffer, &value))
1284         continue;
1285
1286       trace ("\tgot value %s for %s, node %x\n", registry_value_dump (value), buffer, cache_child_node);
1287
1288       if (cache_child_node == NULL)
1289         {
1290           /* This is a new value */
1291           cache_child_node = registry_cache_add_item (cache_node, buffer, value,
1292                                                       n_watches);
1293           changed = TRUE;
1294         }
1295       else
1296         {
1297          /* For efficiency, instead of converting every value back to a GVariant to
1298           * compare it, we compare them as registry values (integers, or string
1299           * representations of the variant). The spurious change notifications that may
1300           * result should not be a big issue.
1301           *
1302           * Note that 'value' is swallowed or freed.
1303           */
1304           changed = registry_cache_update_node (cache_child_node, value);
1305         }
1306
1307       child_item = cache_child_node->data;
1308       child_item->touched = TRUE;
1309       if (changed == TRUE && changes != NULL)
1310         {
1311           gchar *item;
1312           if (partial_key_name == NULL)
1313             item = g_strdup (buffer);
1314           else
1315             item = g_build_path ("/", partial_key_name, buffer, NULL);
1316           g_ptr_array_add (changes, item);
1317         }
1318     }
1319
1320   if (result != ERROR_NO_MORE_ITEMS)
1321     g_message_win32_error (result, "gregistrybackend: error enumerating values for cache");
1322
1323   /* Any nodes now left untouched must have been deleted, remove them from cache */
1324   g_node_children_foreach (cache_node, G_TRAVERSE_ALL,
1325                            registry_cache_remove_deleted, self->watch);
1326
1327   trace ("registry cache update complete.\n");
1328   g_free (key_name);
1329 };
1330
1331
1332
1333 /***********************************************************************************
1334  * Thread to watch for registry change events
1335  ***********************************************************************************/
1336
1337 /* Called by watch thread. Apply for notifications on a registry key and its subkeys. */
1338 static DWORD
1339 registry_watch_key (HKEY hpath, HANDLE event)
1340 {
1341   return RegNotifyChangeKeyValue (hpath, TRUE,
1342                                   REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
1343                                   event, TRUE);
1344 }
1345
1346
1347 /* One of these is sent down the pipe when something happens in the registry. */
1348 typedef struct
1349 {
1350   GRegistryBackend *self;
1351   gchar *prefix;          /* prefix is a gsettings path, all items are subkeys of this. */
1352   GPtrArray *items;       /* each item is a subkey below prefix that has changed. */
1353 } RegistryEvent;
1354
1355 /* This handler runs in the main thread to emit the changed signals */
1356 static gboolean
1357 watch_handler (RegistryEvent *event)
1358 {
1359   gint i;
1360   trace ("Watch handler: got event in %s, items %i.\n", event->prefix, event->items->len);
1361
1362   /* GSettings requires us to NULL-terminate the array. */
1363   g_ptr_array_add (event->items, NULL);
1364   g_settings_backend_keys_changed (G_SETTINGS_BACKEND (event->self), event->prefix,
1365                                    (gchar const **)event->items->pdata, NULL);
1366
1367   for (i=0; i<event->items->len; i++)
1368     g_free (g_ptr_array_index (event->items, i));
1369   g_ptr_array_free (event->items, TRUE);
1370
1371   g_free (event->prefix);
1372   g_object_unref (event->self);
1373   
1374   g_slice_free (RegistryEvent, event);
1375   return G_SOURCE_REMOVE;
1376 };
1377
1378
1379 static void
1380 _free_watch (WatchThreadState *self,
1381              gint              index,
1382              GNode            *cache_node)
1383 {
1384   HKEY    hpath;
1385   HANDLE  cond;
1386   gchar  *prefix;
1387
1388   g_return_if_fail (index > 0 && index < self->events->len);
1389
1390   cond       = g_ptr_array_index (self->events,      index);
1391   hpath      = g_ptr_array_index (self->handles,     index);
1392   prefix     = g_ptr_array_index (self->prefixes,    index);
1393
1394   trace ("Freeing watch %i [%s]\n", index, prefix);
1395  
1396   /* These can be NULL if the watch was already dead, this can happen when eg.
1397    * a key is deleted but GSettings is still subscribed to it - the watch is
1398    * kept alive so that the unsubscribe function works properly, but does not
1399    * do anything.
1400    */
1401   if (hpath != NULL)
1402     RegCloseKey (hpath);
1403
1404   if (cache_node != NULL)
1405     {
1406       //registry_cache_dump (G_REGISTRY_BACKEND (self->owner)->cache_root, NULL);
1407       registry_cache_unref_tree (cache_node);
1408     }
1409
1410   CloseHandle (cond);
1411   g_free (prefix);
1412
1413   /* As long as we remove from each array at the same time, it doesn't matter that
1414    * their orders get messed up - they all get messed up the same.
1415    */
1416   g_ptr_array_remove_index_fast (self->handles,     index);
1417   g_ptr_array_remove_index_fast (self->events,      index);
1418   g_ptr_array_remove_index_fast (self->prefixes,    index);
1419   g_ptr_array_remove_index_fast (self->cache_nodes, index);
1420 }
1421
1422 static void
1423 watch_thread_handle_message (WatchThreadState *self)
1424 {
1425   switch (self->message.type)
1426     {
1427       case WATCH_THREAD_NONE:
1428         trace ("watch thread: you woke me up for nothin', man!");
1429         break;
1430
1431       case WATCH_THREAD_ADD_WATCH:
1432         {
1433           RegistryWatch *watch = &self->message.watch;
1434           LONG           result;
1435           result = registry_watch_key (watch->hpath, watch->event);
1436           if (result == ERROR_SUCCESS)
1437             {
1438               g_ptr_array_add (self->events,      watch->event);
1439               g_ptr_array_add (self->handles,     watch->hpath);
1440               g_ptr_array_add (self->prefixes,    watch->prefix);
1441               g_ptr_array_add (self->cache_nodes, watch->cache_node);
1442               trace ("watch thread: new watch on %s, %i total\n", watch->prefix,
1443                      self->events->len);
1444             }
1445           else
1446             {
1447               g_message_win32_error (result, "watch thread: could not watch %s", watch->prefix);
1448               CloseHandle (watch->event);
1449               RegCloseKey (watch->hpath);
1450               g_free (watch->prefix);
1451               registry_cache_unref_tree (watch->cache_node);
1452             }
1453           break;
1454         }
1455
1456       case WATCH_THREAD_REMOVE_WATCH:
1457         {
1458           GNode             *cache_node;
1459           RegistryCacheItem *cache_item;
1460           gint               i;
1461
1462           for (i=1; i<self->prefixes->len; i++)
1463             if (strcmp (g_ptr_array_index (self->prefixes, i),
1464                         self->message.watch.prefix) == 0)
1465                 break;
1466  
1467           if (i >= self->prefixes->len)
1468             {
1469               /* Don't make a fuss if the prefix is not being watched because
1470                * maybe the path was deleted so we removed the watch.
1471                */
1472               trace ("unsubscribe: prefix %s is not being watched [%i things are]!\n",
1473                      self->message.watch.prefix, self->prefixes->len);
1474               g_free (self->message.watch.prefix);
1475               break;
1476             }
1477
1478           cache_node = g_ptr_array_index (self->cache_nodes, i);
1479
1480           trace ("watch thread: unsubscribe: freeing node %x, prefix %s, index %i\n",
1481                  (guint)cache_node, self->message.watch.prefix, i);
1482           if (cache_node != NULL)
1483             {
1484               cache_item = cache_node->data;
1485
1486               /* There may be more than one GSettings object subscribed to this
1487                * path, only free the watch when the last one unsubscribes.
1488                */
1489               cache_item->subscription_count --;
1490               if (cache_item->subscription_count > 0)
1491                 break;
1492             }
1493
1494           _free_watch (self, i, cache_node);
1495           g_free (self->message.watch.prefix);
1496
1497           g_atomic_int_inc (&self->watches_remaining);
1498           break;
1499         }
1500
1501       case WATCH_THREAD_STOP:
1502         {
1503           gint i;
1504
1505           /* Free any remaining cache and watch handles */
1506           for (i=1; i<self->events->len; i++)
1507             _free_watch (self, i, g_ptr_array_index (self->cache_nodes, i));
1508
1509           SetEvent (self->message_received_event);
1510           ExitThread (0);
1511         }
1512     }
1513
1514   self->message.type = WATCH_THREAD_NONE;
1515   SetEvent (self->message_received_event);
1516 }
1517
1518
1519 /* Thread which watches for win32 registry events */
1520 static DWORD WINAPI
1521 watch_thread_function (LPVOID parameter)
1522 {
1523   WatchThreadState *self = (WatchThreadState *)parameter;
1524   DWORD result;
1525
1526   self->events = g_ptr_array_new ();
1527   self->handles = g_ptr_array_new ();
1528   self->prefixes = g_ptr_array_new ();
1529   self->cache_nodes = g_ptr_array_new ();
1530   g_ptr_array_add (self->events, self->message_sent_event);
1531   g_ptr_array_add (self->handles, NULL);
1532   g_ptr_array_add (self->prefixes, NULL);
1533   g_ptr_array_add (self->cache_nodes, NULL);
1534
1535   while (1)
1536     {
1537       trace ("watch thread: going to sleep; %i events watched.\n", self->events->len);
1538       result = WaitForMultipleObjects (self->events->len, self->events->pdata, FALSE, INFINITE);
1539
1540       if (result == WAIT_OBJECT_0)
1541         {
1542           /* A message to you. The sender (main thread) will block until we signal the received
1543            * event, so there should be no danger of it sending another before we receive the
1544            * first.
1545            */
1546           watch_thread_handle_message (self);
1547         }
1548       else if (result > WAIT_OBJECT_0 && result <= WAIT_OBJECT_0 + self->events->len)
1549         {
1550           HKEY               hpath;
1551           HANDLE             cond;
1552           gchar             *prefix;
1553           GNode             *cache_node;
1554           RegistryCacheItem *cache_item;
1555           RegistryEvent     *event;
1556
1557           /* One of our notifications has triggered. All we know is which one, and which key
1558            * this is for. We do most of the processing here, because we may as well. If the
1559            * registry changes further while we are processing it doesn't matter - we will then
1560            * receive another change notification from the OS anyway.
1561            */
1562           gint notify_index = result - WAIT_OBJECT_0;
1563           hpath      = g_ptr_array_index (self->handles,     notify_index);
1564           cond       = g_ptr_array_index (self->events,      notify_index);
1565           prefix     = g_ptr_array_index (self->prefixes,    notify_index);
1566           cache_node = g_ptr_array_index (self->cache_nodes, notify_index);
1567
1568           trace ("Watch thread: notify received on prefix %i: %s.\n", notify_index, prefix);
1569
1570           if (cache_node == NULL)
1571             {
1572               /* This path has been deleted */
1573               trace ("Notify received on a path that was deleted :(\n");
1574               continue;
1575             }
1576
1577           /* Firstly we need to reapply for the notification, because (what a
1578            * sensible API) we won't receive any more. MSDN is pretty
1579            * inconsistent on this matter:
1580            *   http://msdn.microsoft.com/en-us/library/ms724892%28VS.85%29.aspx
1581            *   http://support.microsoft.com/kb/236570
1582            * But my tests (on Windows XP SP3) show that we need to reapply
1583            * each time.
1584            */
1585           result = registry_watch_key (hpath, cond);
1586
1587           if (result != ERROR_SUCCESS)
1588             {
1589               /* Watch failed, most likely because the key has just been
1590                * deleted. Free the watch and unref the cache nodes.
1591                */
1592              if (result != ERROR_KEY_DELETED)
1593                g_message_win32_error (result, "watch thread: failed to watch %s", prefix);
1594              _free_watch (self, notify_index, cache_node);
1595              g_atomic_int_inc (&self->watches_remaining);
1596              continue;
1597             }
1598
1599           /* The notification may have been blocked because we just changed
1600            * some data ourselves.
1601            */
1602           cache_item = cache_node->data;
1603           if (cache_item->block_count)
1604             {
1605               cache_item->block_count --;
1606               trace ("Watch thread: notify blocked at %s\n", prefix);
1607               continue;
1608             }
1609   
1610           /* Now we update our stored cache from registry data, and find which keys have
1611            * actually changed. If more changes happen while we are processing, we will get
1612            * another event because we have reapplied for change notifications already.
1613            *
1614            * Working here rather than in the main thread is preferable because the UI is less
1615            * likely to block (only when changing notification subscriptions).
1616            */
1617           event = g_slice_new (RegistryEvent);
1618
1619           event->self = G_REGISTRY_BACKEND (self->owner);
1620           g_object_ref (self->owner);
1621
1622           event->items = g_ptr_array_new ();
1623
1624           EnterCriticalSection (G_REGISTRY_BACKEND (self->owner)->cache_lock);
1625           registry_cache_update (G_REGISTRY_BACKEND (self->owner), hpath,
1626                                  prefix, NULL, cache_node, 0, event->items);
1627           LeaveCriticalSection (G_REGISTRY_BACKEND (self->owner)->cache_lock);
1628
1629           if (event->items->len > 0)
1630             {
1631               event->prefix = g_strdup (prefix);
1632               g_idle_add ((GSourceFunc) watch_handler, event);
1633             }
1634           else
1635             {
1636               g_ptr_array_free (event->items, TRUE);
1637               g_slice_free (RegistryEvent, event);
1638             }
1639         }
1640       else
1641         {
1642           /* God knows what has happened */
1643           g_message_win32_error (GetLastError(), "watch thread: WaitForMultipleObjects error");
1644         }
1645     }
1646
1647   return -1;
1648 }
1649
1650 static gboolean
1651 watch_start (GRegistryBackend *self)
1652 {
1653   WatchThreadState *watch;
1654
1655   g_return_val_if_fail (self->watch == NULL, FALSE);
1656
1657   watch = g_slice_new (WatchThreadState);
1658   watch->owner = G_SETTINGS_BACKEND (self);
1659
1660   watch->watches_remaining = MAX_WATCHES;
1661
1662   watch->message_lock = g_slice_new (CRITICAL_SECTION);
1663   InitializeCriticalSection (watch->message_lock);
1664   watch->message_sent_event = CreateEvent (NULL, FALSE, FALSE, NULL);
1665   watch->message_received_event = CreateEvent (NULL, FALSE, FALSE, NULL);
1666   if (watch->message_sent_event == NULL || watch->message_received_event == NULL)
1667     {
1668       g_message_win32_error (0, "gregistrybackend: Failed to create sync objects.");
1669       goto fail_1;
1670     }
1671
1672   /* Use a small stack to make the thread more lightweight. */
1673   watch->thread = CreateThread (NULL, 1024, watch_thread_function, watch, 0, NULL);
1674   if (watch->thread == NULL)
1675     {
1676       g_message_win32_error (0, "gregistrybackend: Failed to create notify watch thread.");
1677       goto fail_2;
1678     }
1679
1680   self->watch = watch;
1681
1682   return TRUE;
1683
1684 fail_2:
1685   DeleteCriticalSection (watch->message_lock);
1686   g_slice_free (CRITICAL_SECTION, watch->message_lock);
1687   CloseHandle (watch->message_sent_event);
1688   CloseHandle (watch->message_received_event);
1689 fail_1:
1690   g_slice_free (WatchThreadState, watch);
1691   return FALSE;
1692 }
1693
1694 /* This function assumes you hold the message lock! */
1695 static void
1696 watch_stop_unlocked (GRegistryBackend *self)
1697 {
1698   WatchThreadState *watch = self->watch;
1699   DWORD result;
1700   g_return_if_fail (watch != NULL);
1701
1702   watch->message.type = WATCH_THREAD_STOP;
1703   SetEvent (watch->message_sent_event);
1704
1705   /* This is signalled as soon as the message is received. We must not return
1706    * while the watch thread is still firing off callbacks. Freeing all of the
1707    * memory is done in the watch thread after this is signalled.
1708    */
1709   result = WaitForSingleObject (watch->message_received_event, INFINITE);
1710   if (result != WAIT_OBJECT_0)
1711     {
1712       g_warning ("gregistrybackend: unable to stop watch thread.");
1713       return;
1714     }
1715
1716   LeaveCriticalSection (watch->message_lock);
1717   DeleteCriticalSection (watch->message_lock);
1718   g_slice_free (CRITICAL_SECTION, watch->message_lock);
1719   CloseHandle (watch->message_sent_event);
1720   CloseHandle (watch->message_received_event);
1721   CloseHandle (watch->thread);
1722   g_slice_free (WatchThreadState, watch);
1723
1724   trace ("\nwatch thread: %x: all data freed.\n", self);
1725   self->watch = NULL;
1726 };
1727
1728 static gboolean
1729 watch_add_notify (GRegistryBackend *self,
1730                   HANDLE            event,
1731                   HKEY              hpath,
1732                   gchar            *gsettings_prefix)
1733 {
1734   WatchThreadState  *watch = self->watch;
1735   GNode             *cache_node;
1736   RegistryCacheItem *cache_item;
1737 #ifdef TRACE
1738   DWORD              result;
1739 #endif
1740
1741   g_return_val_if_fail (watch != NULL, FALSE);
1742   trace ("watch_add_notify: prefix %s.\n", gsettings_prefix);
1743
1744   /* Duplicate tree into the cache in the main thread, before we add the notify: if we do it in the
1745    * thread we can miss changes while we are caching.
1746    */
1747   EnterCriticalSection (self->cache_lock);
1748   cache_node = registry_cache_get_node_for_key (self->cache_root, gsettings_prefix, TRUE);
1749
1750   if (cache_node == NULL || cache_node->data == NULL)
1751     {
1752       LeaveCriticalSection (self->cache_lock);
1753       g_warn_if_reached ();
1754       return FALSE;
1755     }
1756   
1757   cache_item = cache_node->data;
1758
1759   cache_item->subscription_count ++;
1760   if (cache_item->subscription_count > 1)
1761     {
1762       trace ("watch_add_notify: prefix %s already watched, %i subscribers.\n",
1763              gsettings_prefix, cache_item->subscription_count);
1764       LeaveCriticalSection (self->cache_lock);
1765       return FALSE;
1766     }
1767
1768   registry_cache_ref_tree (cache_node);
1769   registry_cache_update (self, hpath, gsettings_prefix, NULL, cache_node, 0, NULL);
1770   //registry_cache_dump (self->cache_root, NULL);
1771   LeaveCriticalSection (self->cache_lock);
1772
1773   EnterCriticalSection (watch->message_lock);
1774   watch->message.type = WATCH_THREAD_ADD_WATCH;
1775   watch->message.watch.event      = event;
1776   watch->message.watch.hpath      = hpath;
1777   watch->message.watch.prefix     = gsettings_prefix;
1778   watch->message.watch.cache_node = cache_node;
1779
1780   SetEvent (watch->message_sent_event);
1781
1782   /* Wait for the received event in return, to avoid sending another message before the first
1783    * one was received. If it takes > 200ms there is a possible race but the worst outcome is
1784    * a notification is ignored.
1785    */
1786 #ifdef TRACE
1787   result =
1788 #endif
1789     WaitForSingleObject (watch->message_received_event, 200);
1790 #ifdef TRACE
1791   if (result != WAIT_OBJECT_0)
1792     trace ("watch thread is slow to respond - notification may not be added.");
1793 #endif
1794
1795   LeaveCriticalSection (watch->message_lock);
1796
1797   return TRUE;
1798 };
1799
1800
1801 static void
1802 watch_remove_notify (GRegistryBackend *self,
1803                      const gchar      *key_name)
1804 {
1805   WatchThreadState *watch = self->watch;
1806   LONG     result;
1807
1808   if (self->watch == NULL)
1809     /* Here we assume that the unsubscribe message is for somewhere that was
1810      * deleted, and so it has already been removed and the watch thread has
1811      * stopped.
1812      */
1813     return;
1814
1815   EnterCriticalSection (watch->message_lock);
1816   watch->message.type = WATCH_THREAD_REMOVE_WATCH;
1817   watch->message.watch.prefix = g_strdup (key_name);
1818
1819   SetEvent (watch->message_sent_event);
1820
1821   /* Wait for the received event in return, to avoid sending another message before the first
1822    * one was received.
1823    */
1824   result = WaitForSingleObject (watch->message_received_event, INFINITE);
1825
1826   if (result != ERROR_SUCCESS)
1827     g_warning ("unsubscribe from %s: message not acknowledged\n", key_name);
1828
1829   if (g_atomic_int_get (&watch->watches_remaining) >= MAX_WATCHES)
1830     /* Stop it before any new ones can get added and confuse things */
1831     watch_stop_unlocked (self); 
1832   else
1833     LeaveCriticalSection (watch->message_lock);
1834 }
1835
1836 /* dconf semantics are: if the key ends in /, watch the keys underneath it - if not, watch that
1837  * key. Our job is easier because keys and values are separate.
1838  */
1839 static void
1840 g_registry_backend_subscribe (GSettingsBackend *backend,
1841                               const char       *key_name)
1842 {
1843   GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
1844   gchar *path_name, *value_name = NULL;
1845   HKEY hpath;
1846   HANDLE event;
1847   LONG result;
1848
1849   if (self->watch == NULL)
1850     if (!watch_start (self))
1851       return;
1852
1853   if (g_atomic_int_dec_and_test (&self->watch->watches_remaining))
1854     {
1855       g_atomic_int_inc (&self->watch->watches_remaining);
1856       g_warning ("subscribe() failed: only %i different paths may be watched.\n", MAX_WATCHES);
1857       return;
1858     }
1859
1860   path_name = parse_key (key_name, self->base_path, &value_name);
1861
1862   /* Must check for this, otherwise strange crashes occur because the cache
1863    * node that is being watched gets freed. All path names to subscribe must
1864    * end in a slash!
1865    */
1866   if (value_name != NULL && *value_name != 0)
1867     g_warning ("subscribe() failed: path must end in a /, got %s\n", key_name);
1868
1869   trace ("Subscribing to %s [registry %s / %s] - watch %x\n", key_name, path_name, value_name, self->watch);
1870
1871
1872   /* Give the caller the benefit of the doubt if the key doesn't exist and create it. The caller
1873    * is almost certainly a new g_settings with this path as base path. */
1874   result = RegCreateKeyExA (HKEY_CURRENT_USER, path_name, 0, NULL, 0, KEY_READ, NULL, &hpath,
1875                             NULL);
1876   g_free (path_name);
1877
1878   if (result != ERROR_SUCCESS)
1879     {
1880       g_message_win32_error (result, "gregistrybackend: Unable to subscribe to key %s.", key_name);
1881       g_atomic_int_inc (&self->watch->watches_remaining);
1882       return;
1883     }
1884
1885   event = CreateEvent (NULL, FALSE, FALSE, NULL);
1886   if (event == NULL)
1887     {
1888       g_message_win32_error (result, "gregistrybackend: CreateEvent failed.\n");
1889       g_atomic_int_inc (&self->watch->watches_remaining);
1890       RegCloseKey (hpath);
1891       return;
1892     }
1893
1894   /* The actual watch is added by the thread, which has to re-subscribe each time it
1895    * receives a change. */
1896   if (!watch_add_notify (self, event, hpath, g_strdup (key_name)))
1897     g_atomic_int_inc (&self->watch->watches_remaining);
1898 }
1899
1900 static void
1901 g_registry_backend_unsubscribe (GSettingsBackend *backend,
1902                                 const char       *key_name)
1903 {
1904   trace ("unsubscribe: %s.\n", key_name);
1905
1906   watch_remove_notify (G_REGISTRY_BACKEND (backend), key_name);
1907 }
1908
1909
1910 /********************************************************************************
1911  * Object management junk
1912  ********************************************************************************/
1913
1914 static void
1915 g_registry_backend_finalize (GObject *object)
1916 {
1917   GRegistryBackend  *self = G_REGISTRY_BACKEND (object);
1918   RegistryCacheItem *item;
1919
1920   item = self->cache_root->data;
1921   g_warn_if_fail (item->ref_count == 1);
1922
1923   _free_cache_item (item);
1924   g_node_destroy (self->cache_root);
1925
1926   if (self->watch != NULL)
1927     {
1928       EnterCriticalSection (self->watch->message_lock);
1929       watch_stop_unlocked (self);
1930     }
1931
1932   DeleteCriticalSection (self->cache_lock);
1933   g_slice_free (CRITICAL_SECTION, self->cache_lock);
1934
1935   g_free (self->base_path);
1936 }
1937
1938 static void
1939 g_registry_backend_class_init (GRegistryBackendClass *class)
1940 {
1941   GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class);
1942   GObjectClass *object_class = G_OBJECT_CLASS (class);
1943
1944   object_class->finalize = g_registry_backend_finalize;
1945
1946   backend_class->read = g_registry_backend_read;
1947   backend_class->write = g_registry_backend_write;
1948   backend_class->write_tree = g_registry_backend_write_tree;
1949   backend_class->reset = g_registry_backend_reset;
1950   backend_class->get_writable = g_registry_backend_get_writable;
1951   backend_class->get_permission = g_registry_backend_get_permission;
1952   backend_class->subscribe = g_registry_backend_subscribe;
1953   backend_class->unsubscribe = g_registry_backend_unsubscribe;
1954 }
1955
1956 static void
1957 g_registry_backend_init (GRegistryBackend *self)
1958 {
1959   RegistryCacheItem *item;
1960   self->base_path = g_strdup_printf ("Software\\GSettings");
1961
1962   item = g_slice_new (RegistryCacheItem);
1963   item->value.type = REG_NONE;
1964   item->value.ptr = NULL;
1965   item->name = g_strdup ("<root>");
1966   item->ref_count = 1;
1967   self->cache_root = g_node_new (item);
1968
1969   self->cache_lock = g_slice_new (CRITICAL_SECTION);
1970   InitializeCriticalSection (self->cache_lock);
1971
1972   self->watch = NULL;
1973 }