/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2014 Руслан Ижбулатов <lrn1986@gmail.com>
 *
 * 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/>.
 *
 */

#include "config.h"
#include "ginitable.h"
#include "gwin32registrykey.h"
#include <gio/gioerror.h>
#ifdef _MSC_VER
#pragma warning ( disable:4005 )
#endif
#include <windows.h>
#include <ntstatus.h>
#include <winternl.h>

#include "gstrfuncsprivate.h"

#ifndef _WDMDDK_
typedef enum _KEY_INFORMATION_CLASS {
  KeyBasicInformation,
  KeyNodeInformation,
  KeyFullInformation,
  KeyNameInformation,
  KeyCachedInformation,
  KeyFlagsInformation,
  KeyVirtualizationInformation,
  KeyHandleTagsInformation,
  MaxKeyInfoClass
} KEY_INFORMATION_CLASS;

typedef struct _KEY_BASIC_INFORMATION {
  LARGE_INTEGER LastWriteTime;
  ULONG TitleIndex;
  ULONG NameLength;
  WCHAR Name[1];
} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
#endif

#if !defined (__OBJECT_ATTRIBUTES_DEFINED) && defined (__MINGW32_)
#define __OBJECT_ATTRIBUTES_DEFINED
  typedef struct _OBJECT_ATTRIBUTES {
    ULONG Length;
#ifdef _WIN64
    ULONG pad1;
#endif
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
#ifdef _WIN64
    ULONG pad2;
#endif
    PVOID SecurityDescriptor;
    PVOID SecurityQualityOfService;
  } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
#endif

#ifndef HKEY_CURRENT_USER_LOCAL_SETTINGS
#define HKEY_CURRENT_USER_LOCAL_SETTINGS ((HKEY) (ULONG_PTR)((LONG)0x80000007))
#endif

#if !defined (__UNICODE_STRING_DEFINED) && defined (__MINGW32_)
#define __UNICODE_STRING_DEFINED
typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
#endif
typedef const UNICODE_STRING* PCUNICODE_STRING;

typedef NTSTATUS
(NTAPI * NtQueryKeyFunc)(HANDLE                key_handle,
                         KEY_INFORMATION_CLASS key_info_class,
                         PVOID                 key_info_buffer,
                         ULONG                 key_info_buffer_size,
                         PULONG                result_size);

typedef NTSTATUS
(NTAPI * NtNotifyChangeMultipleKeysFunc)(HANDLE             key_handle,
                                         ULONG              subkey_count,
                                         POBJECT_ATTRIBUTES subkeys,
                                         HANDLE             event,
                                         PIO_APC_ROUTINE    apc_routine,
                                         PVOID              apc_closure,
                                         PIO_STATUS_BLOCK   status_block,
                                         ULONG              filter,
                                         BOOLEAN            watch_tree,
                                         PVOID              buffer,
                                         ULONG              buffer_size,
                                         BOOLEAN            async);

static NtQueryKeyFunc nt_query_key = NULL;
static NtNotifyChangeMultipleKeysFunc nt_notify_change_multiple_keys = NULL;

#define G_WIN32_KEY_UNWATCHED 0
#define G_WIN32_KEY_WATCHED 1
#define G_WIN32_KEY_UNCHANGED 0
#define G_WIN32_KEY_CHANGED 1
#define G_WIN32_KEY_UNKNOWN -1

enum
{
  PROP_0,
  PROP_PATH,
  PROP_PATH_UTF16,
  PROP_MAX,
};

typedef enum
{
  G_WIN32_REGISTRY_UPDATED_NOTHING = 0,
  G_WIN32_REGISTRY_UPDATED_PATH = 1,
} GWin32RegistryKeyUpdateFlag;

static gsize
g_utf16_len (const gunichar2 *str)
{
  gsize result;

  for (result = 0; str[0] != 0; str++, result++)
    ;

  return result;
}

static gunichar2 *
g_wcsdup (const gunichar2 *str, gssize str_len)
{
  gsize str_len_unsigned;
  gsize str_size;

  g_return_val_if_fail (str != NULL, NULL);

  if (str_len < 0)
    str_len_unsigned = g_utf16_len (str);
  else
    str_len_unsigned = (gsize) str_len;

  g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1);
  str_size = (str_len_unsigned + 1) * sizeof (gunichar2);

  return g_memdup2 (str, str_size);
}

/**
 * g_win32_registry_subkey_iter_copy:
 * @iter: an iterator
 *
 * Creates a dynamically-allocated copy of an iterator. Dynamically-allocated
 * state of the iterator is duplicated too.
 *
 * Returns: (transfer full): a copy of the @iter,
 * free with g_win32_registry_subkey_iter_free ()
 *
 * Since: 2.46
 **/
GWin32RegistrySubkeyIter *
g_win32_registry_subkey_iter_copy (const GWin32RegistrySubkeyIter *iter)
{
  GWin32RegistrySubkeyIter *new_iter;

  g_return_val_if_fail (iter != NULL, NULL);

  new_iter = g_new0 (GWin32RegistrySubkeyIter, 1);

  new_iter->key = g_object_ref (iter->key);
  new_iter->counter = iter->counter;
  new_iter->subkey_count = iter->subkey_count;
  new_iter->subkey_name = g_wcsdup (iter->subkey_name, iter->subkey_name_size);
  new_iter->subkey_name_size = iter->subkey_name_size;

  if (iter->subkey_name_u8)
    new_iter->subkey_name_u8 = iter->subkey_name_u8;
  else
    new_iter->subkey_name_u8 = NULL;

  return new_iter;
}

/**
 * g_win32_registry_subkey_iter_free:
 * @iter: a dynamically-allocated iterator
 *
 * Free an iterator allocated on the heap. For iterators that are allocated
 * on the stack use g_win32_registry_subkey_iter_clear () instead.
 *
 * Since: 2.46
 **/
void
g_win32_registry_subkey_iter_free (GWin32RegistrySubkeyIter *iter)
{
  g_return_if_fail (iter != NULL);

  g_object_unref (iter->key);
  g_free (iter->subkey_name);
  g_free (iter->subkey_name_u8);
  g_free (iter);
}

/**
 * g_win32_registry_subkey_iter_assign:
 * @iter: a #GWin32RegistrySubkeyIter
 * @other: another #GWin32RegistrySubkeyIter
 *
 * Assigns the value of @other to @iter.  This function
 * is not useful in applications, because iterators can be assigned
 * with `GWin32RegistrySubkeyIter i = j;`. The
 * function is used by language bindings.
 *
 * Since: 2.46
 **/
void
g_win32_registry_subkey_iter_assign (GWin32RegistrySubkeyIter       *iter,
                                     const GWin32RegistrySubkeyIter *other)
{
  g_return_if_fail (iter != NULL);
  g_return_if_fail (other != NULL);

  *iter = *other;
}


G_DEFINE_BOXED_TYPE (GWin32RegistrySubkeyIter, g_win32_registry_subkey_iter,
                     g_win32_registry_subkey_iter_copy,
                     g_win32_registry_subkey_iter_free)

/**
 * g_win32_registry_value_iter_copy:
 * @iter: an iterator
 *
 * Creates a dynamically-allocated copy of an iterator. Dynamically-allocated
 * state of the iterator is duplicated too.
 *
 * Returns: (transfer full): a copy of the @iter,
 * free with g_win32_registry_value_iter_free ().
 *
 * Since: 2.46
 **/
GWin32RegistryValueIter *
g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter)
{
  GWin32RegistryValueIter *new_iter;

  g_return_val_if_fail (iter != NULL, NULL);

  new_iter = g_new0 (GWin32RegistryValueIter, 1);

  new_iter->key = g_object_ref (iter->key);
  new_iter->counter = iter->counter;
  new_iter->value_count = iter->value_count;
  new_iter->value_name = g_wcsdup (iter->value_name, iter->value_name_size);
  new_iter->value_name_size = iter->value_name_size;

  if (iter->value_data != NULL)
    new_iter->value_data = g_memdup2 (iter->value_data, iter->value_data_size);

  new_iter->value_data_size = iter->value_data_size;

  if (iter->value_name_u8 != NULL)
    new_iter->value_name_u8 = g_strdup (iter->value_name_u8);

  new_iter->value_name_u8_len = iter->value_name_u8_len;

  if (iter->value_data_u8 != NULL)
    new_iter->value_data_u8 = g_strdup (iter->value_data_u8);

  new_iter->value_data_u8_size = iter->value_data_u8_size;

  if (iter->value_data_expanded != NULL)
    new_iter->value_data_expanded = g_wcsdup ((gunichar2 *) iter->value_data_expanded,
                                              iter->value_data_expanded_charsize * sizeof (gunichar2));

  new_iter->value_data_expanded_charsize = iter->value_data_expanded_charsize;

  if (iter->value_data_expanded_u8 != NULL)
    new_iter->value_data_expanded_u8 = g_memdup2 (iter->value_data_expanded_u8,
                                                  iter->value_data_expanded_charsize);

  new_iter->value_data_expanded_u8_size = iter->value_data_expanded_charsize;

  return new_iter;
}

/**
 * g_win32_registry_value_iter_free:
 * @iter: a dynamically-allocated iterator
 *
 * Free an iterator allocated on the heap. For iterators that are allocated
 * on the stack use g_win32_registry_value_iter_clear () instead.
 *
 * Since: 2.46
 **/
void
g_win32_registry_value_iter_free (GWin32RegistryValueIter *iter)
{
  g_return_if_fail (iter != NULL);

  g_object_unref (iter->key);
  g_free (iter->value_name);
  g_free (iter->value_data);
  g_free (iter->value_data_expanded);
  g_free (iter->value_name_u8);
  g_free (iter->value_data_u8);
  g_free (iter->value_data_expanded_u8);
  g_free (iter);
}

/**
 * g_win32_registry_value_iter_assign:
 * @iter: a #GWin32RegistryValueIter
 * @other: another #GWin32RegistryValueIter
 *
 * Assigns the value of @other to @iter.  This function
 * is not useful in applications, because iterators can be assigned
 * with `GWin32RegistryValueIter i = j;`. The
 * function is used by language bindings.
 *
 * Since: 2.46
 **/
void
g_win32_registry_value_iter_assign (GWin32RegistryValueIter       *iter,
                                    const GWin32RegistryValueIter *other)
{
  g_return_if_fail (iter != NULL);
  g_return_if_fail (other != NULL);

  *iter = *other;
}

G_DEFINE_BOXED_TYPE (GWin32RegistryValueIter, g_win32_registry_value_iter,
                     g_win32_registry_value_iter_copy,
                     g_win32_registry_value_iter_free)

