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