/*
 * Copyright © 2009-10 Sam Thursfield
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Sam Thursfield <ssssam@gmail.com>
 */

/* GRegistryBackend implementation notes:
 *
 *   - All settings are stored under the path:
 *       HKEY_CURRENT_USER\Software\GSettings\
 *     This means all settings are per-user. Permissions and system-wide
 *     defaults are not implemented and will probably always be out of scope of
 *     the Windows port of GLib.
 *
 *   - The registry type system is limited. Most GVariant types are stored as
 *     literals via g_variant_print/parse(). Strings are stored without the
 *     quotes that GVariant requires. Integer types are stored as native
 *     REG_DWORD or REG_QWORD. The REG_MULTI_SZ (string array) type could be
 *     used to avoid flattening container types.
 *
 *   - Notifications are handled; the change event is watched for in a separate
 *     thread (Windows does not provide a callback API) which sends them with
 *     g_idle_add to the GLib main loop. The threading is done using Windows
 *     API functions, so there is no dependence on GThread.
 *
 *   - Windows doesn't tell us which value has changed. This means we have to
 *     maintain a cache of every stored value so we can play spot the
 *     difference. This should not be a performance issue because if you are
 *     storing thousands of values in GSettings, you are probably using it
 *     wrong.
 *
 *   - The cache stores the value as a registry type. Because many variants are
 *     stored as string representations, values which have changed equality but
 *     not equivalence may trigger spurious change notifications. GSettings
 *     users must already deal with this possibility and converting all data to
 *     GVariant values would be more effort.
 *
 *   - Because we have to cache every registry value locally, reads are done
 *     from the cache rather than directly from the registry. Writes update
 *     both. This means that the backend will not work if the watch thread is
 *     not running. A GSettings object always subscribes to changes so we can
 *     be sure that the watch thread will be running, but if for some reason
 *     the backend is being used directly you should bear that in mind.
 *
 *   - The registry is totally user-editable, so we are very forgiving about
 *     errors in the data we get.
 *
 *   - The registry uses backslashes as path separators. GSettings keys only
 *     allow [A-Za-z\-] so no escaping is needed. No attempt is made to solve
 *     clashes between keys differing only in case.
 *
 *   - RegCreateKeyW is used - We should always make the UTF-8 -> UTF-16
 *     conversion ourselves to avoid problems when the system language changes.
 *
 *   - The Windows registry has the following limitations: a key may not exceed
 *     255 characters, an entry's value may not exceed 16,383 characters, and
 *     all the values of a key may not exceed 65,535 characters.
 *
 *   - Terminology:
 *     * in GSettings, a 'key' is eg. /desktop/gnome/background/primary-color
 *     * in the registry, the 'key' is path, which contains some 'values'.
 *     * in this file, any GSettings key is a 'key', while a registry key is
 *       termed a 'path', which contains 'values'.
 *
 *   - My set of tests for this backend are currently at:
 *       http://gitorious.org/gsettings-gtk/gsettings-test.git
 *
 *   - There is an undocumented function in ntdll.dll which might be more
 *     than RegNotifyChangeKeyValue(), NtNotifyChangeKey:
 *       http://source.winehq.org/source/dlls/ntdll/reg.c#L618
 *       http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Key/NtNotifyChangeKey.html
 *
 *   - If updating the cache ever becomes a performance issue it may make sense
 *     to use a red-black tree, but I don't currently think it's worth the time
 */

#include "config.h"

#include "gregistrysettingsbackend.h"
#include "gsettingsbackend.h"
#include "giomodule.h"

#include <windows.h>

//#define TRACE

/* GSettings' limit */
#define MAX_KEY_NAME_LENGTH   128

/* Testing (on Windows XP SP3) shows that WaitForMultipleObjects fails with
 * "The parameter is incorrect" after 64 watches. We need one for the
 * message_sent cond, which is allowed for in the way the watches_remaining
 * variable is used.
 */
#define MAX_WATCHES   64

/* A watch on one registry path and its subkeys */
typedef struct
{
  HANDLE event;
  HKEY hpath;
  char *prefix;
  GNode *cache_node;
} RegistryWatch;

/* Simple message passing for the watch thread. Not enough traffic to
 * justify a queue.
 */
typedef enum
{
  WATCH_THREAD_NONE,
  WATCH_THREAD_ADD_WATCH,
  WATCH_THREAD_REMOVE_WATCH,
  WATCH_THREAD_STOP
} WatchThreadMessageType;

typedef struct
{
  WatchThreadMessageType type;
  RegistryWatch watch;
} WatchThreadMessage;

typedef struct
{
  GSettingsBackend *owner;
  HANDLE *thread;

  /* Details of the things we are watching. */
  int watches_remaining;
  GPtrArray *events, *handles, *prefixes, *cache_nodes;

  /* Communication with the main thread. Only one message is stored at a time,
   * to make sure that messages are acknowledged before being overwritten we
   * create two events - one is signalled when a new message is set, the
   * other is signalled by the thread when it has processed the message.
   */
  WatchThreadMessage message;
  CRITICAL_SECTION *message_lock;
  HANDLE message_sent_event, message_received_event;
} WatchThreadState;

#define G_TYPE_REGISTRY_BACKEND      (g_registry_backend_get_type ())
#define G_REGISTRY_BACKEND(inst)     (G_TYPE_CHECK_INSTANCE_CAST ((inst),         \
                                      G_TYPE_REGISTRY_BACKEND, GRegistryBackend))
#define G_IS_REGISTRY_BACKEND(inst)  (G_TYPE_CHECK_INSTANCE_TYPE ((inst),         \
                                      G_TYPE_REGISTRY_BACKEND))

typedef GSettingsBackendClass GRegistryBackendClass;

typedef struct {
  GSettingsBackend parent_instance;

  gchar *base_path;
  gunichar2 *base_pathw;

  /* A stored copy of the whole tree being watched. When we receive a change notification
   * we have to check against this to see what has changed ... every time ...*/
  CRITICAL_SECTION *cache_lock;
  GNode *cache_root;

  WatchThreadState *watch;
} GRegistryBackend;

G_DEFINE_TYPE_WITH_CODE (GRegistryBackend,
                         g_registry_backend,
                         G_TYPE_SETTINGS_BACKEND,
                         g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
                                                         g_define_type_id, "registry", 90))

/**********************************************************************************
 * Utility functions
 **********************************************************************************/

#include <stdio.h>
static void
trace (const char *format,
       ...)
{
#ifdef TRACE
  va_list va; va_start (va, format);
  vprintf (format, va);
  fflush (stdout);
  va_end (va);
#endif
}

/* g_message including a windows error message. It is not useful to have an
 * equivalent function for g_warning because none of the registry errors can
 * result from programmer error (Microsoft programmers don't count), instead
 * they will mostly occur from people messing with the registry by hand. */
static void G_GNUC_PRINTF (2, 3)
g_message_win32_error (DWORD        result_code,
                       const gchar *format,
                      ...)
{
  va_list va;
  gchar *message;
  gchar *win32_error;
  gchar *win32_message;

  g_return_if_fail (result_code != 0);

  va_start (va, format);
  message = g_strdup_vprintf (format, va);
  win32_error = g_win32_error_message (result_code);
  win32_message = g_strdup_printf ("%s: %s", message, win32_error);
  g_free (message);
  g_free (win32_error);

  if (result_code == ERROR_KEY_DELETED)
    trace ("(%s)", win32_message);
  else
    g_message ("%s", win32_message);

  g_free (win32_message);
}

/* Make gsettings key into a registry path & value pair. 
 * 
 * Note that the return value *only* needs freeing - registry_value_name
 * is a pointer to further inside the same block of memory.
 */