/**
 * SECTION:gwin32registrykey
 * @title: GWin32RegistryKey
 * @short_description: W32 registry access helper
 * @include: gio/win32/gwin32registrykey.h
 *
 * #GWin32RegistryKey represents a single Windows Registry key.
 *
 * #GWin32RegistryKey is used by a number of helper functions that read
 * Windows Registry. All keys are opened with read-only access, and at
 * the moment there is no API for writing into registry keys or creating
 * new ones.
 *
 * #GWin32RegistryKey implements the #GInitable interface, so if it is manually
 * constructed by e.g. g_object_new() you must call g_initable_init() and check
 * the results before using the object. This is done automatically
 * in g_win32_registry_key_new() and g_win32_registry_key_get_child(), so these
 * functions can return %NULL.
 *
 * To increase efficiency, a UTF-16 variant is available for all functions
 * that deal with key or value names in the registry. Use these to perform
 * deep registry queries or other operations that require querying a name
 * of a key or a value and then opening it (or querying its data). The use
 * of UTF-16 functions avoids the overhead of converting names to UTF-8 and
 * back.
 *
 * All functions operate in current user's context (it is not possible to
 * access registry tree of a different user).
 *
 * Key paths must use '\\' as a separator, '/' is not supported. Key names
 * must not include '\\', because it's used as a separator. Value names
 * can include '\\'.
 *
 * Key and value names are not case sensitive.
 *
 * Full key name (excluding the pre-defined ancestor's name) can't exceed
 * 255 UTF-16 characters, give or take. Value name can't exceed 16383 UTF-16
 * characters. Tree depth is limited to 512 levels.
 **/

struct _GWin32RegistryKeyPrivate {
  /* Ancestor of this key. May not be the immediate parent, because
   * RegOpenKeyEx() allows grand*-children to be opened transitively.
   * May be NULL.
   */
  GWin32RegistryKey *ancestor;

  /* Handle to the key */
  HKEY handle;

  /* Full absolute path of the key, in UTF-16. Always allocated.
   * Can become out of sync if the key is renamed from while we have it
   * open, check watch_indicator to see if anything changed.
   */
  gunichar2 *absolute_path_w;

  /* Full absolute path of the key, in UTF-8. Allocated when needed by
   * converting the UTF-16 value from absolute_path_w. */
  gchar *absolute_path;

  /* TRUE if this object represents one of the pre-defined keys
   * (and thus must not be closed).
   */
  gboolean predefined;

  /* Set to G_WIN32_KEY_UNWATCHED if the key is not being watched.
   * Set to G_WIN32_KEY_WATCHED when the key is put on watch notification.
   */
  gint watch_indicator;

  /* Set to G_WIN32_KEY_UNKNOWN while the key is not being watched.
   * Set to G_WIN32_KEY_UNCHANGED once the key is put under watch.
   * Set to G_WIN32_KEY_CHANGED by the watch notification APC on key change.
   */
  gint change_indicator;

  /* Unset after the key is changed, individual bits are set when their
   * respective key parameters are updated from the registry.
   * This prevents GLib from re-querying things like key name each time
   * one is requested by the client while key is in G_WIN32_KEY_CHANGED state.
   */
  GWin32RegistryKeyUpdateFlag update_flags;

  GWin32RegistryKeyWatchCallbackFunc callback;

  gpointer user_data;
};

static void     g_win32_registry_key_initable_iface_init (GInitableIface  *iface);
static gboolean g_win32_registry_key_initable_init       (GInitable       *initable,
                                                          GCancellable    *cancellable,
                                                          GError         **error);

G_DEFINE_TYPE_WITH_CODE (GWin32RegistryKey, g_win32_registry_key, G_TYPE_OBJECT,
                         G_ADD_PRIVATE (GWin32RegistryKey)
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
                                                g_win32_registry_key_initable_iface_init));

static void
g_win32_registry_key_dispose (GObject *object)
{
  GWin32RegistryKey *key;
  GWin32RegistryKeyPrivate *priv;

  key = G_WIN32_REGISTRY_KEY (object);
  priv = key->priv;

  g_clear_object (&priv->ancestor);
  g_clear_pointer (&priv->absolute_path_w, g_free);
  g_clear_pointer (&priv->absolute_path, g_free);

  if (!priv->predefined && priv->handle != INVALID_HANDLE_VALUE)
    {
      RegCloseKey (priv->handle);
      priv->handle = INVALID_HANDLE_VALUE;
    }

  G_OBJECT_CLASS (g_win32_registry_key_parent_class)->dispose (object);
}

/**
 * g_win32_registry_key_new:
 * @path: absolute full name of a key to open (in UTF-8)
 * @error: (nullable): a pointer to a %NULL #GError, or %NULL
 *
 * Creates an object that represents a registry key specified by @path.
 * @path must start with one of the following pre-defined names:
 * - HKEY_CLASSES_ROOT
 * - HKEY_CURRENT_CONFIG
 * - HKEY_CURRENT_USER
 * - HKEY_CURRENT_USER_LOCAL_SETTINGS
 * - HKEY_LOCAL_MACHINE
 * - HKEY_PERFORMANCE_DATA
 * - HKEY_PERFORMANCE_NLSTEXT
 * - HKEY_PERFORMANCE_TEXT
 * - HKEY_USERS
 * @path must not end with '\\'.
 *
 * Returns: (nullable) (transfer full): a #GWin32RegistryKey or %NULL if can't
 *   be opened. Free with g_object_unref().
 */
GWin32RegistryKey *
g_win32_registry_key_new (const gchar  *path,
                          GError      **error)
{
  g_return_val_if_fail (path != NULL, NULL);

  return g_initable_new (G_TYPE_WIN32_REGISTRY_KEY,
                         NULL,
                         error,
                         "path",
                         path,
                         NULL);
}

/**
 * g_win32_registry_key_new_w:
 * @path: (in) (transfer none): absolute full name of a key to open (in UTF-16)
 * @error: (inout) (optional) (nullable): a pointer to a %NULL #GError, or %NULL
 *
 * Creates an object that represents a registry key specified by @path.
 * @path must start with one of the following pre-defined names:
 * - HKEY_CLASSES_ROOT
 * - HKEY_CURRENT_CONFIG
 * - HKEY_CURRENT_USER
 * - HKEY_CURRENT_USER_LOCAL_SETTINGS
 * - HKEY_LOCAL_MACHINE
 * - HKEY_PERFORMANCE_DATA
 * - HKEY_PERFORMANCE_NLSTEXT
 * - HKEY_PERFORMANCE_TEXT
 * - HKEY_USERS
 * @path must not end with L'\\'.
 *
 * Returns: (nullable) (transfer full): a #GWin32RegistryKey or %NULL if can't
 *   be opened. Free with g_object_unref().
 */
GWin32RegistryKey *
g_win32_registry_key_new_w (const gunichar2  *path,
                            GError          **error)
{
  GObject *result;

  g_return_val_if_fail (path != NULL, NULL);

  result = g_initable_new (G_TYPE_WIN32_REGISTRY_KEY,
                           NULL,
                           error,
                           "path-utf16",
                           g_wcsdup (path, -1),
                           NULL);

  return result ? G_WIN32_REGISTRY_KEY (result) : NULL;
}

static void
g_win32_registry_key_initable_iface_init (GInitableIface *iface)
{
  iface->init = g_win32_registry_key_initable_init;
}

static gboolean
g_win32_registry_key_initable_init (GInitable     *initable,
                                    GCancellable  *cancellable,
                                    GError       **error)
{
  GWin32RegistryKey *key;
  GWin32RegistryKeyPrivate *priv;
  gunichar2 *path;
  gunichar2 *first_chunk_end;
  gsize first_chunk_len;
  gunichar2 *second_chunk_begin;
  gunichar2 *first_chunk;
  HKEY ancestor;
  HKEY key_handle;
  LONG opened;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (initable), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  key = G_WIN32_REGISTRY_KEY (initable);
  priv = key->priv;

  if (priv->absolute_path_w == NULL)
    {
      priv->absolute_path_w = g_utf8_to_utf16 (priv->absolute_path,
                                               -1,
                                               NULL,
                                               NULL,
                                               error);

      if (priv->absolute_path_w == NULL)
        return FALSE;
    }

  path = priv->absolute_path_w;

  first_chunk_end = wcschr (path, L'\\');

  if (first_chunk_end == NULL)
    first_chunk_end = &path[wcslen (path)];

  first_chunk_len = first_chunk_end - path;
  first_chunk = g_wcsdup (path, -1);
  first_chunk[first_chunk_len] = L'\0';
  if (wcscmp (first_chunk, L"HKEY_CLASSES_ROOT") == 0)
    ancestor = HKEY_CLASSES_ROOT;
  else if (wcscmp (first_chunk, L"HKEY_LOCAL_MACHINE") == 0)
    ancestor = HKEY_LOCAL_MACHINE;
  else if (wcscmp (first_chunk, L"HKEY_CURRENT_USER") == 0)
    ancestor = HKEY_CURRENT_USER;
  else if (wcscmp (first_chunk, L"HKEY_CURRENT_CONFIG") == 0)
    ancestor = HKEY_CURRENT_CONFIG;
  else if (wcscmp (first_chunk, L"HKEY_CURRENT_USER_LOCAL_SETTINGS") == 0)
    ancestor = HKEY_CURRENT_USER_LOCAL_SETTINGS;
  else if (wcscmp (first_chunk, L"HKEY_USERS") == 0)
    ancestor = HKEY_USERS;
  else if (wcscmp (first_chunk, L"HKEY_PERFORMANCE_DATA") == 0)
    ancestor = HKEY_PERFORMANCE_DATA;
  else if (wcscmp (first_chunk, L"HKEY_PERFORMANCE_NLSTEXT") == 0)
    ancestor = HKEY_PERFORMANCE_NLSTEXT;
  else if (wcscmp (first_chunk, L"HKEY_PERFORMANCE_TEXT") == 0)
    ancestor = HKEY_PERFORMANCE_TEXT;
  else
    {
      g_critical ("Root key '%S' is not a pre-defined key", first_chunk);
      g_free (first_chunk);
      return FALSE;
    }

  g_free (first_chunk);

  second_chunk_begin = first_chunk_end;

  while (second_chunk_begin[0] != L'\0' && second_chunk_begin[0] == L'\\')
    second_chunk_begin++;

  if (second_chunk_begin != first_chunk_end && second_chunk_begin[0] == L'\0')
    {
      g_critical ("Key name '%S' ends with '\\'", path);
      return FALSE;
    }

  opened = RegOpenKeyExW (ancestor, second_chunk_begin, 0, KEY_READ, &key_handle);

  if (opened != ERROR_SUCCESS)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (opened),
                   "Failed to open registry key '%S'", path);
      return FALSE;
    }

  priv->ancestor = NULL;
  priv->handle = key_handle;
  priv->predefined = (second_chunk_begin[0] == L'\0');

  return TRUE;
}

