/*
 * 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   32

/* 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_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: %s.\n",
                           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 ("\treg 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 notifcation 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;
}