static gchar *
parse_key (const gchar  *key_name,
           const gchar  *registry_prefix,
           gchar       **value_name)
{
  gchar *path_name, *c;

  /* All key paths are treated as absolute; gsettings doesn't seem to enforce a
   * preceding /.
   */
  if (key_name[0] == '/')
    key_name++;

  if (registry_prefix == NULL)
    path_name = g_strdup (key_name);
  else
    path_name = g_strjoin ("/", registry_prefix, key_name, NULL);

  /* Prefix is expected to be in registry format (\ separators) so don't escape that. */
  for (c = path_name + (registry_prefix ? strlen (registry_prefix) : 0); *c != 0; c++)
    {
      if (*c == '/')
        {
          *c = '\\';
          *value_name = c;
        }
    }

  **value_name = 0;
  (*value_name)++;

  return path_name;
}

static DWORD
g_variant_get_as_dword (GVariant *variant)
{
  switch (g_variant_get_type_string (variant)[0])
    {
    case 'b':
      return g_variant_get_boolean (variant);
    case 'y':
      return g_variant_get_byte (variant);
    case 'n':
      return g_variant_get_int16 (variant);
    case 'q':
      return g_variant_get_uint16 (variant);
    case 'i':
      return g_variant_get_int32 (variant);
    case 'u':
      return g_variant_get_uint32 (variant);
    default:
      g_warn_if_reached ();
    }
  return 0;
}

static DWORDLONG
g_variant_get_as_qword (GVariant *variant)
{
  switch (g_variant_get_type_string (variant)[0])
    {
    case 'x':
      return g_variant_get_int64 (variant);
    case 't':
      return g_variant_get_uint64 (variant);
    default:
      g_warn_if_reached ();
    }
  return 0;
}

static void
handle_read_error (LONG         result,
                   const gchar *path_name,
                   const gchar *value_name)
{
  /* file not found means key value not set, this isn't an error for us. */
  if (result != ERROR_FILE_NOT_FOUND)
    g_message_win32_error (result, "Unable to query value %s/%s",
                           path_name, value_name);
}

/***************************************************************************
 * Cache of registry values
 ***************************************************************************/

/* Generic container for registry values */
typedef struct {
  DWORD type;

  union {
    gint  dword;  /* FIXME: could inline QWORD on 64-bit systems too */
    void *ptr;
  };
} RegistryValue;

static char *
registry_value_dump (RegistryValue value)
{
  if (value.type == REG_DWORD)
    return g_strdup_printf ("%d", value.dword);
  else if (value.type == REG_QWORD)
    return g_strdup_printf ("%"G_GINT64_FORMAT, value.ptr == NULL ? 0: *(DWORDLONG *)value.ptr);
  else if (value.type == REG_SZ)
    return g_strdup_printf ("%s", (char *)value.ptr);
  else if (value.type == REG_NONE)
    return g_strdup_printf ("<empty>");
  else
    return g_strdup_printf ("<invalid>");
}

static void
registry_value_free (RegistryValue value)
{
  if (value.type == REG_SZ || value.type == REG_QWORD)
    g_free (value.ptr);

  value.type = REG_NONE;
  value.ptr = NULL;
}

/* The registry cache is stored as a tree, for easy traversal. Right now we
 * don't sort it in a clever way. Each node corresponds to a path element
 * ('key' in registry terms) or a value.
 *
 * Each subscription uses the same cache. Because GSettings can subscribe to
 * the tree at any node any number of times, we need to reference count the
 * nodes.
 */
typedef struct
{
  /* Component of path that this node represents */
  gchar *name;

  /* If a watch is subscribed at this point (subscription_count > 0) we can
   * block its next notification. This is useful because if two watches cover
   * the same path, both will trigger when it changes. It also allows changes
   * done by the application to be ignored by the watch thread.
   */
  gint32 block_count : 8;

  /* Number of times g_settings_subscribe has been called for this location
   * (I guess you can't subscribe more than 16383 times) */
  gint32 subscription_count : 14;
  
  gint32 ref_count : 9;

  gint32 readable : 1;
  RegistryValue value;
} RegistryCacheItem;

static GNode *
registry_cache_add_item (GNode         *parent,
                         gchar         *name,
                         RegistryValue  value,
                         gint           ref_count)
{
  RegistryCacheItem *item;
  GNode *cache_node;

  g_return_val_if_fail (name != NULL, NULL);
  g_return_val_if_fail (parent != NULL, NULL);

  item = g_slice_new (RegistryCacheItem);

  /* Ref count should be the number of watch points above this node */
  item->ref_count = ref_count;

  item->name = g_strdup (name);
  item->value = value;
  item->subscription_count = 0;
  item->block_count = 0;
  item->readable = FALSE;

  trace ("\tregistry cache: adding %s to %s\n",
         name, ((RegistryCacheItem *)parent->data)->name);

  cache_node = g_node_new (item);
  g_node_append (parent, cache_node);

  return cache_node;
}

/* The reference counting of cache tree nodes works like this: when a node is
 * subscribed to (GSettings wants us to watch that path and everything below
 * it) the reference count of that node and everything below is increased, as
 * well as each parent up to the root.
 */

static void
_ref_down (GNode *node)
{
  RegistryCacheItem *item = node->data;

  g_node_children_foreach (node, G_TRAVERSE_ALL,
                           (GNodeForeachFunc)_ref_down, NULL);
  item->ref_count++;
}

static void
registry_cache_ref_tree (GNode *tree)
{
  RegistryCacheItem *item = tree->data;
  GNode *node = tree->parent;

  g_return_if_fail (tree != NULL);

  item->ref_count++;

  g_node_children_foreach (tree, G_TRAVERSE_ALL,
                           (GNodeForeachFunc)_ref_down, NULL);

  for (node = tree->parent; node; node = node->parent)
    {
      item = node->data;
      item->ref_count++;
    }
}

static void
registry_cache_item_free (RegistryCacheItem *item)
{
  trace ("\t -- Free node %s\n", item->name);

  g_free (item->name);
  registry_value_free (item->value);
  g_slice_free (RegistryCacheItem, item);
}

/* Unreferencing has to be done bottom-up */
static void
_unref_node (GNode *node)
{
  RegistryCacheItem *item = node->data;

  item->ref_count--;

  g_warn_if_fail (item->ref_count >= 0);

  if (item->ref_count == 0)
    {
      registry_cache_item_free (item);
      g_node_destroy (node);
    }
}

static void
_unref_down (GNode *node)
{
  g_node_children_foreach (node, G_TRAVERSE_ALL,
                           (GNodeForeachFunc)_unref_down, NULL);
  _unref_node (node);
}

static void
registry_cache_unref_tree (GNode *tree)
{
  GNode *parent = tree->parent, *next_parent;

  _unref_down (tree);

  while (parent)
    {
      next_parent = parent->parent;
      _unref_node (parent);
      parent = next_parent;
    }
}

#if 0
static void
registry_cache_dump (GNode    *cache_node,
                     gpointer  data)
{
  RegistryCacheItem *item = cache_node->data;

  int depth     = GPOINTER_TO_INT(data),
      new_depth = depth+1,
      i;

  g_return_if_fail (cache_node != NULL);

  for (i=0; i<depth; i++)
    g_print ("  ");
  if (item == NULL)
    g_print ("*root*\n");
  else
    g_print ("'%s'  [%i] @ %x = %s\n", item->name, item->ref_count, (guint)cache_node,
             registry_value_dump (item->value));
  g_node_children_foreach (cache_node, G_TRAVERSE_ALL, registry_cache_dump,
                           GINT_TO_POINTER (new_depth));
}
#endif

typedef struct
{
  gchar *name;
  GNode *result;
} RegistryCacheSearch;

static gboolean
registry_cache_find_compare (GNode    *node,
                             gpointer  data)
{
  RegistryCacheSearch *search = data;
  RegistryCacheItem *item = node->data;

  if (item == NULL)  /* root node */
    return FALSE;

  g_return_val_if_fail (search->name != NULL, FALSE);
  g_return_val_if_fail (item->name != NULL, FALSE);

  if (strcmp (search->name, item->name) == 0)
    {
      search->result = node;
      return TRUE;
    }

  return FALSE;
}

static GNode *
registry_cache_find_immediate_child (GNode *node,
                                     gchar *name)
{
  RegistryCacheSearch search;

  search.result = NULL;
  search.name = name;

  g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, 2,
                   registry_cache_find_compare, &search);

  return search.result;
}