/**
 * g_win32_registry_key_get_child:
 * @key: (in) (transfer none): a parent #GWin32RegistryKey
 * @subkey: (in) (transfer none): name of a child key to open (in UTF-8), relative to @key
 * @error: (inout) (optional) (nullable): a pointer to a %NULL #GError, or %NULL
 *
 * Opens a @subkey of the @key.
 *
 * Returns: (nullable): a #GWin32RegistryKey or %NULL if can't be opened. Free
 *                      with g_object_unref().
 */
GWin32RegistryKey *
g_win32_registry_key_get_child (GWin32RegistryKey  *key,
                                const gchar        *subkey,
                                GError            **error)
{
  gunichar2 *subkey_w;
  GWin32RegistryKey *result = NULL;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), NULL);
  g_return_val_if_fail (subkey != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  subkey_w = g_utf8_to_utf16 (subkey, -1, NULL, NULL, error);

  if (subkey_w != NULL)
    {
      result = g_win32_registry_key_get_child_w (key, subkey_w, error);
      g_free (subkey_w);
    }

  return result;
}

/**
 * g_win32_registry_key_get_child_w:
 * @key: (in) (transfer none): a parent #GWin32RegistryKey
 * @subkey: (in) (transfer none): name of a child key to open (in UTF-8), relative to @key
 * @error: (inout) (optional) (nullable): a pointer to a %NULL #GError, or %NULL
 *
 * Opens a @subkey of the @key.
 *
 * Returns: (nullable): a #GWin32RegistryKey or %NULL if can't be opened. Free
 *                      with g_object_unref().
 */
GWin32RegistryKey *
g_win32_registry_key_get_child_w (GWin32RegistryKey  *key,
                                  const gunichar2    *subkey,
                                  GError            **error)
{
  HKEY key_handle;
  LONG opened;
  const gunichar2 *end_of_subkey;
  gsize subkey_len;
  GWin32RegistryKey *result;
  const gunichar2 *key_path;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), NULL);
  g_return_val_if_fail (subkey != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  if (subkey[0] == L'\\')
    {
      g_critical ("Subkey name '%S' starts with '\\'", subkey);
      return NULL;
    }

  subkey_len = wcslen (subkey);
  end_of_subkey = &subkey[subkey_len];

  if (subkey_len == 0)
    end_of_subkey = subkey;

  if (end_of_subkey[0] == L'\\')
    {
      g_critical ("Subkey name '%S' ends with '\\'", subkey);
      return NULL;
    }

  key_path = g_win32_registry_key_get_path_w (key);
  opened = RegOpenKeyExW (key->priv->handle, subkey, 0, KEY_READ, &key_handle);

  if (opened != ERROR_SUCCESS)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (opened),
                   "Failed to open registry subkey '%S' of key '%S'",
                   subkey, key_path);
      return NULL;
    }

  result = g_object_new (G_TYPE_WIN32_REGISTRY_KEY, NULL);

  result->priv->handle = key_handle;
  result->priv->absolute_path_w =
      g_malloc ((wcslen (key_path) + 2 + subkey_len) * sizeof (gunichar2));
  result->priv->absolute_path_w[0] = L'\0';
  wcscat (&result->priv->absolute_path_w[0], key_path);
  wcscat (&result->priv->absolute_path_w[wcslen (key_path)], L"\\");
  wcscat (&result->priv->absolute_path_w[wcslen (key_path) + 1], subkey);
  result->priv->predefined = (subkey[0] == L'\0' && key->priv->predefined);

  if (subkey[0] != L'\0')
    result->priv->ancestor = g_object_ref (key);
  else
    result->priv->ancestor = NULL;

  result->priv->change_indicator = G_WIN32_KEY_UNKNOWN;

  return result;
}

/**
 * g_win32_registry_subkey_iter_init:
 * @iter: (in) (transfer none): a pointer to a #GWin32RegistrySubkeyIter
 * @key: (in) (transfer none): a #GWin32RegistryKey to iterate over
 * @error: (inout) (optional) (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Initialises (without allocating) a #GWin32RegistrySubkeyIter.  @iter may be
 * completely uninitialised prior to this call; its old value is
 * ignored.
 *
 * The iterator remains valid for as long as @key exists.
 * Clean up its internal buffers with a call to
 * g_win32_registry_subkey_iter_clear() when done.
 *
 * Returns: %TRUE if iterator was initialized successfully, %FALSE on error.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_subkey_iter_init (GWin32RegistrySubkeyIter  *iter,
                                   GWin32RegistryKey         *key,
                                   GError                   **error)
{
  LONG status;
  DWORD subkey_count;
  DWORD max_subkey_len;

  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  status = RegQueryInfoKeyW (key->priv->handle,
                             NULL, NULL, NULL,
                             &subkey_count, &max_subkey_len,
                             NULL, NULL, NULL, NULL, NULL, NULL);

  if (status != ERROR_SUCCESS)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status),
                   "Failed to query info for registry key '%S'",
                   g_win32_registry_key_get_path_w (key));
      return FALSE;
    }

  iter->key = g_object_ref (key);
  iter->counter = -1;
  iter->subkey_count = subkey_count;
  iter->subkey_name_size = sizeof (gunichar2) * (max_subkey_len + 1);
  iter->subkey_name = g_malloc (iter->subkey_name_size);
  iter->subkey_name_u8 = NULL;

  return TRUE;
}

/**
 * g_win32_registry_subkey_iter_clear:
 * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter
 *
 * Frees internal buffers of a #GWin32RegistrySubkeyIter.
 *
 * Since: 2.46
 **/
void
g_win32_registry_subkey_iter_clear (GWin32RegistrySubkeyIter *iter)
{
  g_return_if_fail (iter != NULL);

  g_free (iter->subkey_name);
  g_free (iter->subkey_name_u8);
  g_clear_object (&iter->key);
}

/**
 * g_win32_registry_subkey_iter_n_subkeys:
 * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter
 *
 * Queries the number of subkeys items in the key that we are
 * iterating over.  This is the total number of subkeys -- not the number
 * of items remaining.
 *
 * This information is accurate at the point of iterator initialization,
 * and may go out of sync with reality even while subkeys are enumerated.
 *
 * Returns: the number of subkeys in the key
 *
 * Since: 2.46
 **/
gsize
g_win32_registry_subkey_iter_n_subkeys (GWin32RegistrySubkeyIter *iter)
{
  g_return_val_if_fail (iter != NULL, 0);

  return iter->subkey_count;
}

/**
 * g_win32_registry_subkey_iter_next:
 * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter
 * @skip_errors: (in): %TRUE if iterator should silently ignore errors (such as
 *     the actual number of subkeys being less than expected) and
 *     proceed forward
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Moves iterator to the next subkey.
 * Enumeration errors can be ignored if @skip_errors is %TRUE
 *
 * Here is an example for iterating with g_win32_registry_subkey_iter_next():
 * |[<!-- language="C" -->
 *   // recursively iterate a key
 *   void
 *   iterate_key_recursive (GWin32RegistryKey *key)
 *   {
 *     GWin32RegistrySubkeyIter iter;
 *     gchar *name;
 *     GWin32RegistryKey *child;
 *
 *     if (!g_win32_registry_subkey_iter_init (&iter, key, NULL))
 *       return;
 *
 *     while (g_win32_registry_subkey_iter_next (&iter, TRUE, NULL))
 *       {
 *         if (!g_win32_registry_subkey_iter_get_name (&iter, &name, NULL, NULL))
 *           continue;
 *
 *         g_print ("subkey '%s'\n", name);
 *         child = g_win32_registry_key_get_child (key, name, NULL);
 *
 *         if (child)
 *           iterate_key_recursive (child);
 *       }
 *
 *     g_win32_registry_subkey_iter_clear (&iter);
 *   }
 * ]|
 *
 * Returns: %TRUE if next subkey info was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_subkey_iter_next (GWin32RegistrySubkeyIter  *iter,
                                   gboolean                   skip_errors,
                                   GError                   **error)
{
  LONG status;
  DWORD subkey_len;

  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->subkey_count)
    {
      g_critical ("g_win32_registry_subkey_iter_get_next_w: must not be called again "
                  "after FALSE has already been returned.");
      return FALSE;
    }

  while (TRUE)
    {
      iter->counter += 1;

      if (iter->counter >= iter->subkey_count)
        return FALSE;

      /* Including 0-terminator */
      subkey_len = iter->subkey_name_size;
      status = RegEnumKeyExW (iter->key->priv->handle,
                              iter->counter,
                              iter->subkey_name,
                              &subkey_len,
                              NULL, NULL, NULL, NULL);

      if (status == ERROR_SUCCESS)
        {
          iter->subkey_name_len = subkey_len;

          return TRUE;
        }

      if (!skip_errors)
        {
          g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status),
                       "Failed to enumerate subkey #%d for key '%S'",
                       iter->counter, g_win32_registry_key_get_path_w (iter->key));
          iter->subkey_count = 0;

          return FALSE;
        }
    }
}

/**
 * g_win32_registry_subkey_iter_get_name_w:
 * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter
 * @subkey_name: (out callee-allocates) (transfer none): Pointer to a location
 *     to store the name of a subkey (in UTF-16).
 * @subkey_name_len: (out) (optional) (transfer none): Pointer to a location
 *     to store the length of @subkey_name, in gunichar2s, excluding
 *     NUL-terminator.
 *     %NULL if length is not needed.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Same as g_win32_registry_subkey_iter_get_next(), but outputs UTF-16-encoded
 * data, without converting it to UTF-8 first.
 *
 * Returns: %TRUE if the name was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_subkey_iter_get_name_w (GWin32RegistrySubkeyIter  *iter,
                                         gunichar2                **subkey_name,
                                         gsize                     *subkey_name_len,
                                         GError                   **error)
{
  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (subkey_name != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->subkey_count)
    {
      g_critical ("g_win32_registry_subkey_iter_get_name_w: must not be called "
                  "after FALSE has already been returned by "
                  "g_win32_registry_subkey_iter_next.");
      return FALSE;
    }

  *subkey_name = iter->subkey_name;

  if (subkey_name_len)
    *subkey_name_len = iter->subkey_name_len;

  return TRUE;
}

/**
 * g_win32_registry_subkey_iter_get_name:
 * @iter: (in) (transfer none): a #GWin32RegistrySubkeyIter
 * @subkey_name: (out callee-allocates) (transfer none): Pointer to a location
 *     to store the name of a subkey (in UTF-8). Free with g_free().
 * @subkey_name_len: (out) (optional): Pointer to a location to store the
 *     length of @subkey_name, in gchars, excluding NUL-terminator.
 *     %NULL if length is not needed.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Gets the name of the subkey at the @iter potision.
 *
 * Returns: %TRUE if the name was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_subkey_iter_get_name (GWin32RegistrySubkeyIter  *iter,
                                       gchar                    **subkey_name,
                                       gsize                     *subkey_name_len,
                                       GError                   **error)
{
  glong subkey_name_len_glong;

  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (subkey_name != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->subkey_count)
    {
      g_critical ("g_win32_registry_subkey_iter_get_name_w: must not be called "
                  "after FALSE has already been returned by "
                  "g_win32_registry_subkey_iter_next.");
      return FALSE;
    }

  g_clear_pointer (&iter->subkey_name_u8, g_free);
  iter->subkey_name_u8 = g_utf16_to_utf8 (iter->subkey_name,
                                          iter->subkey_name_len,
                                          NULL,
                                          &subkey_name_len_glong,
                                          error);

  if (iter->subkey_name_u8 != NULL)
    {
      *subkey_name_len = subkey_name_len_glong;
      return TRUE;
    }

  return FALSE;
}

/**
 * g_win32_registry_value_iter_init:
 * @iter: (in) (transfer none): a pointer to a #GWin32RegistryValueIter
 * @key: (in) (transfer none): a #GWin32RegistryKey to iterate over
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Initialises (without allocating) a #GWin32RegistryValueIter.  @iter may be
 * completely uninitialised prior to this call; its old value is
 * ignored.
 *
 * The iterator remains valid for as long as @key exists.
 * Clean up its internal buffers with a call to
 * g_win32_registry_value_iter_clear() when done.
 *
 * Returns: %TRUE if iterator was initialized successfully, %FALSE on error.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_value_iter_init (GWin32RegistryValueIter  *iter,
                                  GWin32RegistryKey        *key,
                                  GError                  **error)
{
  LONG status;
  DWORD value_count;
  DWORD max_value_len;
  DWORD max_data_len;

  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  status = RegQueryInfoKeyW (key->priv->handle,
                             NULL, NULL, NULL, NULL, NULL, NULL,
                             &value_count, &max_value_len,
                             &max_data_len, NULL, NULL);

  if (status != ERROR_SUCCESS)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status),
                   "Failed to query info for registry key '%S'",
                   g_win32_registry_key_get_path_w (key));
      return FALSE;
    }

  iter->key = g_object_ref (key);
  iter->counter = -1;
  iter->value_count = value_count;
  iter->value_name_size = sizeof (gunichar2) * (max_value_len + 1);
  iter->value_name = g_malloc (iter->value_name_size);
  /* FIXME: max_value_data_len is said to have no size limit in newer W32
   * versions (and its size limit in older ones is 1MB!). Consider limiting it
   * with a hard-coded value, or by allowing the user to choose a limit.
   */
  /* Two extra gunichar2s is for cases when a string was stored in the
   * Registry without a 0-terminator (for multiline strings - 00-terminator),
   * and we need to terminate it ourselves.
   */
  iter->value_data_size = max_data_len + sizeof (gunichar2) * 2;
  iter->value_data = g_malloc (iter->value_data_size);
  iter->value_name_u8 = NULL;
  iter->value_data_u8 = NULL;
  iter->value_data_expanded = NULL;
  iter->value_data_expanded_charsize = 0;
  iter->value_data_expanded_u8 = NULL;
  iter->value_data_expanded_u8_size = 0;
  return TRUE;
}

/**
 * g_win32_registry_value_iter_clear:
 * @iter: (in) (transfer none): a #GWin32RegistryValueIter
 *
 * Frees internal buffers of a #GWin32RegistryValueIter.
 *
 * Since: 2.46
 **/
void
g_win32_registry_value_iter_clear (GWin32RegistryValueIter *iter)
{
  g_return_if_fail (iter != NULL);

  g_free (iter->value_name);
  g_free (iter->value_data);
  g_free (iter->value_name_u8);
  g_free (iter->value_data_u8);
  g_free (iter->value_data_expanded);
  g_free (iter->value_data_expanded_u8);
  g_clear_object (&iter->key);
}

/**
 * g_win32_registry_value_iter_n_values:
 * @iter: (in) (transfer none): a #GWin32RegistryValueIter
 *
 * Queries the number of values items in the key that we are
 * iterating over.  This is the total number of values -- not the number
 * of items remaining.
 *
 * This information is accurate at the point of iterator initialization,
 * and may go out of sync with reality even while values are enumerated.
 *
 * Returns: the number of values in the key
 *
 * Since: 2.46
 **/
gsize
g_win32_registry_value_iter_n_values (GWin32RegistryValueIter *iter)
{
  g_return_val_if_fail (iter != NULL, 0);

  return iter->value_count;
}

static GWin32RegistryValueType
_g_win32_registry_type_w_to_g (DWORD value_type)
{
  switch (value_type)
    {
    case REG_BINARY:
      return G_WIN32_REGISTRY_VALUE_BINARY;
    case REG_DWORD:
      return G_WIN32_REGISTRY_VALUE_UINT32;
#if G_BYTE_ORDER == G_BIG_ENDIAN
    case REG_DWORD_LITTLE_ENDIAN:
      return G_WIN32_REGISTRY_VALUE_UINT32LE;
#else
    case REG_DWORD_BIG_ENDIAN:
      return G_WIN32_REGISTRY_VALUE_UINT32BE;
#endif
    case REG_EXPAND_SZ:
      return G_WIN32_REGISTRY_VALUE_EXPAND_STR;
    case REG_LINK:
      return G_WIN32_REGISTRY_VALUE_LINK;
    case REG_MULTI_SZ:
      return G_WIN32_REGISTRY_VALUE_MULTI_STR;
    case REG_NONE:
      return G_WIN32_REGISTRY_VALUE_NONE;
    case REG_QWORD:
      return G_WIN32_REGISTRY_VALUE_UINT64;
#if G_BYTE_ORDER == G_BIG_ENDIAN
    case REG_QWORD_LITTLE_ENDIAN:
      return G_WIN32_REGISTRY_VALUE_UINT64LE;
#endif
    case REG_SZ:
      return G_WIN32_REGISTRY_VALUE_STR;
    default:
      return G_WIN32_REGISTRY_VALUE_NONE;
    }
}

static gsize
ensure_nul_termination (GWin32RegistryValueType  value_type,
                        guint8                  *value_data,
                        gsize                    value_data_size)
{
  gsize new_size = value_data_size;

  if (value_type == G_WIN32_REGISTRY_VALUE_EXPAND_STR ||
      value_type == G_WIN32_REGISTRY_VALUE_LINK ||
      value_type == G_WIN32_REGISTRY_VALUE_STR)
    {
      if ((value_data_size < 2) ||
          (value_data[value_data_size - 1] != 0) ||
          (value_data[value_data_size - 2] != 0))
        {
          value_data[value_data_size] = 0;
          value_data[value_data_size + 1] = 0;
          new_size += 2;
        }
    }
  else if (value_type == G_WIN32_REGISTRY_VALUE_MULTI_STR)
    {
      if ((value_data_size < 4) ||
          (value_data[value_data_size - 1] != 0) ||
          (value_data[value_data_size - 2] != 0) ||
          (value_data[value_data_size - 3] != 0) ||
          (value_data[value_data_size - 4] != 0))
        {
          value_data[value_data_size] = 0;
          value_data[value_data_size + 1] = 0;
          value_data[value_data_size + 2] = 0;
          value_data[value_data_size + 3] = 0;
          new_size += 4;
        }
    }

  return new_size;
}

/**
 * g_win32_registry_value_iter_next:
 * @iter: (in) (transfer none): a #GWin32RegistryValueIter
 * @skip_errors: (in): %TRUE if iterator should silently ignore errors (such as
 *     the actual number of values being less than expected) and
 *     proceed forward
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Advances iterator to the next value in the key. If no more values remain then
 * FALSE is returned.
 * Enumeration errors can be ignored if @skip_errors is %TRUE
 *
 * Here is an example for iterating with g_win32_registry_value_iter_next():
 * |[<!-- language="C" -->
 *   // iterate values of a key
 *   void
 *   iterate_values_recursive (GWin32RegistryKey *key)
 *   {
 *     GWin32RegistryValueIter iter;
 *     gchar *name;
 *     GWin32RegistryValueType val_type;
 *     gchar *val_data;
 *
 *     if (!g_win32_registry_value_iter_init (&iter, key, NULL))
 *       return;
 *
 *     while (g_win32_registry_value_iter_next (&iter, TRUE, NULL))
 *       {
 *         if ((!g_win32_registry_value_iter_get_value_type (&iter, &value)) ||
 *             ((val_type != G_WIN32_REGISTRY_VALUE_STR) &&
 *              (val_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR)))
 *           continue;
 *
 *         if (g_win32_registry_value_iter_get_value (&iter, TRUE, &name, NULL,
 *                                                    &val_data, NULL, NULL))
 *           g_print ("value '%s' = '%s'\n", name, val_data);
 *       }
 *
 *     g_win32_registry_value_iter_clear (&iter);
 *   }
 * ]|
 *
 * Returns: %TRUE if next value info was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_value_iter_next (GWin32RegistryValueIter  *iter,
                                  gboolean                  skip_errors,
                                  GError                  **error)
{
  LONG status;
  DWORD value_name_len_w;
  DWORD value_data_size_w;
  DWORD value_type_w;
  GWin32RegistryValueType value_type_g;

  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->value_count)
    {
      g_critical ("g_win32_registry_value_iter_next: must not be called "
                  "again after FALSE has already been returned.");
      return FALSE;
    }

  while (TRUE)
    {
      iter->counter += 1;

      if (iter->counter >= iter->value_count)
        return FALSE;

      g_clear_pointer (&iter->value_name_u8, g_free);
      g_clear_pointer (&iter->value_data_u8, g_free);
      g_clear_pointer (&iter->value_data_expanded_u8, g_free);
      /* Including 0-terminator */
      value_name_len_w = iter->value_name_size / sizeof (gunichar2);
      value_data_size_w = iter->value_data_size;
      status = RegEnumValueW (iter->key->priv->handle,
                              iter->counter,
                              iter->value_name,
                              &value_name_len_w,
                              NULL,
                              &value_type_w,
                              (LPBYTE) iter->value_data,
                              &value_data_size_w);

      if (status != ERROR_SUCCESS && !skip_errors)
        {
          g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status),
                       "Failed to enumerate value #%d for key '%S'",
                       iter->counter, g_win32_registry_key_get_path_w (iter->key));
          iter->value_count = 0;

          return FALSE;
        }
      else if (status != ERROR_SUCCESS && skip_errors)
        continue;

      value_type_g = _g_win32_registry_type_w_to_g (value_type_w);
      value_data_size_w = ensure_nul_termination (value_type_g,
                                                  iter->value_data,
                                                  value_data_size_w);
      iter->value_type = value_type_g;
      iter->value_expanded_type = value_type_g;
      iter->value_actual_data_size = value_data_size_w;
      iter->value_name_len = value_name_len_w;

      return TRUE;
    }
}