static GNode *
registry_cache_get_node_for_key_recursive (GNode    *node,
                                           gchar    *key_name,
                                           gboolean  create_if_not_found,
                                           gint      n_parent_watches)
{
  RegistryCacheItem *item;
  gchar *component = key_name;
  gchar *c = strchr (component, '/');
  GNode *child;

  if (c != NULL)
    *c = 0;

  /* We count up how many watch points we travel through finding this node,
   * because a new node should have as many references as there are watches at
   * points above it in the tree.
   */
  item = node->data;
  if (item->subscription_count > 0)
    n_parent_watches++;

  child = registry_cache_find_immediate_child (node, component);
  if (child == NULL && create_if_not_found)
    {
      RegistryValue null_value = { REG_NONE, {0} };

      child = registry_cache_add_item (node, component,
                                       null_value, n_parent_watches);

      trace ("\tget node for key recursive: new %x = %s.\n", node, component);
    }

  /* We are done if there are no more path components. Allow for a trailing /. */
  if (child == NULL || c == NULL || *(c + 1) == 0)
    return child;

  trace ("get node for key recursive: next: %s.\n", c + 1);

  return registry_cache_get_node_for_key_recursive (child, c + 1,
                                                    create_if_not_found,
                                                    n_parent_watches);
}

/* Look up a GSettings key in the cache. */
static GNode *
registry_cache_get_node_for_key (GNode       *root,
                                 const gchar *key_name,
                                 gboolean     create_if_not_found)
{
  GNode *child = NULL;
  GNode *result = NULL;
  gchar *component, *c;

  g_return_val_if_fail (key_name != NULL, NULL);

  if (key_name[0] == '/')
    key_name++;

  /* Ignore preceding / */
  component = g_strdup (key_name);
  c = strchr (component, '/');

  if (c == NULL)
    {
      g_free (component);
      return root;
    }

  if (c != NULL)
    *c = 0;

  child = registry_cache_find_immediate_child (root, component);
  if (child == NULL && create_if_not_found)
    {
      RegistryValue null_value = { REG_NONE, {0} };

      /* Reference count is set to 0, tree should be referenced by the caller */
      child = registry_cache_add_item (root, component,
                                       null_value, 0);

      trace ("get_node_for_key: New node for component '%s'\n", component);
    }

  if (*(c + 1) == 0)
    result = child;
  else if (child != NULL)
    result = registry_cache_get_node_for_key_recursive (child, c + 1,
                                                        create_if_not_found, 0);

  g_free (component);

  return result;
}

/* Check the cache node against the registry key it represents. Return TRUE if
 * they differ, and update the cache with the new value.
 */
static gboolean
registry_cache_update_node (GNode        *cache_node,
                            RegistryValue registry_value)
{
  RegistryCacheItem *cache_item;

  g_return_val_if_fail (cache_node != NULL, FALSE);
  g_return_val_if_fail (cache_node->data != NULL, FALSE);

  cache_item = cache_node->data;

  if (registry_value.type != cache_item->value.type)
    {
      /* The type has changed. Update cache item and register it as changed.
       * Either the schema has changed and this is entirely legitimate, or
       * whenever the app reads the key it will get the default value due to
       * the type mismatch.
       */
      cache_item->value = registry_value;
      return TRUE;
    }
 
  switch (registry_value.type)
    {
    case REG_DWORD:
      {
        if (cache_item->value.dword == registry_value.dword)
          return FALSE;
        else
          {
            cache_item->value.dword = registry_value.dword;
            return TRUE;
          }
      }
    case REG_QWORD:
      {
        g_return_val_if_fail (registry_value.ptr != NULL &&
                              cache_item->value.ptr != NULL, FALSE);

        if (memcmp (registry_value.ptr, cache_item->value.ptr, 8)==0)
          {
            g_free (registry_value.ptr);
            return FALSE;
          }
        else
          {
            g_free (cache_item->value.ptr);
            cache_item->value.ptr = registry_value.ptr;
            return TRUE;
          }
      }
    case REG_SZ:
      {
        /* Value should not exist if it is NULL, an empty string is "" */
        g_return_val_if_fail (cache_item->value.ptr != NULL, FALSE);
        g_return_val_if_fail (registry_value.ptr != NULL, FALSE);

        if (strcmp (registry_value.ptr, cache_item->value.ptr) == 0)
          {
            g_free (registry_value.ptr);
            return FALSE;
          }
        else
          {
            g_free (cache_item->value.ptr);
            cache_item->value.ptr = registry_value.ptr;
            return TRUE;
          }
      }
    default:
      g_warning ("gregistrybackend: registry_cache_update_node: Unhandled value type");
      return FALSE;
    }
}

/* Blocking notifications is a useful optimisation. When a change is made
 * through GSettings we update the cache manually, but a notification is
 * triggered as well. This function is also used for nested notifications,
 * eg. if /test and /test/foo are watched, and /test/foo/value is changed then
 * we will get notified both for /test/foo and /test and it is helpful to block
 * the second.
 */
static void
registry_cache_block_notification (GNode *node)
{
  RegistryCacheItem *item = node->data;

  g_return_if_fail (node != NULL);

  if (item->subscription_count > 0)
    item->block_count++;

  if (node->parent != NULL)
    registry_cache_block_notification (node->parent);
}

static void registry_cache_destroy_tree (GNode            *node,
                                         WatchThreadState *self);

/***************************************************************************
 * Reading and writing
 ***************************************************************************/

static gboolean
registry_read (HKEY           hpath,
               const gchar   *path_name,
               const gchar   *value_name,
               RegistryValue *p_value)
{
  LONG result;
  DWORD value_data_size;
  gpointer *buffer;
  gunichar2 *value_namew;

  g_return_val_if_fail (p_value != NULL, FALSE);

  p_value->type = REG_NONE;
  p_value->ptr = NULL;

  value_namew = g_utf8_to_utf16 (value_name, -1, NULL, NULL, NULL);

  result = RegQueryValueExW (hpath, value_namew, 0, &p_value->type, NULL, &value_data_size);
  if (result != ERROR_SUCCESS)
    {
      handle_read_error (result, path_name, value_name);
      g_free (value_namew);
      return FALSE;
    }

  if (p_value->type == REG_SZ && value_data_size == 0)
    {
      p_value->ptr = g_strdup ("");
      g_free (value_namew);
      return TRUE;
    }

  if (p_value->type == REG_DWORD)
    /* REG_DWORD is inlined */
    buffer = (void *)&p_value->dword;
  else
    buffer = p_value->ptr = g_malloc (value_data_size);

  result = RegQueryValueExW (hpath, value_namew, 0, NULL, (LPBYTE)buffer, &value_data_size);
  g_free (value_namew);

  if (result != ERROR_SUCCESS)
    {
      handle_read_error (result, path_name, value_name);

      if (p_value->type != REG_DWORD)
        g_free (buffer);

      return FALSE;
    }

  if (p_value->type == REG_SZ)
    {
      gchar *valueu8 = g_utf16_to_utf8 (p_value->ptr, -1, NULL, NULL, NULL);
      g_free (p_value->ptr);
      p_value->ptr = valueu8;
    }

  return TRUE;
}

static GVariant *
g_registry_backend_read (GSettingsBackend   *backend,
                         const gchar        *key_name,
                         const GVariantType *expected_type,
                         gboolean            default_value)
{
  GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
  GNode *cache_node;
  RegistryValue registry_value;
  GVariant *gsettings_value = NULL;
  gchar *gsettings_type;

  g_return_val_if_fail (expected_type != NULL, NULL);

  if (default_value)
    return NULL;

  /* Simply read from the cache, which is updated from the registry by the
   * watch thread as soon as changes can propagate. Any changes not yet in the
   * cache will have the 'changed' signal emitted after this function returns.
   */
  EnterCriticalSection (self->cache_lock);
  cache_node = registry_cache_get_node_for_key (self->cache_root, key_name, FALSE);
  LeaveCriticalSection (self->cache_lock);

  trace ("Reading key %s, cache node %x\n", key_name, cache_node);

  /* Maybe it's not set, we can return to default */
  if (cache_node == NULL)
    return NULL;

  trace ("\t- cached value %s\n", registry_value_dump (((RegistryCacheItem *)cache_node->data)->value));

  registry_value = ((RegistryCacheItem *)cache_node->data)->value;

  gsettings_type = g_variant_type_dup_string (expected_type);

  /* The registry is user-editable, so we need to be fault-tolerant here. */
  switch (gsettings_type[0])
    {
    case 'b':
    case 'y':
    case 'n':
    case 'q':
    case 'i':
    case 'u':
      if (registry_value.type == REG_DWORD)
        gsettings_value = g_variant_new (gsettings_type, registry_value.dword);
      break;

    case 't':
    case 'x':
      if (registry_value.type == REG_QWORD)
        {
          DWORDLONG qword_value = *(DWORDLONG *)registry_value.ptr;
          gsettings_value = g_variant_new (gsettings_type, qword_value);
        }
      break;

    default:
      if (registry_value.type == REG_SZ)
        {
          if (gsettings_type[0] == 's')
            gsettings_value = g_variant_new_string ((char *)registry_value.ptr);
          else
            {
              GError *error = NULL;

              gsettings_value = g_variant_parse (expected_type, registry_value.ptr,
                                                 NULL, NULL, &error);

              if (error != NULL)
                g_message ("gregistrysettingsbackend: error parsing key %s: %s",
                           key_name, error->message);
            }
        }
        break;
    }

  g_free (gsettings_type);

  return gsettings_value;
}


typedef struct
{
  GRegistryBackend *self;
  HKEY hroot;
} RegistryWrite;

static gboolean
g_registry_backend_write_one (const char *key_name,
                              GVariant   *variant,
                              gpointer    user_data)
{
  GRegistryBackend *self;
  RegistryWrite *action;
  RegistryValue value;
  HKEY hroot;
  HKEY hpath;
  gchar *path_name;
  gunichar2 *path_namew;
  gchar *value_name = NULL;
  gunichar2 *value_namew;
  DWORD value_data_size;
  LPVOID value_data;
  gunichar2 *value_dataw;
  LONG result;
  GNode *node;
  gboolean changed;
  const gchar *type_string;

  type_string = g_variant_get_type_string (variant);
  action = user_data;
  self = G_REGISTRY_BACKEND (action->self);
  hroot = action->hroot;

  value.type = REG_NONE;
  value.ptr = NULL;

  switch (type_string[0])
    {
    case 'b':
    case 'y':
    case 'n':
    case 'q':
    case 'i':
    case 'u':
      value.type = REG_DWORD;
      value.dword = g_variant_get_as_dword (variant);
      value_data_size = 4;
      value_data = &value.dword;
      break;

    case 'x':
    case 't':
      value.type = REG_QWORD;
      value.ptr = g_malloc (8);
      *(DWORDLONG *)value.ptr = g_variant_get_as_qword (variant);
      value_data_size = 8;
      value_data = value.ptr;
      break;

    default:
      value.type = REG_SZ;
      if (type_string[0] == 's')
        {
          gsize length;
          value.ptr = g_strdup (g_variant_get_string (variant, &length));
          value_data_size = length + 1;
          value_data = value.ptr;
        }
      else
        {
          GString *value_string;
          value_string = g_variant_print_string (variant, NULL, FALSE);
          value_data_size = value_string->len + 1;
          value.ptr = value_data = g_string_free (value_string, FALSE);
        }
      break;
    }

  /* First update the cache, because the value may not have changed and we can
   * save a write.
   * 
   * If 'value' has changed then its memory will not be freed by update_node(),
   * because it will be stored in the node.
   */
  EnterCriticalSection (self->cache_lock);
  node = registry_cache_get_node_for_key (self->cache_root, key_name, TRUE);
  changed = registry_cache_update_node (node, value);
  LeaveCriticalSection (self->cache_lock);

  if (!changed)
    return FALSE;

  /* Block the next notification to any watch points above this location,
   * because they will each get triggered on a change that is already updated
   * in the cache.
   */
  registry_cache_block_notification (node);

  path_name = parse_key (key_name, NULL, &value_name);

  trace ("Set key: %s / %s\n", path_name, value_name);

  path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL);

  /* Store the value in the registry */
  result = RegCreateKeyExW (hroot, path_namew, 0, NULL, 0, KEY_WRITE, NULL, &hpath, NULL);
  if (result != ERROR_SUCCESS)
    {
      g_message_win32_error (result, "gregistrybackend: opening key %s failed",
                             path_name + 1);
      registry_value_free (value);
      g_free (path_namew);
      g_free (path_name);
      return FALSE;
    }

  g_free (path_namew);

  value_namew = g_utf8_to_utf16 (value_name, -1, NULL, NULL, NULL);

  value_dataw = NULL;

  switch (type_string[0])
    {
    case 'b':
    case 'y':
    case 'n':
    case 'q':
    case 'i':
    case 'u':
    case 'x':
    case 't':
      break;
    default:
      value_dataw = g_utf8_to_utf16 (value_data, -1, NULL, NULL, NULL);
      value_data = value_dataw;
      value_data_size = (DWORD)((wcslen (value_data) + 1) * sizeof (gunichar2));
      break;
    }

  result = RegSetValueExW (hpath, value_namew, 0, value.type, value_data, value_data_size);

  if (result != ERROR_SUCCESS)
    g_message_win32_error (result, "gregistrybackend: setting value %s\\%s\\%s failed.\n",
                           self->base_path, path_name, value_name);

  /* If the write fails then it will seem like the value has changed until the
   * next execution (because we wrote to the cache first). There's no reason
   * for it to fail unless something is weirdly broken, however.
   */

  RegCloseKey (hpath);
  g_free (path_name);
  g_free (value_namew);
  g_free (value_dataw);

  return FALSE;
}

/* The dconf write policy is to do the write while making out it succeeded, 
 * and then backtrack if it didn't. The registry functions are synchronous so
 * we can't do that. */

static gboolean
g_registry_backend_write (GSettingsBackend *backend,
                          const gchar      *key_name,
                          GVariant         *value,
                          gpointer          origin_tag)
{
  GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
  LONG result;
  HKEY hroot;
  RegistryWrite action;

  result = RegCreateKeyExW (HKEY_CURRENT_USER, self->base_pathw, 0, NULL, 0,
                            KEY_WRITE, NULL, &hroot, NULL);
  if (result != ERROR_SUCCESS)
    {
      trace ("Error opening/creating key %s.\n", self->base_path);
      return FALSE;
    }

  action.self = self;
  action.hroot = hroot;
  g_registry_backend_write_one (key_name, value, &action);
  g_settings_backend_changed (backend, key_name, origin_tag);

  RegCloseKey (hroot);

  return TRUE;
}

static gboolean
g_registry_backend_write_tree (GSettingsBackend *backend,
                               GTree            *values,
                               gpointer          origin_tag)
{
  GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
  LONG result;
  HKEY hroot;
  RegistryWrite action;

  result = RegCreateKeyExW (HKEY_CURRENT_USER, self->base_pathw, 0, NULL, 0,
                            KEY_WRITE, NULL, &hroot, NULL);
  if (result != ERROR_SUCCESS)
    {
      trace ("Error opening/creating key %s.\n", self->base_path);
      return FALSE;
    }

  action.self =  self;
  action.hroot = hroot;
  g_tree_foreach (values, (GTraverseFunc)g_registry_backend_write_one,
                  &action);

  g_settings_backend_changed_tree (backend, values, origin_tag);
  RegCloseKey (hroot);

  return TRUE;
}