/**
 * g_win32_registry_value_iter_get_value_type:
 * @iter: (in) (transfer none): a #GWin32RegistryValueIter
 * @value_type: (out): Pointer to a location to store the type of
 *     the value.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Stores the type of the value currently being iterated over in @value_type.
 *
 * Returns: %TRUE if value type was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_value_iter_get_value_type (GWin32RegistryValueIter  *iter,
                                            GWin32RegistryValueType  *value_type,
                                            GError                  **error)
{
  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (value_type != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->value_count)
    {
      g_critical ("g_win32_registry_value_iter_get_type: must not be called "
                  "again after NULL has already been returned.");
      return FALSE;
    }

  *value_type = iter->value_type;

  return TRUE;
}

/**
 * g_win32_registry_value_iter_get_name_w:
 * @iter: (in) (transfer none): a #GWin32RegistryValueIter
 * @value_name: (out callee-allocates) (transfer none): Pointer to a location
 *     to store the name of a value (in UTF-16).
 * @value_name_len: (out) (optional): Pointer to a location to store the length
 *     of @value_name, in gunichar2s, excluding NUL-terminator.
 *     %NULL if length is not needed.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Stores the name of the value currently being iterated over in @value_name,
 * and its length - in @value_name (if not %NULL).
 *
 * Returns: %TRUE if value name was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_value_iter_get_name_w (GWin32RegistryValueIter  *iter,
                                        gunichar2               **value_name,
                                        gsize                    *value_name_len,
                                        GError                  **error)
{
  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (value_name != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->value_count)
    {
      g_critical ("g_win32_registry_value_iter_get_name_w: must not be called "
                  "again after NULL has already been returned.");
      return FALSE;
    }

  *value_name = iter->value_name;

  if (value_name_len)
    *value_name_len = iter->value_name_len;

  return TRUE;
}

/**
 * g_win32_registry_value_iter_get_name:
 * @iter: (in) (transfer none): a #GWin32RegistryValueIter
 * @value_name: (out callee-allocates) (transfer none): Pointer to a location
 *     to store the name of a value (in UTF-8).
 * @value_name_len: (out) (optional): Pointer to a location to store the length
 *     of @value_name, in gchars, excluding NUL-terminator.
 *     %NULL if length is not needed.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Stores the name of the value currently being iterated over in @value_name,
 * and its length - in @value_name_len (if not %NULL).
 *
 * Returns: %TRUE if value name was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_value_iter_get_name (GWin32RegistryValueIter  *iter,
                                      gchar                   **value_name,
                                      gsize                    *value_name_len,
                                      GError                  **error)
{
  glong value_name_len_glong;

  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (value_name != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->value_count)
    {
      g_critical ("g_win32_registry_value_iter_get_name: must not be called "
                  "again after NULL has already been returned.");
      return FALSE;
    }

  if (iter->value_name_u8 == NULL)
    {
      iter->value_name_u8 = g_utf16_to_utf8 (iter->value_name, iter->value_name_len, NULL,
                                             &value_name_len_glong, error);

      if (iter->value_name_u8 == NULL)
        return FALSE;
    }

  *value_name = iter->value_name_u8;

  if (value_name_len)
    *value_name_len = iter->value_name_u8_len;

  return TRUE;
}

static gboolean
expand_value (gunichar2  *value,
              const gunichar2  *value_name,
              gpointer   *expanded_value,
              gsize      *expanded_charsize,
              GError    **error)
{
  DWORD value_data_expanded_charsize_w;

  value_data_expanded_charsize_w =
      ExpandEnvironmentStringsW (value,
                                 (gunichar2 *) *expanded_value,
                                 *expanded_charsize);

  if (value_data_expanded_charsize_w > *expanded_charsize)
    {
      *expanded_value = g_realloc (*expanded_value,
                                   value_data_expanded_charsize_w * sizeof (gunichar2));
      *expanded_charsize = value_data_expanded_charsize_w;
      value_data_expanded_charsize_w =
          ExpandEnvironmentStringsW (value,
                                     (gunichar2 *) *expanded_value,
                                     *expanded_charsize);
    }

  if (value_data_expanded_charsize_w == 0)
    {
      g_set_error (error, G_IO_ERROR,
                   g_io_error_from_win32_error (GetLastError ()),
                   "Failed to expand data '%S' of value %S",
                   value, value_name);
      return FALSE;
    }

  return TRUE;
}

/**
 * g_win32_registry_value_iter_get_data_w:
 * @iter: (in) (transfer none): a #GWin32RegistryValueIter
 * @auto_expand: (in): %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR to
 *     G_WIN32_REGISTRY_VALUE_STR
 * @value_data: (out callee-allocates) (optional) (transfer none): Pointer to a
 *     location to store the data of the value (in UTF-16, if it's a string)
 * @value_data_size: (out) (optional): Pointer to a location to store the size
 *     of @value_data, in bytes (including any NUL-terminators, if it's a string).
 *     %NULL if length is not needed.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Stores the data of the value currently being iterated over in @value_data,
 * and its length - in @value_data_len (if not %NULL).
 *
 * Returns: %TRUE if value data was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_value_iter_get_data_w (GWin32RegistryValueIter  *iter,
                                        gboolean                  auto_expand,
                                        gpointer                 *value_data,
                                        gsize                    *value_data_size,
                                        GError                  **error)
{
  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (value_data != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->value_count)
    {
      g_critical ("g_win32_registry_value_iter_get_data_w: must not be called "
                  "again after FALSE has already been returned.");
      return FALSE;
    }

  if (!auto_expand || (iter->value_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR))
    {
      *value_data = iter->value_data;

      if (value_data_size)
        *value_data_size = iter->value_actual_data_size;

      return TRUE;
    }

  if (iter->value_type == iter->value_expanded_type)
    {
      if (!expand_value ((gunichar2 *) iter->value_data,
                         iter->value_name,
                         (gpointer *) &iter->value_data_expanded,
                         &iter->value_data_expanded_charsize,
                         error))
        return FALSE;

      iter->value_expanded_type = G_WIN32_REGISTRY_VALUE_STR;
    }

  *value_data = iter->value_data_expanded;

  if (value_data_size)
    *value_data_size = iter->value_data_expanded_charsize * sizeof (gunichar2);

  return TRUE;
}

/**
 * g_win32_registry_value_iter_get_data:
 * @iter: (in) (transfer none): a #GWin32RegistryValueIter
 * @auto_expand: (in): %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR to
 *     G_WIN32_REGISTRY_VALUE_STR
 * @value_data: (out callee-allocates) (optional) (transfer none): Pointer to a
 *     location to store the data of the value (in UTF-8, if it's a string)
 * @value_data_size: (out) (optional): Pointer to a location to store the length
 *     of @value_data, in bytes (including any NUL-terminators, if it's a string).
 *     %NULL if length is not needed
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Stores the data of the value currently being iterated over in @value_data,
 * and its length - in @value_data_len (if not %NULL).
 *
 * Returns: %TRUE if value data was retrieved, %FALSE otherwise.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_value_iter_get_data (GWin32RegistryValueIter  *iter,
                                      gboolean                  auto_expand,
                                      gpointer                 *value_data,
                                      gsize                    *value_data_size,
                                      GError                  **error)
{
  gsize value_data_len_gsize;
  gpointer tmp;
  gsize tmp_size;

  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (value_data != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if G_UNLIKELY (iter->counter >= iter->value_count)
    {
      g_critical ("g_win32_registry_value_iter_get_data: must not be called "
                  "again after FALSE has already been returned.");
      return FALSE;
    }

  if (iter->value_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR &&
      iter->value_type != G_WIN32_REGISTRY_VALUE_LINK &&
      iter->value_type != G_WIN32_REGISTRY_VALUE_STR &&
      iter->value_type != G_WIN32_REGISTRY_VALUE_MULTI_STR)
    {
      *value_data = iter->value_data;

      if (value_data_size != NULL)
        *value_data_size = iter->value_actual_data_size;

      return TRUE;
    }

  if (!auto_expand || (iter->value_type != G_WIN32_REGISTRY_VALUE_EXPAND_STR))
    {
      if (iter->value_data_u8 == NULL)
        {
          iter->value_data_u8 = g_convert ((const gchar *) iter->value_data,
                                           iter->value_actual_data_size - sizeof (gunichar2) /* excl. 0 */,
                                           "UTF8", "UTF16", NULL,
                                           &value_data_len_gsize,
                                           error);

          if (iter->value_data_u8 == NULL)
            return FALSE;

          iter->value_data_u8_size = value_data_len_gsize + 1; /* incl. 0 */
        }

      *value_data = iter->value_data_u8;

      if (value_data_size != NULL)
        *value_data_size = iter->value_data_u8_size;

      return TRUE;
    }

  if (iter->value_data_expanded_u8 == NULL)
    {
      if (!g_win32_registry_value_iter_get_data_w (iter,
                                                   TRUE,
                                                   &tmp,
                                                   &tmp_size,
                                                   error))
        return FALSE;

      iter->value_data_expanded_u8 = g_convert ((const gchar *) iter->value_data_expanded,
                                                iter->value_data_expanded_charsize * sizeof (gunichar2) - sizeof (gunichar2) /* excl. 0 */,
                                                "UTF8", "UTF16", NULL,
                                                &value_data_len_gsize,
                                                error);

      if (iter->value_data_expanded_u8 == NULL)
        return FALSE;

      iter->value_data_u8_size = value_data_len_gsize + 1; /* incl. 0 */
    }

  *value_data = iter->value_data_expanded_u8;

  if (value_data_size != NULL)
    *value_data_size = iter->value_data_expanded_u8_size;

  return TRUE;
}

static void
_g_win32_registry_key_reread_kernel (GWin32RegistryKey        *key,
                                     GWin32RegistryKeyPrivate *buf)
{
  NTSTATUS status;
  KEY_BASIC_INFORMATION *basic_info;
  ULONG basic_info_size;
  ULONG datasize;

  basic_info_size = 256 * sizeof (gunichar2) + sizeof (KEY_BASIC_INFORMATION);
  basic_info = g_malloc (basic_info_size + sizeof (gunichar2));
  status = nt_query_key (key->priv->handle,
                         KeyBasicInformation,
                         basic_info,
                         basic_info_size,
                         &datasize);

  if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL)
    {
      g_free (basic_info);
      basic_info_size = datasize;
       /* +1 for 0-terminator */
      basic_info = g_malloc (basic_info_size + sizeof (gunichar2));
      status = nt_query_key (key->priv->handle,
                             KeyBasicInformation,
                             basic_info,
                             basic_info_size,
                             &datasize);
    }

  if (status != STATUS_SUCCESS)
    {
      g_free (basic_info);
      return;
    }

  /* Ensure 0-termination */
  ((char *) basic_info)[datasize] = 0;
  ((char *) basic_info)[datasize + 1] = 0;

  buf->absolute_path_w = g_wcsdup (&basic_info->Name[0],
                                   basic_info->NameLength + sizeof (gunichar2));
  g_free (basic_info);
}