static void
g_registry_backend_reset (GSettingsBackend *backend,
                          const gchar      *key_name,
                          gpointer          origin_tag)
{
  GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
  gchar *path_name;
  gunichar2 *path_namew;
  gchar *value_name = NULL;
  gunichar2 *value_namew;
  GNode *cache_node;
  LONG result;
  HKEY hpath;

  /* Remove from cache */
  EnterCriticalSection (self->cache_lock);
  cache_node = registry_cache_get_node_for_key (self->cache_root, key_name, FALSE);
  if (cache_node)
    registry_cache_destroy_tree (cache_node, self->watch);
  LeaveCriticalSection (self->cache_lock);

  /* Remove from the registry */
  path_name = parse_key (key_name, self->base_path, &value_name);
  path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL);

  result = RegOpenKeyExW (HKEY_CURRENT_USER, path_namew, 0, KEY_SET_VALUE, &hpath);
  g_free (path_namew);

  if (result != ERROR_SUCCESS)
    {
      g_message_win32_error (result, "Registry: resetting key '%s'", path_name);
      g_free (path_name);
      return;
    }

  value_namew = g_utf8_to_utf16 (value_name, -1, NULL, NULL, NULL);

  result = RegDeleteValueW (hpath, value_namew);
  g_free (value_namew);
  RegCloseKey (hpath);

  if (result != ERROR_SUCCESS)
    {
      g_message_win32_error (result, "Registry: resetting key '%s'", path_name);
      g_free (path_name);
      return;
    }

  g_free (path_name);

  g_settings_backend_changed (backend, key_name, origin_tag);
}

static gboolean
g_registry_backend_get_writable (GSettingsBackend *backend,
                                 const gchar      *key_name)
{
  GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
  gchar *path_name;
  gunichar2 *path_namew;
  gchar *value_name;
  HKEY hpath;
  LONG result;

  path_name = parse_key (key_name, self->base_path, &value_name);
  path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL);

  /* Note: we create the key if it wasn't created yet, but it is not much
   * of a problem since at the end of the day we have to create it anyway
   * to read or to write from it
   */
  result = RegCreateKeyExW (HKEY_CURRENT_USER, path_namew, 0, NULL, 0,
                            KEY_WRITE, NULL, &hpath, NULL);
  g_free (path_namew);

  if (result != ERROR_SUCCESS)
    {
      trace ("Error opening/creating key to check writability: %s.\n",
             path_name);
      g_free (path_name);

      return FALSE;
    }

  g_free (path_name);
  RegCloseKey (hpath);

  return TRUE;
}

/********************************************************************************
 * Spot-the-difference engine
 ********************************************************************************/

static void
_free_watch (WatchThreadState *self,
             guint             index,
             GNode            *cache_node);

static void
registry_cache_item_reset_readable (GNode    *node,
                                    gpointer  data)
{
  RegistryCacheItem *item = node->data;
  item->readable = FALSE;
}

/* Delete a node and any children, for when it has been deleted from the registry */
static void
registry_cache_destroy_tree (GNode            *node,
                             WatchThreadState *self)
{
  RegistryCacheItem *item = node->data;

  g_node_children_foreach (node, G_TRAVERSE_ALL,
                           (GNodeForeachFunc)registry_cache_destroy_tree, self);

  if (item->subscription_count > 0)
    {
      guint i;

      /* There must be some watches active if this node is a watch point */
      g_warn_if_fail (self->cache_nodes->len > 1);

      /* This is a watch point that has been deleted. Let's free the watch! */
      for (i = 1; i < self->cache_nodes->len; i++)
        {
          if (g_ptr_array_index (self->cache_nodes, i) == node)
            break;
        }

      if (i >= self->cache_nodes->len)
        g_warning ("watch thread: a watch point was deleted, but unable to "
                   "find '%s' in the list of %i watch nodes\n", item->name,
                   self->cache_nodes->len - 1);
      else
        {
          _free_watch (self, i, node);
          g_atomic_int_inc (&self->watches_remaining);
        }
    }
  registry_cache_item_free (node->data);
  g_node_destroy (node);
}

/* One of these is sent down the pipe when something happens in the registry. */
typedef struct
{
  GRegistryBackend *self;
  gchar *prefix;          /* prefix is a gsettings path, all items are subkeys of this. */
  GPtrArray *items;       /* each item is a subkey below prefix that has changed. */
} RegistryEvent;

typedef struct
{
  RegistryEvent *event;
  gchar *current_key_name;
} DeletedItemData;

static void
mark_all_subkeys_as_changed (GNode    *node,
                             gpointer  data)
{
  RegistryCacheItem *item = node->data;
  DeletedItemData *item_data = data;

  if (item_data->current_key_name == NULL)
    item_data->current_key_name = g_strdup (item->name);
  else
    {
      gchar *name;

      name = g_build_path ("/", item_data->current_key_name, item->name, NULL);
      g_free (item_data->current_key_name);
      item_data->current_key_name = name;
    }

  /* Iterate until we find an item that is a value */
  if (item->value.type == REG_NONE)
    g_node_children_foreach (node, G_TRAVERSE_ALL,
                             mark_all_subkeys_as_changed, data);
  else
    g_ptr_array_add (item_data->event->items, item_data->current_key_name);
}

static void
registry_cache_remove_deleted (GNode    *node,
                               gpointer  data)
{
  RegistryCacheItem *item = node->data;
  RegistryEvent *event = data;

  if (!item->readable)
    {
      DeletedItemData item_data;

      item_data.event = event;
      item_data.current_key_name = NULL;

      mark_all_subkeys_as_changed (node, &item_data);
      registry_cache_destroy_tree (node, event->self->watch);
    }
}

/* Update cache from registry, and optionally report on the changes.
 * 
 * This function is sometimes called from the watch thread, with no locking. It
 * does call g_registry_backend functions, but this is okay because they only
 * access self->base which is constant.
 *
 * When looking at this code bear in mind the terminology: in the registry, keys
 * are containers that contain values, and other keys. Keys have a 'default'
 * value which we always ignore.
 *
 * n_parent_watches: a counter used to set the reference count of any new nodes
 *                   that are created - they should have as many references as
 *                   there are notifications that are watching them.
 */
static void
registry_cache_update (GRegistryBackend *self,
                       HKEY              hpath,
                       const gchar      *prefix,
                       const gchar      *partial_key_name,
                       GNode            *cache_node,
                       int               n_watches,
                       RegistryEvent    *event)
{
  gunichar2 bufferw[MAX_KEY_NAME_LENGTH + 1];
  gchar *buffer;
  gchar *key_name;
  gint i;
  LONG result;
  RegistryCacheItem *item;

  item = cache_node->data;

  if (item->subscription_count > 0)
    n_watches++;

  /* prefix is the level that all changes occur below; partial_key_name should
   * be NULL on the first call to this function */
  key_name = g_build_path ("/", prefix, partial_key_name, NULL);

  trace ("registry cache update: %s. Node %x has %i children\n", key_name,
         cache_node, g_node_n_children (cache_node));

  /* Start by zeroing 'readable' flag. When the registry traversal is done, any unreadable nodes
   * must have been deleted from the registry.
   */
  g_node_children_foreach (cache_node, G_TRAVERSE_ALL,
                           registry_cache_item_reset_readable, NULL);

  /* Recurse into each subpath at the current level, if any */
  i = 0;
  while (1)
    {
      DWORD bufferw_size = MAX_KEY_NAME_LENGTH + 1;
      HKEY  hsubpath;

      result = RegEnumKeyExW (hpath, i++, bufferw, &bufferw_size, NULL, NULL, NULL, NULL);
      if (result != ERROR_SUCCESS)
        break;

      result = RegOpenKeyExW (hpath, bufferw, 0, KEY_READ, &hsubpath);
      if (result == ERROR_SUCCESS)
        {
          GNode *subkey_node;
          RegistryCacheItem *child_item;
          gchar *new_partial_key_name;

          buffer = g_utf16_to_utf8 (bufferw, -1, NULL, NULL, NULL);
          if (buffer == NULL)
            continue;

          subkey_node = registry_cache_find_immediate_child (cache_node, buffer);
          if (subkey_node == NULL)
            {
              RegistryValue null_value = {REG_NONE, {0}};
              subkey_node = registry_cache_add_item (cache_node, buffer,
                                                     null_value, n_watches);
            }

          new_partial_key_name = g_build_path ("/", partial_key_name, buffer, NULL);
          registry_cache_update (self, hsubpath, prefix, new_partial_key_name,
                                 subkey_node, n_watches, event);
          g_free (new_partial_key_name);

          child_item = subkey_node->data;
          child_item->readable = TRUE;

          g_free (buffer);
          RegCloseKey (hsubpath);
        }
    }

  if (result != ERROR_NO_MORE_ITEMS)
    g_message_win32_error (result, "gregistrybackend: error enumerating subkeys for cache.");

  /* Enumerate each value at 'path' and check if it has changed */
  i = 0;
  while (1)
    {
      DWORD bufferw_size = MAX_KEY_NAME_LENGTH + 1;
      GNode *cache_child_node;
      RegistryCacheItem *child_item;
      RegistryValue value;
      gboolean changed = FALSE;

      result = RegEnumValueW (hpath, i++, bufferw, &bufferw_size, NULL, NULL, NULL, NULL);
      if (result != ERROR_SUCCESS)
        break;

      buffer = g_utf16_to_utf8 (bufferw, -1, NULL, NULL, NULL);

      if (buffer == NULL || buffer[0] == 0)
        {
          /* This is the key's 'default' value, for which we have no use. */
          g_free (buffer);
          continue;
        }

      cache_child_node = registry_cache_find_immediate_child (cache_node, buffer);

      if (!registry_read (hpath, key_name, buffer, &value))
        {
          g_free (buffer);
          continue;
        }

      trace ("\tgot value %s for %s, node %x\n",
             registry_value_dump (value), buffer, cache_child_node);

      if (cache_child_node == NULL)
        {
          /* This is a new value */
          cache_child_node = registry_cache_add_item (cache_node, buffer, value,
                                                      n_watches);
          changed = TRUE;
        }
      else
        {
         /* For efficiency, instead of converting every value back to a GVariant to
          * compare it, we compare them as registry values (integers, or string
          * representations of the variant). The spurious change notifications that may
          * result should not be a big issue.
          *
          * Note that 'value' is swallowed or freed.
          */
          changed = registry_cache_update_node (cache_child_node, value);
        }

      child_item = cache_child_node->data;
      child_item->readable = TRUE;
      if (changed && event != NULL)
        {
          gchar *item;

          if (partial_key_name == NULL)
            item = g_strdup (buffer);
          else
            item = g_build_path ("/", partial_key_name, buffer, NULL);

          g_ptr_array_add (event->items, item);
        }

      g_free (buffer);
    }

  if (result != ERROR_NO_MORE_ITEMS)
    g_message_win32_error (result, "gregistrybackend: error enumerating values for cache");

  /* Any nodes now left unreadable must have been deleted, remove them from cache */
  g_node_children_foreach (cache_node, G_TRAVERSE_ALL,
                           registry_cache_remove_deleted, event);

  trace ("registry cache update complete.\n");

  g_free (key_name);
}

/***********************************************************************************
 * Thread to watch for registry change events
 ***********************************************************************************/

/* Called by watch thread. Apply for notifications on a registry key and its subkeys. */
static DWORD
registry_watch_key (HKEY   hpath,
                    HANDLE event)
{
  return RegNotifyChangeKeyValue (hpath, TRUE,
                                  REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
                                  event, TRUE);
}

/* This handler runs in the main thread to emit the changed signals */
static gboolean
watch_handler (RegistryEvent *event)
{
  trace ("Watch handler: got event in %s, items %i.\n", event->prefix, event->items->len);

  /* GSettings requires us to NULL-terminate the array. */
  g_ptr_array_add (event->items, NULL);
  g_settings_backend_keys_changed (G_SETTINGS_BACKEND (event->self), event->prefix,
                                   (gchar const **)event->items->pdata, NULL);

  g_ptr_array_free (event->items, TRUE);
  g_free (event->prefix);
  g_object_unref (event->self);
  g_slice_free (RegistryEvent, event);

  return G_SOURCE_REMOVE;
}

static void
_free_watch (WatchThreadState *self,
             guint             index,
             GNode            *cache_node)
{
  HKEY hpath;
  HANDLE cond;
  gchar *prefix;

  g_return_if_fail (index > 0 && index < self->events->len);

  cond = g_ptr_array_index (self->events, index);
  hpath = g_ptr_array_index (self->handles, index);
  prefix = g_ptr_array_index (self->prefixes, index);

  trace ("Freeing watch %i [%s]\n", index, prefix);
 
  /* These can be NULL if the watch was already dead, this can happen when eg.
   * a key is deleted but GSettings is still subscribed to it - the watch is
   * kept alive so that the unsubscribe function works properly, but does not
   * do anything.
   */
  if (hpath != NULL)
    RegCloseKey (hpath);

  if (cache_node != NULL)
    {
      //registry_cache_dump (G_REGISTRY_BACKEND (self->owner)->cache_root, NULL);
      registry_cache_unref_tree (cache_node);
    }

  CloseHandle (cond);
  g_free (prefix);

  /* As long as we remove from each array at the same time, it doesn't matter that
   * their orders get messed up - they all get messed up the same.
   */
  g_ptr_array_remove_index_fast (self->handles, index);
  g_ptr_array_remove_index_fast (self->events, index);
  g_ptr_array_remove_index_fast (self->prefixes, index);
  g_ptr_array_remove_index_fast (self->cache_nodes, index);
}

static void
watch_thread_handle_message (WatchThreadState *self)
{
  switch (self->message.type)
    {
    case WATCH_THREAD_NONE:
      trace ("watch thread: you woke me up for nothin', man!");
      break;

    case WATCH_THREAD_ADD_WATCH:
      {
        RegistryWatch *watch = &self->message.watch;
        LONG result;

        result = registry_watch_key (watch->hpath, watch->event);

        if (result == ERROR_SUCCESS)
          {
            g_ptr_array_add (self->events, watch->event);
            g_ptr_array_add (self->handles, watch->hpath);
            g_ptr_array_add (self->prefixes, watch->prefix);
            g_ptr_array_add (self->cache_nodes, watch->cache_node);

            trace ("watch thread: new watch on %s, %i total\n", watch->prefix,
                   self->events->len);
          }
        else
          {
            g_message_win32_error (result, "watch thread: could not watch %s", watch->prefix);

            CloseHandle (watch->event);
            RegCloseKey (watch->hpath);
            g_free (watch->prefix);
            registry_cache_unref_tree (watch->cache_node);
          }
        break;
      }

    case WATCH_THREAD_REMOVE_WATCH:
      {
        GNode *cache_node;
        RegistryCacheItem *cache_item;
        guint i;

        for (i = 1; i < self->prefixes->len; i++)
          {
            if (strcmp (g_ptr_array_index (self->prefixes, i),
                        self->message.watch.prefix) == 0)
              break;
          }

        if (i >= self->prefixes->len)
          {
            /* Don't make a fuss if the prefix is not being watched because
             * maybe the path was deleted so we removed the watch.
             */
            trace ("unsubscribe: prefix %s is not being watched [%i things are]!\n",
                   self->message.watch.prefix, self->prefixes->len);
            g_free (self->message.watch.prefix);
            break;
          }

        cache_node = g_ptr_array_index (self->cache_nodes, i);

        trace ("watch thread: unsubscribe: freeing node %p, prefix %s, index %i\n",
               cache_node, self->message.watch.prefix, i);

        if (cache_node != NULL)
          {
            cache_item = cache_node->data;

            /* There may be more than one GSettings object subscribed to this
             * path, only free the watch when the last one unsubscribes.
             */
            cache_item->subscription_count--;
            if (cache_item->subscription_count > 0)
              break;
          }

        _free_watch (self, i, cache_node);
        g_free (self->message.watch.prefix);

        g_atomic_int_inc (&self->watches_remaining);
        break;
      }

    case WATCH_THREAD_STOP:
      {
        guint i;

        /* Free any remaining cache and watch handles */
        for (i = 1; i < self->events->len; i++)
          _free_watch (self, i, g_ptr_array_index (self->cache_nodes, i));

        SetEvent (self->message_received_event);
        ExitThread (0);
      }
    }

  self->message.type = WATCH_THREAD_NONE;
  SetEvent (self->message_received_event);
}