static void
_g_win32_registry_key_reread_user (GWin32RegistryKey        *key,
                                   GWin32RegistryKeyPrivate *buf)
{
  /* Use RegQueryInfoKey(). It's just like NtQueryKey(), but can't query
   * key name.
   * Since right now we only need the name, this function is a noop.
   */
}

static void
_g_win32_registry_key_reread (GWin32RegistryKey        *key,
                              GWin32RegistryKeyPrivate *buf)
{
  if (g_once_init_enter (&nt_query_key))
    {
      NtQueryKeyFunc func;
      HMODULE ntdll = GetModuleHandleW (L"ntdll.dll");

      if (ntdll != NULL)
        func = (NtQueryKeyFunc) GetProcAddress (ntdll, "NtQueryKey");
      else
        func = NULL;

      g_once_init_leave (&nt_query_key, func);
    }

  /* Assume that predefined keys never get renamed. Also, their handles probably
   * won't be accepted by NtQueryKey(), i suspect.
   */
  if (nt_query_key != NULL && !key->priv->predefined)
    _g_win32_registry_key_reread_kernel (key, buf);
  else
    _g_win32_registry_key_reread_user (key, buf);
}

static gboolean
_g_win32_registry_key_update_path (GWin32RegistryKey *key)
{
  GWin32RegistryKeyPrivate tmp;
  gboolean changed;
  gint change_indicator;

  change_indicator = g_atomic_int_get (&key->priv->change_indicator);

  if (change_indicator == G_WIN32_KEY_UNCHANGED)
    return FALSE;

  tmp.absolute_path_w = NULL;
  _g_win32_registry_key_reread (key, &tmp);
  changed = FALSE;

  if (wcscmp (key->priv->absolute_path_w, tmp.absolute_path_w) == 0)
    g_free (tmp.absolute_path_w);
  else
    {
      g_free (key->priv->absolute_path_w);
      key->priv->absolute_path_w = tmp.absolute_path_w;
      changed = TRUE;
    }

  return changed;
}

/**
 * g_win32_registry_key_get_path:
 * @key: (in) (transfer none): a #GWin32RegistryKey
 *
 * Get full path to the key
 *
 * Returns: (transfer none): a full path to the key (in UTF-8),
 *     or %NULL if it can't be converted to UTF-8.
 *
 * Since: 2.46
 **/
const gchar *
g_win32_registry_key_get_path (GWin32RegistryKey *key)
{
  gint change_indicator;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), NULL);

  change_indicator = g_atomic_int_get (&key->priv->change_indicator);

  if (change_indicator == G_WIN32_KEY_CHANGED &&
      !(key->priv->update_flags & G_WIN32_REGISTRY_UPDATED_PATH))
    {
      _g_win32_registry_key_update_path (key);
      key->priv->update_flags |= G_WIN32_REGISTRY_UPDATED_PATH;
    }

  if (key->priv->absolute_path == NULL)
    {
      g_free (key->priv->absolute_path);
      key->priv->absolute_path =
          g_utf16_to_utf8 (key->priv->absolute_path_w, -1,
                           NULL, NULL, NULL);
    }

  return key->priv->absolute_path;
}

/**
 * g_win32_registry_key_get_path_w:
 * @key: (in) (transfer none): a #GWin32RegistryKey
 *
 * Get full path to the key
 *
 * Returns: (transfer none): a full path to the key (in UTF-16)
 *
 * Since: 2.46
 **/
const gunichar2 *
g_win32_registry_key_get_path_w (GWin32RegistryKey *key)
{
  gint change_indicator;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), NULL);

  change_indicator = g_atomic_int_get (&key->priv->change_indicator);

  if (change_indicator == G_WIN32_KEY_CHANGED)
    _g_win32_registry_key_update_path (key);

  return key->priv->absolute_path_w;
}

/**
 * g_win32_registry_get_os_dirs_w:
 *
 * Returns a list of directories for DLL lookups.
 * Can be used with g_win32_registry_key_get_value_w().
 *
 * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of UTF-16 strings.
 *
 * Since: 2.66
 */
const gunichar2 * const *
g_win32_registry_get_os_dirs_w (void)
{
  static gunichar2 **mui_os_dirs = NULL;

  if (g_once_init_enter (&mui_os_dirs))
    {
      gunichar2 **new_mui_os_dirs;
      gunichar2 *system32 = NULL;
      gunichar2 *syswow64 = NULL;
      UINT buffer_size;
      gsize array_index = 0;

      buffer_size = GetSystemWow64DirectoryW (NULL, 0);

      if (buffer_size > 0)
        {
          UINT copied;
          syswow64 = g_malloc (buffer_size * sizeof (gunichar2));
          copied = GetSystemWow64DirectoryW (syswow64, buffer_size);
          if (copied <= 0)
            g_clear_pointer (&syswow64, g_free);
        }

      buffer_size = GetSystemDirectoryW (NULL, 0);

      if (buffer_size > 0)
        {
          UINT copied;
          system32 = g_malloc (buffer_size * sizeof (gunichar2));
          copied = GetSystemDirectoryW (system32, buffer_size);
          if (copied <= 0)
            g_clear_pointer (&system32, g_free);
        }

      new_mui_os_dirs = g_new0 (gunichar2 *, 3);

      if (system32 != NULL)
        new_mui_os_dirs[array_index++] = system32;

      if (syswow64 != NULL)
        new_mui_os_dirs[array_index++] = syswow64;

      new_mui_os_dirs[array_index++] = NULL;

      g_once_init_leave (&mui_os_dirs, new_mui_os_dirs);
    }

  return (const gunichar2 * const *) mui_os_dirs;
}

/**
 * g_win32_registry_get_os_dirs:
 *
 * Returns a list of directories for DLL lookups.
 * Can be used with g_win32_registry_key_get_value().
 *
 * Returns: (array zero-terminated=1) (transfer none): a %NULL-terminated array of UTF-8 strings.
 *
 * Since: 2.66
 */
const gchar * const *
g_win32_registry_get_os_dirs (void)
{
  static gchar **mui_os_dirs = NULL;

  if (g_once_init_enter (&mui_os_dirs))
    {
      gchar **new_mui_os_dirs;
      gsize array_index;
      gsize new_array_index;
      const gunichar2 * const *mui_os_dirs_utf16 = g_win32_registry_get_os_dirs_w ();

      for (array_index = 0; mui_os_dirs_utf16[array_index] != NULL; array_index++)
        ;

      new_mui_os_dirs = g_new0 (gchar *, array_index + 1);

      for (array_index = 0, new_array_index = 0;
           mui_os_dirs_utf16[array_index] != NULL;
           array_index++)
        {
          new_mui_os_dirs[new_array_index] = g_utf16_to_utf8 (mui_os_dirs_utf16[array_index],
                                                              -1, NULL, NULL, NULL);
          if (new_mui_os_dirs[new_array_index] != NULL)
            new_array_index += 1;
          else
            g_critical ("Failed to convert to a system directory #%zu to UTF-8", array_index);
        }

      g_once_init_leave (&mui_os_dirs, new_mui_os_dirs);
    }

  return (const gchar * const *) mui_os_dirs;
}

/**
 * g_win32_registry_key_get_value:
 * @key: (in) (transfer none): a #GWin32RegistryKey
 * @mui_dll_dirs: (in) (transfer none) (array zero-terminated=1) (optional): a %NULL-terminated
 *     array of directory names where the OS
 *     should look for a DLL indicated in a MUI string, if the
 *     DLL path in the string is not absolute
 * @auto_expand: (in) %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR
 *     to G_WIN32_REGISTRY_VALUE_STR.
 * @value_name: (in) (transfer none): name of the value to get (in UTF-8).
 *   Empty string means the '(Default)' value.
 * @value_type: (out) (optional): type of the value retrieved.
 * @value_data: (out callee-allocates) (optional): contents of the value.
 * @value_data_size: (out) (optional): size of the buffer pointed
 *   by @value_data.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Get data from a value of a key. String data is guaranteed to be
 * appropriately terminated and will be in UTF-8.
 *
 * When not %NULL, @mui_dll_dirs indicates that `RegLoadMUIStringW()` API
 * should be used instead of the usual `RegQueryValueExW()`. This implies
 * that the value being queried is of type `REG_SZ` or `REG_EXPAND_SZ` (if it is not, the function
 * falls back to `RegQueryValueExW()`), and that this string must undergo special processing
 * (see [`SHLoadIndirectString()` documentation](https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring) for an explanation on what
 * kinds of strings are processed) to get the result.
 *
 * If no specific MUI DLL directories need to be used, pass
 * the return value of g_win32_registry_get_os_dirs() as @mui_dll_dirs
 * (as an bonus, the value from g_win32_registry_get_os_dirs()
 * does not add any extra UTF8->UTF16 conversion overhead).
 *
 * @auto_expand works with @mui_dll_dirs, but only affects the processed
 * string, making it somewhat useless. The unprocessed string is always expanded
 * internally, if its type is `REG_EXPAND_SZ` - there is no need to enable
 * @auto_expand for this to work.
 *
 * The API for this function changed in GLib 2.66 to add the @mui_dll_dirs argument.
 *
 * Returns: %TRUE on success, %FALSE on failure.
 *
 * Since: 2.66
 **/
gboolean
g_win32_registry_key_get_value (GWin32RegistryKey        *key,
                                const gchar * const      *mui_dll_dirs,
                                gboolean                  auto_expand,
                                const gchar              *value_name,
                                GWin32RegistryValueType  *value_type,
                                gpointer                 *value_data,
                                gsize                    *value_data_size,
                                GError                  **error)
{
  GWin32RegistryValueType value_type_g;
  gpointer value_data_w;
  gsize value_data_w_size;
  gunichar2 *value_name_w;
  gchar *value_data_u8;
  gsize value_data_u8_len;
  gboolean result;
  gsize mui_dll_dirs_count;
  gunichar2 **mui_dll_dirs_utf16;
  const gchar * const *mui_os_dirs;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE);
  g_return_val_if_fail (value_name != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  /* No sense calling this function with all of these set to NULL */
  g_return_val_if_fail (value_type != NULL ||
                        value_data != NULL ||
                        value_data_size != NULL, FALSE);

  value_name_w = g_utf8_to_utf16 (value_name, -1, NULL, NULL, error);

  if (value_name_w == NULL)
    return FALSE;

  mui_dll_dirs_utf16 = NULL;
  mui_os_dirs = g_win32_registry_get_os_dirs ();

  if (mui_dll_dirs != NULL &&
      mui_dll_dirs != mui_os_dirs)
    {
      gsize i;

      mui_dll_dirs_count = g_strv_length ((gchar **) mui_dll_dirs);
      mui_dll_dirs_utf16 = g_new0 (gunichar2 *, mui_dll_dirs_count + 1);

      for (i = 0; mui_dll_dirs[i] != NULL; i++)
        {
          mui_dll_dirs_utf16[i] = g_utf8_to_utf16 (mui_dll_dirs[i], -1, NULL, NULL, error);

          if (mui_dll_dirs_utf16[i] == NULL)
            break;
        }

      if (mui_dll_dirs[i] != NULL)
        {
          g_prefix_error (error,
                          "A mui_dll_dirs string #%zu `%s' failed to convert: ",
                          i, mui_dll_dirs[i]);

          for (i = 0; i < mui_dll_dirs_count; i++)
            g_free (mui_dll_dirs_utf16[i]);

          g_free (mui_dll_dirs_utf16);
          g_free (value_name_w);

          return FALSE;
        }
    }
  else if (mui_dll_dirs != NULL &&
           mui_dll_dirs == mui_os_dirs)
    {
      mui_dll_dirs_utf16 = (gunichar2 **) g_win32_registry_get_os_dirs_w ();
    }

  result = g_win32_registry_key_get_value_w (key,
                                             (const gunichar2 * const *) mui_dll_dirs_utf16,
                                             auto_expand,
                                             value_name_w,
                                             &value_type_g,
                                             &value_data_w,
                                             &value_data_w_size,
                                             error);

  g_free (value_name_w);
  if (mui_dll_dirs_utf16 != NULL &&
      mui_dll_dirs != mui_os_dirs)
    {
      gsize array_index;
      for (array_index = 0; mui_dll_dirs_utf16[array_index] != NULL; array_index++)
        g_free (mui_dll_dirs_utf16[array_index]);
      g_free (mui_dll_dirs_utf16);
    }

  if (!result)
    return FALSE;

  if (value_type_g == G_WIN32_REGISTRY_VALUE_EXPAND_STR ||
      value_type_g == G_WIN32_REGISTRY_VALUE_LINK ||
      value_type_g == G_WIN32_REGISTRY_VALUE_STR ||
      value_type_g == G_WIN32_REGISTRY_VALUE_MULTI_STR)
    {
      value_data_u8 = g_convert ((const gchar *) value_data_w,
                                 value_data_w_size - sizeof (gunichar2) /* excl. 0 */,
                                 "UTF8",
                                 "UTF16",
                                 NULL,
                                 &value_data_u8_len,
                                 error);
      g_free (value_data_w);

      if (value_data_u8 == NULL)
        return FALSE;

      if (value_data)
        *value_data = value_data_u8;
      else
        g_free (value_data_u8);

      if (value_data_size)
        *value_data_size = value_data_u8_len + 1;
    }
  else
    {
      if (value_data)
        *value_data = value_data_w;
      else
        g_free (value_data_w);

      if (value_data_size)
        *value_data_size = value_data_w_size;
    }

  if (value_type)
    *value_type = value_type_g;

  return TRUE;
}

/* A wrapper that calls either RegQueryValueExW() or
 * RegLoadMUIStringW() depending on the value of the
 * last argument.
 * Apart from the extra argument, the function behaves
 * just like RegQueryValueExW(), with a few caveats.
 */
static LSTATUS
MuiRegQueryValueExW (HKEY                     hKey,
                     LPCWSTR                  lpValueName,
                     LPDWORD                  lpReserved,
                     LPDWORD                  lpType,
                     LPBYTE                   lpData,
                     LPDWORD                  lpcbData,
                     const gunichar2 * const *mui_dll_dirs)
{
  gsize dir_index;
  LSTATUS result = ERROR_PATH_NOT_FOUND;
  DWORD bufsize;
  DWORD data_size;
  PVOID old_value;

  if (mui_dll_dirs == NULL)
    return RegQueryValueExW (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);

  bufsize = 0;

  if (lpcbData != NULL)
    bufsize = *lpcbData;

  if (mui_dll_dirs[0] != NULL)
    {
      /* Optimization: check that the value actually exists,
       * before we start trying different mui dll dirs
       */
      result = RegQueryValueExW (hKey, lpValueName, NULL, NULL, NULL, 0);

      if (result == ERROR_FILE_NOT_FOUND)
        return result;
    }

  Wow64DisableWow64FsRedirection (&old_value);

  /* Try with NULL dir first */
  result = RegLoadMUIStringW (hKey,
                              lpValueName,
                              (wchar_t *) lpData,
                              bufsize,
                              &data_size,
                              0,
                              NULL);

  /* Not a MUI value, load normally */
  if (result == ERROR_INVALID_DATA)
    {
      Wow64RevertWow64FsRedirection (old_value);

      return RegQueryValueExW (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
    }

  for (dir_index = 0;
       result == ERROR_FILE_NOT_FOUND &&
       mui_dll_dirs[dir_index] != NULL;
       dir_index++)
    result = RegLoadMUIStringW (hKey,
                                lpValueName,
                                (wchar_t *) lpData,
                                bufsize,
                                &data_size,
                                0,
                                mui_dll_dirs[dir_index]);

  Wow64RevertWow64FsRedirection (old_value);

  if (lpcbData != NULL &&
      result == ERROR_MORE_DATA)
    *lpcbData = data_size;

  if (lpType != NULL &&
      result != ERROR_INVALID_DATA &&
      result != ERROR_FILE_NOT_FOUND)
    *lpType = REG_SZ;

  return result;
}

/**
 * g_win32_registry_key_get_value_w:
 * @key: (in) (transfer none): a #GWin32RegistryKey
 * @mui_dll_dirs: (in) (transfer none) (array zero-terminated=1) (optional): a %NULL-terminated
 *     array of directory names where the OS
 *     should look for a DLL indicated in a MUI string, if the
 *     DLL path in the string is not absolute
 * @auto_expand: (in) %TRUE to automatically expand G_WIN32_REGISTRY_VALUE_EXPAND_STR
 *     to G_WIN32_REGISTRY_VALUE_STR.
 * @value_name: (in) (transfer none): name of the value to get (in UTF-16).
 *   Empty string means the '(Default)' value.
 * @value_type: (out) (optional): type of the value retrieved.
 * @value_data: (out callee-allocates) (optional): contents of the value.
 * @value_data_size: (out) (optional): size of the buffer pointed
 *   by @value_data.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Get data from a value of a key. String data is guaranteed to be
 * appropriately terminated and will be in UTF-16.
 *
 * When calling with value_data == NULL (to get data size without getting
 * the data itself) remember that returned size corresponds to possibly
 * unterminated string data (if value is some kind of string), because
 * termination cannot be checked and fixed unless the data is retrieved
 * too.
 *
 * When not %NULL, @mui_dll_dirs indicates that `RegLoadMUIStringW()` API
 * should be used instead of the usual `RegQueryValueExW()`. This implies
 * that the value being queried is of type `REG_SZ` or `REG_EXPAND_SZ` (if it is not, the function
 * falls back to `RegQueryValueExW()`), and that this string must undergo special processing
 * (see [`SHLoadIndirectString()` documentation](https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring) for an explanation on what
 * kinds of strings are processed) to get the result.
 *
 * If no specific MUI DLL directories need to be used, pass
 * the return value of g_win32_registry_get_os_dirs_w() as @mui_dll_dirs.
 *
 * @auto_expand works with @mui_dll_dirs, but only affects the processed
 * string, making it somewhat useless. The unprocessed string is always expanded
 * internally, if its type is `REG_EXPAND_SZ` - there is no need to enable
 * @auto_expand for this to work.
 *
 * The API for this function changed in GLib 2.66 to add the @mui_dll_dirs argument.
 *
 * Returns: %TRUE on success, %FALSE on failure.
 *
 * Since: 2.66
 **/
gboolean
g_win32_registry_key_get_value_w (GWin32RegistryKey        *key,
                                  const gunichar2 * const  *mui_dll_dirs,
                                  gboolean                  auto_expand,
                                  const gunichar2          *value_name,
                                  GWin32RegistryValueType  *value_type,
                                  gpointer                 *value_data,
                                  gsize                    *value_data_size,
                                  GError                  **error)
{
  LONG status;
  DWORD value_type_w;
  DWORD value_type_w2;
  char *req_value_data;
  GWin32RegistryValueType value_type_g;
  GWin32RegistryValueType value_type_g2;
  DWORD req_value_data_size;
  DWORD req_value_data_size2;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE);
  g_return_val_if_fail (value_name != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  /* No sense calling this functions with all of these set to NULL */
  g_return_val_if_fail (value_type != NULL ||
                        value_data != NULL ||
                        value_data_size != NULL, FALSE);

  req_value_data_size = 0;
  status = MuiRegQueryValueExW (key->priv->handle,
                                value_name,
                                NULL,
                                &value_type_w,
                                NULL,
                                &req_value_data_size,
                                mui_dll_dirs);

  if (status != ERROR_MORE_DATA && status != ERROR_SUCCESS)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status),
                   "Failed to query value '%S' for key '%S'",
                   value_name, g_win32_registry_key_get_path_w (key));

      return FALSE;
    }

  value_type_g = _g_win32_registry_type_w_to_g (value_type_w);

  if (value_data == NULL &&
      (!auto_expand || value_type_g != G_WIN32_REGISTRY_VALUE_EXPAND_STR))
    {
      if (value_type)
        *value_type = value_type_g;

      if (value_data_size)
        *value_data_size = req_value_data_size;

      return TRUE;
    }

  req_value_data = g_malloc (req_value_data_size + sizeof (gunichar2) * 2);
  req_value_data_size2 = req_value_data_size;
  status = MuiRegQueryValueExW (key->priv->handle,
                                value_name,
                                NULL,
                                &value_type_w2,
                                (gpointer) req_value_data,
                                &req_value_data_size2,
                                mui_dll_dirs);

  if (status != ERROR_SUCCESS)
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_win32_error (status),
                   "Failed to query value '%S' of size %lu for key '%S'",
                   value_name,
                   req_value_data_size,
                   g_win32_registry_key_get_path_w (key));
      g_free (req_value_data);
      return FALSE;
    }

  value_type_g2 = _g_win32_registry_type_w_to_g (value_type_w2);

  if (value_type_w != value_type_w2)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Type of value '%S' of key '%S' changed from %u to %u"
                   " between calls",
                   value_name,
                   g_win32_registry_key_get_path_w (key),
                   value_type_g, value_type_g2);
      g_free (req_value_data);
      return FALSE;
    }

  req_value_data_size = ensure_nul_termination (value_type_g,
                                                (guint8 *) req_value_data,
                                                req_value_data_size2);

  if (value_type_g == G_WIN32_REGISTRY_VALUE_EXPAND_STR && auto_expand)
    {
      gsize value_data_expanded_charsize_w = 0;
      gunichar2 *value_data_expanded = NULL;

      if (!expand_value ((gunichar2 *) req_value_data,
                         value_name,
                         (gpointer *) &value_data_expanded,
                         &value_data_expanded_charsize_w,
                         error))
        return FALSE;

      g_free (req_value_data);

      if (value_type)
        *value_type = G_WIN32_REGISTRY_VALUE_STR;

      if (value_data)
        *value_data = value_data_expanded;
      else
        g_free (value_data_expanded);

      if (value_data_size)
        *value_data_size = value_data_expanded_charsize_w * sizeof (gunichar2);

      return TRUE;
    }

  if (value_type)
    *value_type = value_type_g;

  if (value_data_size)
    *value_data_size = req_value_data_size;

  if (value_data)
    *value_data = req_value_data;
  else
    g_free (req_value_data);

  return TRUE;
}