/* Thread which watches for win32 registry events */
static DWORD WINAPI
watch_thread_function (LPVOID parameter)
{
  WatchThreadState *self = (WatchThreadState *)parameter;
  DWORD result;

  self->events = g_ptr_array_new ();
  self->handles = g_ptr_array_new ();
  self->prefixes = g_ptr_array_new ();
  self->cache_nodes = g_ptr_array_new ();
  g_ptr_array_add (self->events, self->message_sent_event);
  g_ptr_array_add (self->handles, NULL);
  g_ptr_array_add (self->prefixes, NULL);
  g_ptr_array_add (self->cache_nodes, NULL);

  while (1)
    {
      trace ("watch thread: going to sleep; %i events watched.\n", self->events->len);
      result = WaitForMultipleObjects (self->events->len, self->events->pdata, FALSE, INFINITE);

      if (result == WAIT_OBJECT_0)
        {
          /* A message to you. The sender (main thread) will block until we signal the received
           * event, so there should be no danger of it sending another before we receive the
           * first.
           */
          watch_thread_handle_message (self);
        }
      else if (result > WAIT_OBJECT_0 && result <= WAIT_OBJECT_0 + self->events->len)
        {
          HKEY hpath;
          HANDLE cond;
          gchar *prefix;
          GNode *cache_node;
          RegistryCacheItem *cache_item;
          RegistryEvent *event;
          gint notify_index;

          /* One of our notifications has triggered. All we know is which one, and which key
           * this is for. We do most of the processing here, because we may as well. If the
           * registry changes further while we are processing it doesn't matter - we will then
           * receive another change notification from the OS anyway.
           */
          notify_index = result - WAIT_OBJECT_0;
          hpath = g_ptr_array_index (self->handles, notify_index);
          cond = g_ptr_array_index (self->events, notify_index);
          prefix = g_ptr_array_index (self->prefixes, notify_index);
          cache_node = g_ptr_array_index (self->cache_nodes, notify_index);

          trace ("Watch thread: notify received on prefix %i: %s.\n", notify_index, prefix);

          if (cache_node == NULL)
            {
              /* This path has been deleted */
              trace ("Notify received on a path that was deleted\n");
              continue;
            }

          /* Firstly we need to reapply for the notification, because (what a
           * sensible API) we won't receive any more. MSDN is pretty
           * inconsistent on this matter:
           *   http://msdn.microsoft.com/en-us/library/ms724892%28VS.85%29.aspx
           *   http://support.microsoft.com/kb/236570
           * But my tests (on Windows XP SP3) show that we need to reapply
           * each time.
           */
          result = registry_watch_key (hpath, cond);

          if (result != ERROR_SUCCESS)
            {
              /* Watch failed, most likely because the key has just been
               * deleted. Free the watch and unref the cache nodes.
               */
             if (result != ERROR_KEY_DELETED)
               g_message_win32_error (result, "watch thread: failed to watch %s", prefix);

             _free_watch (self, notify_index, cache_node);
             g_atomic_int_inc (&self->watches_remaining);
             continue;
            }

          /* The notification may have been blocked because we just changed
           * some data ourselves.
           */
          cache_item = cache_node->data;
          if (cache_item->block_count)
            {
              cache_item->block_count--;
              trace ("Watch thread: notify blocked at %s\n", prefix);
              continue;
            }

          /* Now we update our stored cache from registry data, and find which keys have
           * actually changed. If more changes happen while we are processing, we will get
           * another event because we have reapplied for change notifications already.
           *
           * Working here rather than in the main thread is preferable because the UI is less
           * likely to block (only when changing notification subscriptions).
           */
          event = g_slice_new (RegistryEvent);
          event->self = G_REGISTRY_BACKEND (g_object_ref (self->owner));
          event->prefix = g_strdup (prefix);
          event->items = g_ptr_array_new_with_free_func (g_free);

          EnterCriticalSection (G_REGISTRY_BACKEND (self->owner)->cache_lock);
          registry_cache_update (G_REGISTRY_BACKEND (self->owner), hpath,
                                 prefix, NULL, cache_node, 0, event);
          LeaveCriticalSection (G_REGISTRY_BACKEND (self->owner)->cache_lock);

          if (event->items->len > 0)
            g_idle_add ((GSourceFunc) watch_handler, event);
          else
            {
              g_object_unref (event->self);
              g_free (event->prefix);
              g_ptr_array_free (event->items, TRUE);
              g_slice_free (RegistryEvent, event);
            }
        }
      else
        {
          /* God knows what has happened */
          g_message_win32_error (GetLastError(), "watch thread: WaitForMultipleObjects error");
        }
    }

  return -1;
}

static gboolean
watch_start (GRegistryBackend *self)
{
  WatchThreadState *watch;

  g_return_val_if_fail (self->watch == NULL, FALSE);

  watch = g_slice_new (WatchThreadState);
  watch->owner = G_SETTINGS_BACKEND (self);

  watch->watches_remaining = MAX_WATCHES;

  watch->message_lock = g_slice_new (CRITICAL_SECTION);
  InitializeCriticalSection (watch->message_lock);
  watch->message_sent_event = CreateEvent (NULL, FALSE, FALSE, NULL);
  watch->message_received_event = CreateEvent (NULL, FALSE, FALSE, NULL);
  if (watch->message_sent_event == NULL || watch->message_received_event == NULL)
    {
      g_message_win32_error (GetLastError (), "gregistrybackend: Failed to create sync objects.");
      goto fail;
    }

  /* Use a small stack to make the thread more lightweight. */
  watch->thread = CreateThread (NULL, 1024, watch_thread_function, watch, 0, NULL);
  if (watch->thread == NULL)
    {
      g_message_win32_error (GetLastError (), "gregistrybackend: Failed to create notify watch thread.");
      goto fail;
    }

  self->watch = watch;

  return TRUE;

fail:
  DeleteCriticalSection (watch->message_lock);
  g_slice_free (CRITICAL_SECTION, watch->message_lock);
  if (watch->message_sent_event != NULL)
    CloseHandle (watch->message_sent_event);
  if (watch->message_received_event != NULL)
    CloseHandle (watch->message_received_event);
  g_slice_free (WatchThreadState, watch);

  return FALSE;
}

/* This function assumes you hold the message lock! */
static void
watch_stop_unlocked (GRegistryBackend *self)
{
  WatchThreadState *watch = self->watch;
  DWORD result;

  g_return_if_fail (watch != NULL);

  watch->message.type = WATCH_THREAD_STOP;
  SetEvent (watch->message_sent_event);

  /* This is signalled as soon as the message is received. We must not return
   * while the watch thread is still firing off callbacks. Freeing all of the
   * memory is done in the watch thread after this is signalled.
   */
  result = WaitForSingleObject (watch->message_received_event, INFINITE);
  if (result != WAIT_OBJECT_0)
    {
      g_warning ("gregistrybackend: unable to stop watch thread.");
      return;
    }

  LeaveCriticalSection (watch->message_lock);
  DeleteCriticalSection (watch->message_lock);
  g_slice_free (CRITICAL_SECTION, watch->message_lock);
  CloseHandle (watch->message_sent_event);
  CloseHandle (watch->message_received_event);
  CloseHandle (watch->thread);
  g_slice_free (WatchThreadState, watch);

  trace ("\nwatch thread: %x: all data freed.\n", self);
  self->watch = NULL;
}