static VOID NTAPI
key_changed (PVOID            closure,
             PIO_STATUS_BLOCK status_block,
             ULONG            reserved)
{
  GWin32RegistryKey *key = G_WIN32_REGISTRY_KEY (closure);

  g_free (status_block);
  g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_CHANGED);
  g_atomic_int_set (&key->priv->watch_indicator, G_WIN32_KEY_UNWATCHED);
  key->priv->update_flags = G_WIN32_REGISTRY_UPDATED_NOTHING;

  if (key->priv->callback)
    key->priv->callback (key, key->priv->user_data);

  key->priv->callback = NULL;
  key->priv->user_data = NULL;
  g_object_unref (key);
}

/**
 * g_win32_registry_key_watch:
 * @key: (in) (transfer none): a #GWin32RegistryKey
 * @watch_children: (in) %TRUE also watch the children of the @key, %FALSE
 *     to watch the key only.
 * @watch_flags: (in): specifies the types of changes to watch for.
 * @callback: (in) (nullable): a function to invoke when a change occurs.
 * @user_data: (in) (nullable): a pointer to pass to @callback on invocation.
 * @error: (nullable): a pointer to %NULL #GError, or %NULL
 *
 * Puts @key under a watch.
 *
 * When the key changes, an APC will be queued in the current thread. The APC
 * will run when the current thread enters alertable state (GLib main loop
 * should do that; if you are not using it, see MSDN documentation for W32API
 * calls that put thread into alertable state). When it runs, it will
 * atomically switch an indicator in the @key. If a callback was specified,
 * it is invoked at that point. Subsequent calls to
 * g_win32_registry_key_has_changed() will return %TRUE, and the callback (if
 * it was specified) will not be invoked anymore.
 * Calling g_win32_registry_key_erase_change_indicator() will reset the indicator,
 * and g_win32_registry_key_has_changed() will start returning %FALSE.
 * To resume the watch, call g_win32_registry_key_watch_for_changes() again.
 *
 * Calling g_win32_registry_key_watch_for_changes() for a key that is already
 * being watched is allowed and affects nothing.
 *
 * The fact that the key is being watched will be used internally to update
 * key path (if it changes).
 *
 * Returns: %TRUE on success, %FALSE on failure.
 *
 * Since: 2.46
 **/
gboolean
g_win32_registry_key_watch (GWin32RegistryKey                   *key,
                            gboolean                             watch_children,
                            GWin32RegistryKeyWatcherFlags        watch_flags,
                            GWin32RegistryKeyWatchCallbackFunc   callback,
                            gpointer                             user_data,
                            GError                             **error)
{
  ULONG filter;
  gboolean started_to_watch;
  NTSTATUS status;
  PIO_STATUS_BLOCK status_block;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE);

  filter = ((watch_flags & G_WIN32_REGISTRY_WATCH_NAME)       ? REG_NOTIFY_CHANGE_NAME       : 0) |
           ((watch_flags & G_WIN32_REGISTRY_WATCH_ATTRIBUTES) ? REG_NOTIFY_CHANGE_ATTRIBUTES : 0) |
           ((watch_flags & G_WIN32_REGISTRY_WATCH_VALUES)     ? REG_NOTIFY_CHANGE_LAST_SET   : 0) |
           ((watch_flags & G_WIN32_REGISTRY_WATCH_SECURITY)   ? REG_NOTIFY_CHANGE_SECURITY   : 0);

  if (filter == 0)
    {
      g_critical ("No supported flags specified in watch_flags (%x)", (guint) watch_flags);
      return FALSE;
    }

  if (g_once_init_enter (&nt_notify_change_multiple_keys))
  {
    NtNotifyChangeMultipleKeysFunc func;
    HMODULE ntdll = GetModuleHandle ("ntdll.dll");

    if (ntdll != NULL)
      func = (NtNotifyChangeMultipleKeysFunc) GetProcAddress (ntdll, "NtNotifyChangeMultipleKeys");
    else
      func = NULL;

    g_once_init_leave (&nt_notify_change_multiple_keys, func);
  }

  if (nt_notify_change_multiple_keys== NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                   "Couldn't get NtNotifyChangeMultipleKeys() from ntdll");
      return FALSE;
    }

  started_to_watch =
      g_atomic_int_compare_and_exchange (&key->priv->watch_indicator,
                                         G_WIN32_KEY_UNWATCHED,
                                         G_WIN32_KEY_WATCHED);

  if (!started_to_watch)
    return TRUE;

  key->priv->callback = callback;
  key->priv->user_data = user_data;

  g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_UNCHANGED);

  /* Keep it alive until APC is called */
  g_object_ref (key);

  status_block = g_malloc (sizeof (IO_STATUS_BLOCK));

  status = nt_notify_change_multiple_keys (key->priv->handle,
                                           0,
                                           NULL,
                                           NULL,
                                           key_changed,
                                           (PVOID) key,
                                           status_block,
                                           filter,
                                           watch_children,
                                           NULL,
                                           0,
                                           TRUE);

  g_assert (status != STATUS_SUCCESS);

  if (status == STATUS_PENDING)
    return TRUE;

  g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_UNKNOWN);
  g_atomic_int_set (&key->priv->watch_indicator, G_WIN32_KEY_UNWATCHED);
  g_object_unref (key);
  g_free (status_block);

  return FALSE;
}

/**
 * g_win32_registry_key_erase_change_indicator:
 * @key: (in) (transfer none): a #GWin32RegistryKey
 *
 * Erases change indicator of the @key.
 *
 * Subsequent calls to g_win32_registry_key_has_changed() will return %FALSE
 * until the key is put on watch again by calling
 * g_win32_registry_key_watch() again.
 *
 * Since: 2.46
 */
void
g_win32_registry_key_erase_change_indicator (GWin32RegistryKey *key)
{
  g_return_if_fail (G_IS_WIN32_REGISTRY_KEY (key));

  g_atomic_int_set (&key->priv->change_indicator, G_WIN32_KEY_UNKNOWN);
}

/**
 * g_win32_registry_key_has_changed:
 * @key: (in) (transfer none): a #GWin32RegistryKey
 *
 * Check the @key's status indicator.
 *
 * Returns: %TRUE if the @key was put under watch at some point and has changed
 * since then, %FALSE if it either wasn't changed or wasn't watched at all.
 *
 * Since: 2.46
 */
gboolean
g_win32_registry_key_has_changed (GWin32RegistryKey *key)
{
  gint changed;

  g_return_val_if_fail (G_IS_WIN32_REGISTRY_KEY (key), FALSE);

  changed = g_atomic_int_get (&key->priv->change_indicator);

  return (changed == G_WIN32_KEY_CHANGED ? TRUE : FALSE);
}

static void
g_win32_registry_key_get_property (GObject    *object,
                                   guint       prop_id,
                                   GValue     *value,
                                   GParamSpec *pspec)
{
  GWin32RegistryKey *key = G_WIN32_REGISTRY_KEY (object);

  switch (prop_id)
    {
      case PROP_PATH:
        g_value_set_string (value, g_win32_registry_key_get_path (key));
        break;

      case PROP_PATH_UTF16:
        g_value_set_pointer (value, (gpointer) g_win32_registry_key_get_path_w (key));
        break;

      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
g_win32_registry_key_set_property (GObject      *object,
                                   guint         prop_id,
                                   const GValue *value,
                                   GParamSpec   *pspec)
{
  GWin32RegistryKey *key = G_WIN32_REGISTRY_KEY (object);
  GWin32RegistryKeyPrivate *priv = key->priv;
  const gchar *path;
  gunichar2 *path_w;

  switch (prop_id)
    {
    case PROP_PATH:
      path = g_value_get_string (value);

      if (path == NULL)
        break;

      path_w = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL);

      if (path_w == NULL)
        break;

      /* Construct only */
      g_assert (priv->absolute_path_w == NULL);
      g_assert (priv->absolute_path == NULL);
      priv->absolute_path_w = path_w;
      priv->absolute_path = g_value_dup_string (value);
      break;

    case PROP_PATH_UTF16:
      path_w = (gunichar2 *) g_value_get_pointer (value);

      if (path_w == NULL)
        break;

      /* Construct only */
      g_assert (priv->absolute_path_w == NULL);
      priv->absolute_path_w = g_wcsdup (path_w, -1);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
g_win32_registry_key_class_init (GWin32RegistryKeyClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->dispose = g_win32_registry_key_dispose;
  gobject_class->set_property = g_win32_registry_key_set_property;
  gobject_class->get_property = g_win32_registry_key_get_property;

  /**
   * GWin32RegistryKey:path:
   *
   * A path to the key in the registry, in UTF-8.
   *
   * Since: 2.46
   */
  g_object_class_install_property (gobject_class,
                                   PROP_PATH,
                                   g_param_spec_string ("path",
                                                        "Path",
                                                        "Path to the key in the registry",
                                                        NULL,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GWin32RegistryKey:path-utf16:
   *
   * A path to the key in the registry, in UTF-16.
   *
   * Since: 2.46
   */
  g_object_class_install_property (gobject_class,
                                   PROP_PATH_UTF16,
                                   g_param_spec_pointer ("path-utf16",
                                                        "Path (UTF-16)",
                                                        "Path to the key in the registry, in UTF-16",
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY |
                                                        G_PARAM_STATIC_STRINGS));
}

static void
g_win32_registry_key_init (GWin32RegistryKey *key)
{
  key->priv = g_win32_registry_key_get_instance_private (key);
  key->priv->change_indicator = G_WIN32_KEY_UNKNOWN;
}