static gboolean
watch_add_notify (GRegistryBackend *self,
                  HANDLE            event,
                  HKEY              hpath,
                  gchar            *gsettings_prefix)
{
  WatchThreadState *watch = self->watch;
  GNode *cache_node;
  RegistryCacheItem *cache_item;
#ifdef TRACE
  DWORD result;
#endif

  g_return_val_if_fail (watch != NULL, FALSE);

  trace ("watch_add_notify: prefix %s.\n", gsettings_prefix);

  /* Duplicate tree into the cache in the main thread, before we add the notify: if we do it in the
   * thread we can miss changes while we are caching.
   */
  EnterCriticalSection (self->cache_lock);
  cache_node = registry_cache_get_node_for_key (self->cache_root, gsettings_prefix, TRUE);

  if (cache_node == NULL || cache_node->data == NULL)
    {
      LeaveCriticalSection (self->cache_lock);
      g_warn_if_reached ();
      return FALSE;
    }
  
  cache_item = cache_node->data;

  cache_item->subscription_count++;
  if (cache_item->subscription_count > 1)
    {
      trace ("watch_add_notify: prefix %s already watched, %i subscribers.\n",
             gsettings_prefix, cache_item->subscription_count);
      LeaveCriticalSection (self->cache_lock);
      return FALSE;
    }

  registry_cache_ref_tree (cache_node);
  registry_cache_update (self, hpath, gsettings_prefix, NULL, cache_node, 0, NULL);
  //registry_cache_dump (self->cache_root, NULL);
  LeaveCriticalSection (self->cache_lock);

  EnterCriticalSection (watch->message_lock);
  watch->message.type = WATCH_THREAD_ADD_WATCH;
  watch->message.watch.event = event;
  watch->message.watch.hpath = hpath;
  watch->message.watch.prefix = gsettings_prefix;
  watch->message.watch.cache_node = cache_node;

  SetEvent (watch->message_sent_event);

  /* Wait for the received event in return, to avoid sending another message before the first
   * one was received. If it takes > 200ms there is a possible race but the worst outcome is
   * a notification is ignored.
   */
#ifdef TRACE
  result =
#endif
    WaitForSingleObject (watch->message_received_event, 200);
#ifdef TRACE
  if (result != WAIT_OBJECT_0)
    trace ("watch thread is slow to respond - notification may not be added.");
#endif

  LeaveCriticalSection (watch->message_lock);

  return TRUE;
}

static void
watch_remove_notify (GRegistryBackend *self,
                     const gchar      *key_name)
{
  WatchThreadState *watch = self->watch;
  LONG result;

  if (self->watch == NULL)
    /* Here we assume that the unsubscribe message is for somewhere that was
     * deleted, and so it has already been removed and the watch thread has
     * stopped.
     */
    return;

  EnterCriticalSection (watch->message_lock);
  watch->message.type = WATCH_THREAD_REMOVE_WATCH;
  watch->message.watch.prefix = g_strdup (key_name);

  SetEvent (watch->message_sent_event);

  /* Wait for the received event in return, to avoid sending another message before the first
   * one was received.
   */
  result = WaitForSingleObject (watch->message_received_event, INFINITE);

  if (result != ERROR_SUCCESS)
    g_warning ("unsubscribe from %s: message not acknowledged", key_name);

  if (g_atomic_int_get (&watch->watches_remaining) >= MAX_WATCHES)
    /* Stop it before any new ones can get added and confuse things */
    watch_stop_unlocked (self);
  else
    LeaveCriticalSection (watch->message_lock);
}

/* dconf semantics are: if the key ends in /, watch the keys underneath it - if not, watch that
 * key. Our job is easier because keys and values are separate.
 */
static void
g_registry_backend_subscribe (GSettingsBackend *backend,
                              const char       *key_name)
{
  GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
  gchar *path_name;
  gunichar2 *path_namew;
  gchar *value_name = NULL;
  HKEY hpath;
  HANDLE event;
  LONG result;

  if (self->watch == NULL && !watch_start (self))
    return;

  if (g_atomic_int_dec_and_test (&self->watch->watches_remaining))
    {
      g_atomic_int_inc (&self->watch->watches_remaining);
      g_warning ("subscribe() failed: only %i different paths may be watched.", MAX_WATCHES);
      return;
    }

  path_name = parse_key (key_name, self->base_path, &value_name);

  /* Must check for this, otherwise strange crashes occur because the cache
   * node that is being watched gets freed. All path names to subscribe must
   * end in a slash!
   */
  if (value_name != NULL && *value_name != 0)
    g_warning ("subscribe() failed: path must end in a /, got %s", key_name);

  trace ("Subscribing to %s [registry %s / %s] - watch %x\n", key_name, path_name, value_name, self->watch);

  path_namew = g_utf8_to_utf16 (path_name, -1, NULL, NULL, NULL);
  g_free (path_name);

  /* Give the caller the benefit of the doubt if the key doesn't exist and create it. The caller
   * is almost certainly a new g_settings with this path as base path. */
  result = RegCreateKeyExW (HKEY_CURRENT_USER, path_namew, 0, NULL, 0, KEY_READ, NULL, &hpath,
                            NULL);
  g_free (path_namew);

  if (result != ERROR_SUCCESS)
    {
      g_message_win32_error (result, "gregistrybackend: Unable to subscribe to key %s.", key_name);
      g_atomic_int_inc (&self->watch->watches_remaining);
      return;
    }

  event = CreateEvent (NULL, FALSE, FALSE, NULL);
  if (event == NULL)
    {
      g_message_win32_error (result, "gregistrybackend: CreateEvent failed.");
      g_atomic_int_inc (&self->watch->watches_remaining);
      RegCloseKey (hpath);
      return;
    }

  /* The actual watch is added by the thread, which has to re-subscribe each time it
   * receives a change. */
  if (!watch_add_notify (self, event, hpath, g_strdup (key_name)))
    {
      g_atomic_int_inc (&self->watch->watches_remaining);
      RegCloseKey (hpath);
      CloseHandle (event);
    }
}

static void
g_registry_backend_unsubscribe (GSettingsBackend *backend,
                                const char       *key_name)
{
  trace ("unsubscribe: %s.\n", key_name);

  watch_remove_notify (G_REGISTRY_BACKEND (backend), key_name);
}

/********************************************************************************
 * Object management junk
 ********************************************************************************/

static void
g_registry_backend_finalize (GObject *object)
{
  GRegistryBackend *self = G_REGISTRY_BACKEND (object);
  RegistryCacheItem *item;

  item = self->cache_root->data;
  g_warn_if_fail (item->ref_count == 1);

  registry_cache_item_free (item);
  g_node_destroy (self->cache_root);

  if (self->watch != NULL)
    {
      EnterCriticalSection (self->watch->message_lock);
      watch_stop_unlocked (self);
    }

  DeleteCriticalSection (self->cache_lock);
  g_slice_free (CRITICAL_SECTION, self->cache_lock);

  g_free (self->base_path);
  g_free (self->base_pathw);
}

static void
g_registry_backend_class_init (GRegistryBackendClass *class)
{
  GSettingsBackendClass *backend_class = G_SETTINGS_BACKEND_CLASS (class);
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->finalize = g_registry_backend_finalize;

  backend_class->read = g_registry_backend_read;
  backend_class->write = g_registry_backend_write;
  backend_class->write_tree = g_registry_backend_write_tree;
  backend_class->reset = g_registry_backend_reset;
  backend_class->get_writable = g_registry_backend_get_writable;
  backend_class->subscribe = g_registry_backend_subscribe;
  backend_class->unsubscribe = g_registry_backend_unsubscribe;
}

static void
g_registry_backend_init (GRegistryBackend *self)
{
  RegistryCacheItem *item;

  self->base_path = g_strdup_printf ("Software\\GSettings");
  self->base_pathw = g_utf8_to_utf16 (self->base_path, -1, NULL, NULL, NULL);

  item = g_slice_new (RegistryCacheItem);
  item->value.type = REG_NONE;
  item->value.ptr = NULL;
  item->name = g_strdup ("<root>");
  item->ref_count = 1;
  self->cache_root = g_node_new (item);

  self->cache_lock = g_slice_new (CRITICAL_SECTION);
  InitializeCriticalSection (self->cache_lock);

  self->watch = NULL;
}
