/**
    This library provides Win32 Registry facilities.

    Copyright: Copyright 2003-2004 by Matthew Wilson and Synesis Software
               Written by Matthew Wilson

    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).

    Author:    Matthew Wilson, Kenji Hara

    History:
        Created      15th March 2003,
        Updated      25th April 2004,

    Source:    $(PHOBOSSRC std/windows/_registry.d)
*/
/* /////////////////////////////////////////////////////////////////////////////
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, in both source and binary form, subject to the following
 * restrictions:
 *
 * -  The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * -  Altered source versions must be plainly marked as such, and must not
 *    be misrepresented as being the original software.
 * -  This notice may not be removed or altered from any source
 *    distribution.
 *
 * ////////////////////////////////////////////////////////////////////////// */
module std.windows.registry;
version (Windows):

import core.sys.windows.windows;
import std.array;
import std.conv;
import std.exception;
import std.internal.cstring;
import std.internal.windows.advapi32;
import std.system : Endian, endian;
import std.windows.syserror;

//debug = winreg;
debug(winreg) import std.stdio;

private
{
    import core.sys.windows.winbase : lstrlenW;

    void enforceSucc(LONG res, lazy string message, string fn = __FILE__, size_t ln = __LINE__)
    {
        if (res != ERROR_SUCCESS)
            throw new RegistryException(message, res, fn, ln);
    }
}

/* ************* Exceptions *************** */

// Do not use. Left for compatibility.
class Win32Exception : WindowsException
{
    @safe
    this(string message, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)
    {
        super(0, message, fn, ln);
    }

    @safe
    this(string message, int errnum, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)
    {
        super(errnum, message, fn, ln);
    }

    @property int error() { return super.code; }
}

version (unittest) import std.string : startsWith, endsWith;

@safe unittest
{
    // Test that we can throw and catch one by its own type
    string message = "Test W1";

    auto e = collectException!Win32Exception(
        enforce(false, new Win32Exception(message)));
    assert(e.msg.startsWith(message));
}

@system unittest
{
    // ditto
    string message = "Test W2";
    int    code    = 5;

    auto e = collectException!Win32Exception(
        enforce(false, new Win32Exception(message, code)));
    assert(e.error == code);
    assert(e.msg.startsWith(message));
}

/**
    Exception class thrown by the std.windows.registry classes.
 */
class RegistryException
    : Win32Exception
{
public:
    /**
        Creates an instance of the exception.

        Params:
            message = The message associated with the exception.
     */
    @safe
    this(string message, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)
    {
        super(message, fn, ln, next);
    }

    /**
        Creates an instance of the exception, with the given.

        Params:
            message = The message associated with the exception.
            error = The Win32 error number associated with the exception.
     */
    @safe
    this(string message, int error, string fn = __FILE__, size_t ln = __LINE__, Throwable next = null)
    {
        super(message, error, fn, ln, next);
    }
}

@system unittest
{
    // (i) Test that we can throw and catch one by its own type
    string message = "Test 1";
    int    code    = 3;

    auto e = collectException!RegistryException(
        enforce(false, new RegistryException(message, code)));
    assert(e.error == code);
    assert(e.msg.startsWith(message));
}

@safe unittest
{
    // ditto
    string message = "Test 2";

    auto e = collectException!RegistryException(
        enforce(false, new RegistryException(message)));
    assert(e.msg.startsWith(message));
}

/* ************* public enumerations *************** */

/**
    Enumeration of the recognised registry access modes.
 */
enum REGSAM
{
    KEY_QUERY_VALUE         = 0x0001,   /// Permission to query subkey data
    KEY_SET_VALUE           = 0x0002,   /// Permission to set subkey data
    KEY_CREATE_SUB_KEY      = 0x0004,   /// Permission to create subkeys
    KEY_ENUMERATE_SUB_KEYS  = 0x0008,   /// Permission to enumerate subkeys
    KEY_NOTIFY              = 0x0010,   /// Permission for change notification
    KEY_CREATE_LINK         = 0x0020,   /// Permission to create a symbolic link
    KEY_WOW64_32KEY         = 0x0200,   /// Enables a 64- or 32-bit application to open a 32-bit key
    KEY_WOW64_64KEY         = 0x0100,   /// Enables a 64- or 32-bit application to open a 64-bit key
    KEY_WOW64_RES           = 0x0300,   ///
    KEY_READ                = (STANDARD_RIGHTS_READ
                               | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY)
                              & ~(SYNCHRONIZE),
                                        /// Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE,
                                        /// KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access rights
    KEY_WRITE               = (STANDARD_RIGHTS_WRITE
                               | KEY_SET_VALUE | KEY_CREATE_SUB_KEY)
                              & ~(SYNCHRONIZE),
                                        /// Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE,
                                        /// and KEY_CREATE_SUB_KEY access rights
    KEY_EXECUTE             = KEY_READ & ~(SYNCHRONIZE),
                                        /// Permission for read access
    KEY_ALL_ACCESS          = (STANDARD_RIGHTS_ALL
                               | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY
                               | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK)
                              & ~(SYNCHRONIZE),
                                        /// Combines the KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS,
                                        /// KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and
                                        /// KEY_SET_VALUE access rights, plus all the standard
                                        /// access rights except SYNCHRONIZE
}

/**
    Enumeration of the recognised registry value types.
 */
enum REG_VALUE_TYPE : DWORD
{
    REG_UNKNOWN                     =  -1,  ///
    REG_NONE                        =   0,  /// The null value type. (In practise this is treated as a zero-length binary array by the Win32 registry)
    REG_SZ                          =   1,  /// A zero-terminated string
    REG_EXPAND_SZ                   =   2,  /// A zero-terminated string containing expandable environment variable references
    REG_BINARY                      =   3,  /// A binary blob
    REG_DWORD                       =   4,  /// A 32-bit unsigned integer
    REG_DWORD_LITTLE_ENDIAN         =   4,  /// A 32-bit unsigned integer, stored in little-endian byte order
    REG_DWORD_BIG_ENDIAN            =   5,  /// A 32-bit unsigned integer, stored in big-endian byte order
    REG_LINK                        =   6,  /// A registry link
    REG_MULTI_SZ                    =   7,  /// A set of zero-terminated strings
    REG_RESOURCE_LIST               =   8,  /// A hardware resource list
    REG_FULL_RESOURCE_DESCRIPTOR    =   9,  /// A hardware resource descriptor
    REG_RESOURCE_REQUIREMENTS_LIST  =  10,  /// A hardware resource requirements list
    REG_QWORD                       =  11,  /// A 64-bit unsigned integer
    REG_QWORD_LITTLE_ENDIAN         =  11,  /// A 64-bit unsigned integer, stored in little-endian byte order
}


/* ************* private *************** */

import core.sys.windows.winnt :
    DELETE                  ,
    READ_CONTROL            ,
    WRITE_DAC               ,
    WRITE_OWNER             ,
    SYNCHRONIZE             ,

    STANDARD_RIGHTS_REQUIRED,

    STANDARD_RIGHTS_READ    ,
    STANDARD_RIGHTS_WRITE   ,
    STANDARD_RIGHTS_EXECUTE ,

    STANDARD_RIGHTS_ALL     ,

    SPECIFIC_RIGHTS_ALL     ;

import core.sys.windows.winreg :
    REG_CREATED_NEW_KEY     ,
    REG_OPENED_EXISTING_KEY ;

// Returns samDesired but without WoW64 flags if not in WoW64 mode
// for compatibility with Windows 2000
private REGSAM compatibleRegsam(in REGSAM samDesired)
{
    return isWow64 ? samDesired : cast(REGSAM)(samDesired & ~REGSAM.KEY_WOW64_RES);
}

///Returns true, if we are in WoW64 mode and have WoW64 flags
private bool haveWoW64Job(in REGSAM samDesired)
{
    return isWow64 && (samDesired & REGSAM.KEY_WOW64_RES);
}

private REG_VALUE_TYPE _RVT_from_Endian(Endian endian)
{
    final switch (endian)
    {
        case Endian.bigEndian:
            return REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN;

        case Endian.littleEndian:
            return REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN;
    }
}

private LONG regCloseKey(in HKEY hkey)
in
{
    assert(hkey !is null);
}
body
{
    /* No need to attempt to close any of the standard hive keys.
     * Although it's documented that calling RegCloseKey() on any of
     * these hive keys is ignored, we'd rather not trust the Win32
     * API.
     */
    if (cast(uint) hkey & 0x80000000)
    {
        switch (cast(uint) hkey)
        {
            case HKEY_CLASSES_ROOT:
            case HKEY_CURRENT_USER:
            case HKEY_LOCAL_MACHINE:
            case HKEY_USERS:
            case HKEY_PERFORMANCE_DATA:
            case HKEY_PERFORMANCE_TEXT:
            case HKEY_PERFORMANCE_NLSTEXT:
            case HKEY_CURRENT_CONFIG:
            case HKEY_DYN_DATA:
                return ERROR_SUCCESS;
            default:
                /* Do nothing */
                break;
        }
    }

    return RegCloseKey(hkey);
}

private void regFlushKey(in HKEY hkey)
in
{
    assert(hkey !is null);
}
body
{
    immutable res = RegFlushKey(hkey);
    enforceSucc(res, "Key cannot be flushed");
}

private HKEY regCreateKey(in HKEY hkey, in string subKey, in DWORD dwOptions, in REGSAM samDesired,
                          in LPSECURITY_ATTRIBUTES lpsa, out DWORD disposition)
in
{
    assert(hkey !is null);
    assert(subKey !is null);
}
body
{
    HKEY hkeyResult;
    enforceSucc(RegCreateKeyExW(
                        hkey, subKey.tempCStringW(), 0, null, dwOptions,
                        compatibleRegsam(samDesired), cast(LPSECURITY_ATTRIBUTES) lpsa,
                        &hkeyResult, &disposition),
        "Failed to create requested key: \"" ~ subKey ~ "\"");

    return hkeyResult;
}

private void regDeleteKey(in HKEY hkey, in string subKey, in REGSAM samDesired)
in
{
    assert(hkey !is null);
    assert(subKey !is null);
}
body
{
    LONG res;
    if (haveWoW64Job(samDesired))
    {
        loadAdvapi32();
        res = pRegDeleteKeyExW(hkey, subKey.tempCStringW(), samDesired, 0);
    }
    else
    {
        res = RegDeleteKeyW(hkey, subKey.tempCStringW());
    }
    enforceSucc(res, "Key cannot be deleted: \"" ~ subKey ~ "\"");
}

private void regDeleteValue(in HKEY hkey, in string valueName)
in
{
    assert(hkey !is null);
    assert(valueName !is null);
}
body
{
    enforceSucc(RegDeleteValueW(hkey, valueName.tempCStringW()),
        "Value cannot be deleted: \"" ~ valueName ~ "\"");
}

private HKEY regDup(HKEY hkey)
in
{
    assert(hkey !is null);
}
body
{
    /* Can't duplicate standard keys, but don't need to, so can just return */
    if (cast(uint) hkey & 0x80000000)
    {
        switch (cast(uint) hkey)
        {
            case HKEY_CLASSES_ROOT:
            case HKEY_CURRENT_USER:
            case HKEY_LOCAL_MACHINE:
            case HKEY_USERS:
            case HKEY_PERFORMANCE_DATA:
            case HKEY_PERFORMANCE_TEXT:
            case HKEY_PERFORMANCE_NLSTEXT:
            case HKEY_CURRENT_CONFIG:
            case HKEY_DYN_DATA:
                return hkey;
            default:
                /* Do nothing */
                break;
        }
    }

    HKEY hkeyDup;
    immutable res = RegOpenKeyW(hkey, null, &hkeyDup);

    debug(winreg)
    {
        if (res != ERROR_SUCCESS)
        {
            writefln("regDup() failed: 0x%08x 0x%08x %d", hkey, hkeyDup, res);
        }

        assert(res == ERROR_SUCCESS);
    }

    return (res == ERROR_SUCCESS) ? hkeyDup : null;
}

private LONG regEnumKeyName(in HKEY hkey, in DWORD index, ref wchar[] name, out DWORD cchName)
in
{
    assert(hkey !is null);
    assert(name !is null);
    assert(name.length > 0);
}
out(res)
{
    assert(res != ERROR_MORE_DATA);
}
body
{
    // The Registry API lies about the lengths of a very few sub-key lengths
    // so we have to test to see if it whinges about more data, and provide
    // more if it does.
    for (;;)
    {
        cchName = to!DWORD(name.length);
        immutable res = RegEnumKeyExW(hkey, index, name.ptr, &cchName, null, null, null, null);
        if (res != ERROR_MORE_DATA)
            return res;

        // Now need to increase the size of the buffer and try again
        name.length *= 2;
    }

    assert(0);
}


private LONG regEnumValueName(in HKEY hkey, in DWORD dwIndex, ref wchar[] name, out DWORD cchName)
in
{
    assert(hkey !is null);
}
body
{
    for (;;)
    {
        cchName = to!DWORD(name.length);
        immutable res = RegEnumValueW(hkey, dwIndex, name.ptr, &cchName, null, null, null, null);
        if (res != ERROR_MORE_DATA)
            return res;

        name.length *= 2;
    }

    assert(0);
}

private LONG regGetNumSubKeys(in HKEY hkey, out DWORD cSubKeys, out DWORD cchSubKeyMaxLen)
in
{
    assert(hkey !is null);
}
body
{
    return RegQueryInfoKeyW(hkey, null, null, null, &cSubKeys,
                            &cchSubKeyMaxLen, null, null, null, null, null, null);
}

private LONG regGetNumValues(in HKEY hkey, out DWORD cValues, out DWORD cchValueMaxLen)
in
{
    assert(hkey !is null);
}
body
{
    return RegQueryInfoKeyW(hkey, null, null, null, null, null, null,
                            &cValues, &cchValueMaxLen, null, null, null);
}

private REG_VALUE_TYPE regGetValueType(in HKEY hkey, in string name)
in
{
    assert(hkey !is null);
}
body
{
    REG_VALUE_TYPE type;
    enforceSucc(RegQueryValueExW(hkey, name.tempCStringW(), null, cast(LPDWORD) &type, null, null),
        "Value cannot be opened: \"" ~ name ~ "\"");

    return type;
}

private HKEY regOpenKey(in HKEY hkey, in string subKey, in REGSAM samDesired)
in
{
    assert(hkey !is null);
    assert(subKey !is null);
}
body
{
    HKEY hkeyResult;
    enforceSucc(RegOpenKeyExW(hkey, subKey.tempCStringW(), 0, compatibleRegsam(samDesired), &hkeyResult),
        "Failed to open requested key: \"" ~ subKey ~ "\"");

    return hkeyResult;
}

private void regQueryValue(in HKEY hkey, string name, out string value, REG_VALUE_TYPE reqType)
in
{
    assert(hkey !is null);
}
body
{
    import core.bitop : bswap;

    REG_VALUE_TYPE type;

    // See bugzilla 961 on this
    union U
    {
        uint    dw;
        ulong   qw;
    }
    U u;
    void* data = &u.qw;
    DWORD cbData = u.qw.sizeof;

    auto keynameTmp = name.tempCStringW();
    LONG res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data, &cbData);
    if (res == ERROR_MORE_DATA)
    {
        data = (new ubyte[cbData]).ptr;
        res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data, &cbData);
    }

    enforceSucc(res,
        "Cannot read the requested value");
    enforce(type == reqType,
            new RegistryException("Value type has been changed since the value was acquired"));

    switch (type)
    {
        case REG_VALUE_TYPE.REG_SZ:
        case REG_VALUE_TYPE.REG_EXPAND_SZ:
            auto wstr = (cast(immutable(wchar)*)data)[0 .. cbData / wchar.sizeof];
            assert(wstr.length > 0 && wstr[$-1] == '\0');
            if (wstr.length && wstr[$-1] == '\0')
                wstr.length = wstr.length - 1;
            assert(wstr.length == 0 || wstr[$-1] != '\0');
            value = wstr.to!string;
            break;

        case REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN:
            version (LittleEndian)
                value = to!string(u.dw);
            else
                value = to!string(bswap(u.dw));
            break;

        case REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN:
            version (LittleEndian)
                value = to!string(bswap(u.dw));
            else
                value = to!string(u.dw);
            break;

        case REG_VALUE_TYPE.REG_QWORD_LITTLE_ENDIAN:
            value = to!string(u.qw);
            break;

        case REG_VALUE_TYPE.REG_BINARY:
        case REG_VALUE_TYPE.REG_MULTI_SZ:
        default:
            throw new RegistryException("Cannot read the given value as a string");
    }
}

private void regQueryValue(in HKEY hkey, in string name, out string[] value, REG_VALUE_TYPE reqType)
in
{
    assert(hkey !is null);
}
body
{
    REG_VALUE_TYPE type;

    auto keynameTmp = name.tempCStringW();
    wchar[] data = new wchar[256];
    DWORD cbData = to!DWORD(data.length * wchar.sizeof);
    LONG res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data.ptr, &cbData);
    if (res == ERROR_MORE_DATA)
    {
        data.length = cbData / wchar.sizeof;
        res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data.ptr, &cbData);
    }
    else if (res == ERROR_SUCCESS)
    {
        data.length = cbData / wchar.sizeof;
    }
    enforceSucc(res, "Cannot read the requested value");
    enforce(type == REG_VALUE_TYPE.REG_MULTI_SZ,
            new RegistryException("Cannot read the given value as a string"));
    enforce(type == reqType,
            new RegistryException("Value type has been changed since the value was acquired"));

    // Remove last two (or one) null terminator
    assert(data.length > 0 && data[$-1] == '\0');
    data.length = data.length - 1;
    if (data.length > 0 && data[$-1] == '\0')
        data.length = data.length - 1;

    auto list = std.array.split(data[], "\0");
    value.length = list.length;
    foreach (i, ref v; value)
    {
        v = list[i].to!string;
    }
}

private void regQueryValue(in HKEY hkey, in string name, out uint value, REG_VALUE_TYPE reqType)
in
{
    assert(hkey !is null);
}
body
{
    import core.bitop : bswap;

    REG_VALUE_TYPE type;

    DWORD cbData = value.sizeof;
    enforceSucc(RegQueryValueExW(hkey, name.tempCStringW(), null, cast(LPDWORD) &type, &value, &cbData),
        "Cannot read the requested value");
    enforce(type == reqType,
            new RegistryException("Value type has been changed since the value was acquired"));

    switch (type)
    {
        case REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN:
            version (LittleEndian)
                static assert(REG_VALUE_TYPE.REG_DWORD == REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN);
            else
                value = bswap(value);
            break;

        case REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN:
            version (LittleEndian)
                value = bswap(value);
            else
                static assert(REG_VALUE_TYPE.REG_DWORD == REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN);
            break;

        default:
            throw new RegistryException("Cannot read the given value as a 32-bit integer");
    }
}

private void regQueryValue(in HKEY hkey, in string name, out ulong value, REG_VALUE_TYPE reqType)
in
{
    assert(hkey !is null);
}
body
{
    REG_VALUE_TYPE type;

    DWORD cbData = value.sizeof;
    enforceSucc(RegQueryValueExW(hkey, name.tempCStringW(), null, cast(LPDWORD) &type, &value, &cbData),
        "Cannot read the requested value");
    enforce(type == reqType,
            new RegistryException("Value type has been changed since the value was acquired"));

    switch (type)
    {
        case REG_VALUE_TYPE.REG_QWORD_LITTLE_ENDIAN:
            break;

        default:
            throw new RegistryException("Cannot read the given value as a 64-bit integer");
    }
}

private void regQueryValue(in HKEY hkey, in string name, out byte[] value, REG_VALUE_TYPE reqType)
in
{
    assert(hkey !is null);
}
body
{
    REG_VALUE_TYPE type;

    byte[] data = new byte[100];
    DWORD cbData = to!DWORD(data.length);
    LONG res;
    auto keynameTmp = name.tempCStringW();
    res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data.ptr, &cbData);
    if (res == ERROR_MORE_DATA)
    {
        data.length = cbData;
        res = RegQueryValueExW(hkey, keynameTmp, null, cast(LPDWORD) &type, data.ptr, &cbData);
    }
    enforceSucc(res, "Cannot read the requested value");
    enforce(type == reqType,
            new RegistryException("Value type has been changed since the value was acquired"));

    switch (type)
    {
        case REG_VALUE_TYPE.REG_BINARY:
            data.length = cbData;
            value = data;
            break;

        default:
            throw new RegistryException("Cannot read the given value as a string");
    }
}

private void regSetValue(in HKEY hkey, in string subKey, in REG_VALUE_TYPE type, in LPCVOID lpData, in DWORD cbData)
in
{
    assert(hkey !is null);
}
body
{
    enforceSucc(RegSetValueExW(hkey, subKey.tempCStringW(), 0, type, cast(BYTE*) lpData, cbData),
        "Value cannot be set: \"" ~ subKey ~ "\"");
}

private void regProcessNthKey(Key key, scope void delegate(scope LONG delegate(DWORD, out string)) dg)
{
    DWORD cSubKeys;
    DWORD cchSubKeyMaxLen;

    immutable res = regGetNumSubKeys(key.m_hkey, cSubKeys, cchSubKeyMaxLen);
    assert(res == ERROR_SUCCESS);

    wchar[] sName = new wchar[cchSubKeyMaxLen + 1];

    // Capture `key` in the lambda to keep the object alive (and so its HKEY handle open).
    dg((DWORD index, out string name)
    {
        DWORD cchName;
        immutable res = regEnumKeyName(key.m_hkey, index, sName, cchName);
        if (res == ERROR_SUCCESS)
        {
            name = sName[0 .. cchName].to!string;
        }
        return res;
    });
}

private void regProcessNthValue(Key key, scope void delegate(scope LONG delegate(DWORD, out string)) dg)
{
    DWORD cValues;
    DWORD cchValueMaxLen;

    immutable res = regGetNumValues(key.m_hkey, cValues, cchValueMaxLen);
    assert(res == ERROR_SUCCESS);

    wchar[] sName = new wchar[cchValueMaxLen + 1];

    // Capture `key` in the lambda to keep the object alive (and so its HKEY handle open).
    dg((DWORD index, out string name)
    {
        DWORD cchName;
        immutable res = regEnumValueName(key.m_hkey, index, sName, cchName);
        if (res == ERROR_SUCCESS)
        {
            name = sName[0 .. cchName].to!string;
        }
        return res;
    });
}

/* ************* public classes *************** */

/**
    This class represents a registry key.
 */
class Key
{
    @safe pure nothrow
    invariant()
    {
        assert(m_hkey !is null);
    }

private:
    @safe pure nothrow
    this(HKEY hkey, string name, bool created)
    in
    {
        assert(hkey !is null);
    }
    body
    {
        m_hkey = hkey;
        m_name = name;
    }

    ~this()
    {
        regCloseKey(m_hkey);

        // Even though this is horried waste-of-cycles programming
        // we're doing it here so that the
        m_hkey = null;
    }

public:
    /// The name of the key
    @property string name() @safe pure nothrow const
    {
        return m_name;
    }

    /**
        The number of sub keys.
     */
    @property size_t keyCount() const
    {
        uint cSubKeys;
        uint cchSubKeyMaxLen;
        enforceSucc(regGetNumSubKeys(m_hkey, cSubKeys, cchSubKeyMaxLen),
            "Number of sub-keys cannot be determined");

        return cSubKeys;
    }

    /**
        An enumerable sequence of all the sub-keys of this key.
     */
    @property KeySequence keys() @safe pure
    {
        return new KeySequence(this);
    }

    /**
        An enumerable sequence of the names of all the sub-keys of this key.
     */
    @property KeyNameSequence keyNames() @safe pure
    {
        return new KeyNameSequence(this);
    }

    /**
        The number of values.
     */
    @property size_t valueCount() const
    {
        uint cValues;
        uint cchValueMaxLen;
        enforceSucc(regGetNumValues(m_hkey, cValues, cchValueMaxLen),
            "Number of values cannot be determined");

        return cValues;
    }

    /**
        An enumerable sequence of all the values of this key.
     */
    @property ValueSequence values() @safe pure
    {
        return new ValueSequence(this);
    }

    /**
        An enumerable sequence of the names of all the values of this key.
     */
    @property ValueNameSequence valueNames() @safe pure
    {
        return new ValueNameSequence(this);
    }

public:
    /**
        Returns the named sub-key of this key.

        Params:
            name = The name of the subkey to create. May not be $(D null).
        Returns:
            The created key.
        Throws:
            $(D RegistryException) is thrown if the key cannot be created.
     */
    Key createKey(string name, REGSAM access = REGSAM.KEY_ALL_ACCESS)
    {
        enforce(!name.empty, new RegistryException("Key name is invalid"));

        DWORD disposition;
        HKEY hkey = regCreateKey(m_hkey, name, 0, access, null, disposition);
        assert(hkey !is null);

        // Potential resource leak here!!
        //
        // If the allocation of the memory for Key fails, the HKEY could be
        // lost. Hence, we catch such a failure by the finally, and release
        // the HKEY there. If the creation of
        try
        {
            Key key = new Key(hkey, name, disposition == REG_CREATED_NEW_KEY);
            hkey = null;
            return key;
        }
        finally
        {
            if (hkey !is null)
            {
                regCloseKey(hkey);
            }
        }
    }

    /**
        Returns the named sub-key of this key.

        Params:
            name = The name of the subkey to aquire. If name is the empty
                   string, then the called key is duplicated.
            access = The desired access; one of the $(D REGSAM) enumeration.
        Returns:
            The aquired key.
        Throws:
            This function never returns $(D null). If a key corresponding to
            the requested name is not found, $(D RegistryException) is thrown.
     */
    Key getKey(string name, REGSAM access = REGSAM.KEY_READ)
    {
        if (name.empty)
            return new Key(regDup(m_hkey), m_name, false);

        HKEY hkey = regOpenKey(m_hkey, name, access);
        assert(hkey !is null);

        // Potential resource leak here!!
        //
        // If the allocation of the memory for Key fails, the HKEY could be
        // lost. Hence, we catch such a failure by the finally, and release
        // the HKEY there. If the creation of
        try
        {
            Key key = new Key(hkey, name, false);
            hkey = null;
            return key;
        }
        finally
        {
            if (hkey != null)
            {
                regCloseKey(hkey);
            }
        }
    }

    /**
        Deletes the named key.

        Params:
            name = The name of the key to delete. May not be $(D null).
     */
    void deleteKey(string name, REGSAM access = cast(REGSAM) 0)
    {
        enforce(!name.empty, new RegistryException("Key name is invalid"));

        regDeleteKey(m_hkey, name, access);
    }

    /**
        Returns the named value.
        If $(D name) is the empty string, then the default value is returned.

        Returns:
            This function never returns $(D null). If a value corresponding
            to the requested name is not found, $(D RegistryException) is thrown.
     */
    Value getValue(string name)
    {
        return new Value(this, name, regGetValueType(m_hkey, name));
    }

    /**
        Sets the named value with the given 32-bit unsigned integer value.

        Params:
            name = The name of the value to set. If it is the empty string,
                   sets the default value.
            value = The 32-bit unsigned value to set.
        Throws:
            If a value corresponding to the requested name is not found,
            $(D RegistryException) is thrown.
     */
    void setValue(string name, uint value)
    {
        setValue(name, value, endian);
    }

    /**
        Sets the named value with the given 32-bit unsigned integer value,
        according to the desired byte-ordering.

        Params:
            name = The name of the value to set. If it is the empty string,
                   sets the default value.
            value = The 32-bit unsigned value to set.
            endian = Can be $(D Endian.BigEndian) or $(D Endian.LittleEndian).
        Throws:
            If a value corresponding to the requested name is not found,
            $(D RegistryException) is thrown.
     */
    void setValue(string name, uint value, Endian endian)
    {
        REG_VALUE_TYPE  type = _RVT_from_Endian(endian);

        assert(type == REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN ||
               type == REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN);

        regSetValue(m_hkey, name, type, &value, value.sizeof);
    }

    /**
        Sets the named value with the given 64-bit unsigned integer value.

        Params:
            name = The name of the value to set. If it is the empty string,
                   sets the default value.
            value = The 64-bit unsigned value to set.
        Throws:
            If a value corresponding to the requested name is not found,
            $(D RegistryException) is thrown.
     */
    void setValue(string name, ulong value)
    {
        regSetValue(m_hkey, name, REG_VALUE_TYPE.REG_QWORD, &value, value.sizeof);
    }

    /**
        Sets the named value with the given string value.

        Params:
            name = The name of the value to set. If it is the empty string,
                   sets the default value.
            value = The string value to set.
        Throws:
            If a value corresponding to the requested name is not found,
            $(D RegistryException) is thrown.
     */
    void setValue(string name, string value)
    {
        setValue(name, value, false);
    }

    /**
        Sets the named value with the given string value.

        Params:
            name = The name of the value to set. If it is the empty string,
                   sets the default value.
            value = The string value to set.
            asEXPAND_SZ = If $(D true), the value will be stored as an
                          expandable environment string, otherwise as a normal string.
        Throws:
            If a value corresponding to the requested name is not found,
            $(D RegistryException) is thrown.
     */
    void setValue(string name, string value, bool asEXPAND_SZ)
    {
        auto pszTmp = value.tempCStringW();
        const(void)* data = pszTmp;
        DWORD len = to!DWORD(lstrlenW(pszTmp) * wchar.sizeof);

        regSetValue(m_hkey, name,
                    asEXPAND_SZ ? REG_VALUE_TYPE.REG_EXPAND_SZ
                                : REG_VALUE_TYPE.REG_SZ,
                    data, len);
    }

    /**
        Sets the named value with the given multiple-strings value.

        Params:
            name = The name of the value to set. If it is the empty string,
                   sets the default value.
            value = The multiple-strings value to set.
        Throws:
            If a value corresponding to the requested name is not found,
            $(D RegistryException) is thrown.
     */
    void setValue(string name, string[] value)
    {
        wstring[] data = new wstring[value.length+1];
        foreach (i, ref s; data[0..$-1])
        {
            s = value[i].to!wstring;
        }
        data[$-1] = "\0";
        auto ws = std.array.join(data, "\0"w);

        regSetValue(m_hkey, name, REG_VALUE_TYPE.REG_MULTI_SZ, ws.ptr, to!uint(ws.length * wchar.sizeof));
    }

    /**
        Sets the named value with the given binary value.

        Params:
            name = The name of the value to set. If it is the empty string,
                   sets the default value.
            value = The binary value to set.
        Throws:
            If a value corresponding to the requested name is not found,
            $(D RegistryException) is thrown.
     */
    void setValue(string name, byte[] value)
    {
        regSetValue(m_hkey, name, REG_VALUE_TYPE.REG_BINARY, value.ptr, to!DWORD(value.length));
    }

    /**
        Deletes the named value.

        Params:
            name = The name of the value to delete. May not be $(D null).
        Throws:
            If a value of the requested name is not found,
            $(D RegistryException) is thrown.
     */
    void deleteValue(string name)
    {
        regDeleteValue(m_hkey, name);
    }

    /**
        Flushes any changes to the key to disk.
     */
    void flush()
    {
        regFlushKey(m_hkey);
    }

private:
    HKEY   m_hkey;
    string m_name;
}

/**
    This class represents a value of a registry key.
 */
class Value
{
    @safe pure nothrow
    invariant()
    {
        assert(m_key !is null);
    }

private:
    @safe pure nothrow
    this(Key key, string name, REG_VALUE_TYPE type)
    in
    {
        assert(null !is key);
    }
    body
    {
        m_key = key;
        m_type = type;
        m_name = name;
    }

public:
    /**
        The name of the value.
        If the value represents a default value of a key, which has no name,
        the returned string will be of zero length.
     */
    @property string name() @safe pure nothrow const
    {
        return m_name;
    }

    /**
        The type of value.
     */
    @property REG_VALUE_TYPE type() @safe pure nothrow const
    {
        return m_type;
    }

    /**
        Obtains the current value of the value as a string.
        If the value's type is REG_EXPAND_SZ the returned value is <b>not</b>
        expanded; $(D value_EXPAND_SZ) should be called

        Returns:
            The contents of the value.
        Throws:
            $(D RegistryException) if the type of the value is not REG_SZ,
            REG_EXPAND_SZ, REG_DWORD, or REG_QWORD.
     */
    @property string value_SZ() const
    {
        string value;

        regQueryValue(m_key.m_hkey, m_name, value, m_type);

        return value;
    }

    /**
        Obtains the current value as a string, within which any environment
        variables have undergone expansion.
        This function works with the same value-types as $(D value_SZ).

        Returns:
            The contents of the value.
     */
    @property string value_EXPAND_SZ() const
    {
        string  value   =   value_SZ;

        // ExpandEnvironemntStrings():
        //      http://msdn2.microsoft.com/en-us/library/ms724265.aspx
        const srcTmp        =   value.tempCStringW();
        DWORD   cchRequired =   ExpandEnvironmentStringsW(srcTmp, null, 0);
        wchar[]  newValue   =   new wchar[cchRequired];

        immutable DWORD count = enforce!Win32Exception(
            ExpandEnvironmentStringsW(srcTmp, newValue.ptr, to!DWORD(newValue.length)),
            "Failed to expand environment variables");

        return newValue[0 .. count-1].to!string; // remove trailing 0
    }

    /**
        Obtains the current value as an array of strings.

        Returns:
            The contents of the value.
        Throws:
            $(D RegistryException) if the type of the value is not REG_MULTI_SZ.
     */
    @property string[] value_MULTI_SZ() const
    {
        string[] value;

        regQueryValue(m_key.m_hkey, m_name, value, m_type);

        return value;
    }

    /**
        Obtains the current value as a 32-bit unsigned integer, ordered
        correctly according to the current architecture.

        Returns:
            The contents of the value.
        Throws:
            $(D RegistryException) is thrown for all types other than
            REG_DWORD, REG_DWORD_LITTLE_ENDIAN and REG_DWORD_BIG_ENDIAN.
     */
    @property uint value_DWORD() const
    {
        uint value;

        regQueryValue(m_key.m_hkey, m_name, value, m_type);

        return value;
    }

    /**
        Obtains the value as a 64-bit unsigned integer, ordered correctly
        according to the current architecture.

        Returns:
            The contents of the value.
        Throws:
            $(D RegistryException) if the type of the value is not REG_QWORD.
     */
    @property ulong value_QWORD() const
    {
        ulong value;

        regQueryValue(m_key.m_hkey, m_name, value, m_type);

        return value;
    }

    /**
        Obtains the value as a binary blob.

        Returns:
            The contents of the value.
        Throws:
            $(D RegistryException) if the type of the value is not REG_BINARY.
     */
    @property byte[] value_BINARY() const
    {
        byte[] value;

        regQueryValue(m_key.m_hkey, m_name, value, m_type);

        return value;
    }

private:
    Key             m_key;
    REG_VALUE_TYPE  m_type;
    string          m_name;
}

/**
    Represents the local system registry.
 */
final class Registry
{
private:
    @disable this() { }

public:
    /// Returns the root key for the HKEY_CLASSES_ROOT hive
    static @property Key classesRoot()     { return new Key(HKEY_CLASSES_ROOT,     "HKEY_CLASSES_ROOT",     false); }
    /// Returns the root key for the HKEY_CURRENT_USER hive
    static @property Key currentUser()     { return new Key(HKEY_CURRENT_USER,     "HKEY_CURRENT_USER",     false); }
    /// Returns the root key for the HKEY_LOCAL_MACHINE hive
    static @property Key localMachine()    { return new Key(HKEY_LOCAL_MACHINE,    "HKEY_LOCAL_MACHINE",    false); }
    /// Returns the root key for the HKEY_USERS hive
    static @property Key users()           { return new Key(HKEY_USERS,            "HKEY_USERS",            false); }
    /// Returns the root key for the HKEY_PERFORMANCE_DATA hive
    static @property Key performanceData() { return new Key(HKEY_PERFORMANCE_DATA, "HKEY_PERFORMANCE_DATA", false); }
    /// Returns the root key for the HKEY_CURRENT_CONFIG hive
    static @property Key currentConfig()   { return new Key(HKEY_CURRENT_CONFIG,   "HKEY_CURRENT_CONFIG",   false); }
    /// Returns the root key for the HKEY_DYN_DATA hive
    static @property Key dynData()         { return new Key(HKEY_DYN_DATA,         "HKEY_DYN_DATA",         false); }
}

/**
    An enumerable sequence representing the names of the sub-keys of a registry Key.

Example:
----
Key key = ...
foreach (string subkeyName; key.keyNames)
{
    // using subkeyName
}
----
 */
class KeyNameSequence
{
    @safe pure nothrow
    invariant()
    {
        assert(m_key !is null);
    }

private:
    @safe pure nothrow
    this(Key key)
    {
        m_key = key;
    }

public:
    /**
        The number of keys.
     */
    @property size_t count() const
    {
        return m_key.keyCount;
    }

    /**
        The name of the key at the given index.

        Params:
            index = The 0-based index of the key to retrieve.
        Returns:
            The name of the key corresponding to the given index.
        Throws:
            RegistryException if no corresponding key is retrieved.
     */
    string getKeyName(size_t index)
    {
        string name;
        regProcessNthKey(m_key, (scope LONG delegate(DWORD, out string) getName)
        {
            enforceSucc(getName(to!DWORD(index), name), "Invalid key");
        });
        return name;
    }

    /**
        The name of the key at the given index.

        Params:
            index = The 0-based index of the key to retrieve.
        Returns:
            The name of the key corresponding to the given index.
        Throws:
            $(D RegistryException) if no corresponding key is retrieved.
     */
    string opIndex(size_t index)
    {
        return getKeyName(index);
    }

public:
    ///
    int opApply(scope int delegate(ref string name) dg)
    {
        int result;
        regProcessNthKey(m_key, (scope LONG delegate(DWORD, out string) getName)
        {
            for (DWORD index = 0; !result; ++index)
            {
                string name;
                immutable res = getName(index, name);
                if (res == ERROR_NO_MORE_ITEMS) // Enumeration complete
                    break;
                enforceSucc(res, "Key name enumeration incomplete");

                result = dg(name);
            }
        });
        return result;
    }

private:
    Key m_key;
}


/**
    An enumerable sequence representing the sub-keys of a registry Key.

Example:
----
Key key = ...
foreach (Key subkey; key.keys)
{
    // using subkey
}
----
 */
class KeySequence
{
    @safe pure nothrow
    invariant()
    {
        assert(m_key !is null);
    }

private:
    @safe pure nothrow
    this(Key key)
    {
        m_key = key;
    }

public:
    /**
        The number of keys.
     */
    @property size_t count() const
    {
        return m_key.keyCount;
    }

    /**
        The key at the given index.

        Params:
            index = The 0-based index of the key to retrieve.
        Returns:
            The key corresponding to the given index.
        Throws:
            $(D RegistryException) if no corresponding key is retrieved.
     */
    Key getKey(size_t index)
    {
        string name;
        regProcessNthKey(m_key, (scope LONG delegate(DWORD, out string) getName)
        {
            enforceSucc(getName(to!DWORD(index), name), "Invalid key");
        });
        return m_key.getKey(name);
    }

    /**
        The key at the given index.

        Params:
            index = The 0-based index of the key to retrieve.
        Returns:
            The key corresponding to the given index.
        Throws:
            $(D RegistryException) if no corresponding key is retrieved.
     */
    Key opIndex(size_t index)
    {
        return getKey(index);
    }

public:
    ///
    int opApply(scope int delegate(ref Key key) dg)
    {
        int result = 0;
        regProcessNthKey(m_key, (scope LONG delegate(DWORD, out string) getName)
        {
            for (DWORD index = 0; !result; ++index)
            {
                string name;
                immutable res = getName(index, name);
                if (res == ERROR_NO_MORE_ITEMS) // Enumeration complete
                    break;
                enforceSucc(res, "Key enumeration incomplete");

                try
                {
                    Key key = m_key.getKey(name);
                    result = dg(key);
                }
                catch (RegistryException e)
                {
                    // Skip inaccessible keys; they are
                    // accessible via the KeyNameSequence
                    if (e.error == ERROR_ACCESS_DENIED)
                        continue;

                    throw e;
                }
            }
        });
        return result;
    }

private:
    Key m_key;
}

/**
    An enumerable sequence representing the names of the values of a registry Key.

Example:
----
Key key = ...
foreach (string valueName; key.valueNames)
{
    // using valueName
}
----
 */
class ValueNameSequence
{
    @safe pure nothrow
    invariant()
    {
        assert(m_key !is null);
    }

private:
    @safe pure nothrow
    this(Key key)
    {
        m_key = key;
    }

public:
    /**
        The number of values.
     */
    @property size_t count() const
    {
        return m_key.valueCount;
    }

    /**
        The name of the value at the given index.

        Params:
            index = The 0-based index of the value to retrieve.
        Returns:
            The name of the value corresponding to the given index.
        Throws:
            $(D RegistryException) if no corresponding value is retrieved.
     */
    string getValueName(size_t index)
    {
        string name;
        regProcessNthValue(m_key, (scope LONG delegate(DWORD, out string) getName)
        {
            enforceSucc(getName(to!DWORD(index), name), "Invalid value");
        });
        return name;
    }

    /**
        The name of the value at the given index.

        Params:
            index = The 0-based index of the value to retrieve.
        Returns:
            The name of the value corresponding to the given index.
        Throws:
            $(D RegistryException) if no corresponding value is retrieved.
     */
    string opIndex(size_t index)
    {
        return getValueName(index);
    }

public:
    ///
    int opApply(scope int delegate(ref string name) dg)
    {
        int result = 0;
        regProcessNthValue(m_key, (scope LONG delegate(DWORD, out string) getName)
        {
            for (DWORD index = 0; !result; ++index)
            {
                string name;
                immutable res = getName(index, name);
                if (res == ERROR_NO_MORE_ITEMS) // Enumeration complete
                    break;
                enforceSucc(res, "Value name enumeration incomplete");

                result = dg(name);
            }
        });
        return result;
    }

private:
    Key m_key;
}

/**
    An enumerable sequence representing the values of a registry Key.

Example:
----
Key key = ...
foreach (Value value; key.values)
{
    // using value
}
----
 */
class ValueSequence
{
    @safe pure nothrow
    invariant()
    {
        assert(m_key !is null);
    }

private:
    @safe pure nothrow
    this(Key key)
    {
        m_key = key;
    }

public:
    /// The number of values
    @property size_t count() const
    {
        return m_key.valueCount;
    }

    /**
        The value at the given $(D index).

        Params:
            index = The 0-based index of the value to retrieve
        Returns:
            The value corresponding to the given index.
        Throws:
            $(D RegistryException) if no corresponding value is retrieved
     */
    Value getValue(size_t index)
    {
        string name;
        regProcessNthValue(m_key, (scope LONG delegate(DWORD, out string) getName)
        {
            enforceSucc(getName(to!DWORD(index), name), "Invalid value");
        });
        return m_key.getValue(name);
    }

    /**
        The value at the given $(D index).

        Params:
            index = The 0-based index of the value to retrieve.
        Returns:
            The value corresponding to the given index.
        Throws:
            $(D RegistryException) if no corresponding value is retrieved.
     */
    Value opIndex(size_t index)
    {
        return getValue(index);
    }

public:
    ///
    int opApply(scope int delegate(ref Value value) dg)
    {
        int result = 0;
        regProcessNthValue(m_key, (scope LONG delegate(DWORD, out string) getName)
        {
            for (DWORD index = 0; !result; ++index)
            {
                string name;
                immutable res = getName(index, name);
                if (res == ERROR_NO_MORE_ITEMS) // Enumeration complete
                    break;
                enforceSucc(res, "Value enumeration incomplete");

                Value value = m_key.getValue(name);
                result = dg(value);
            }
        });
        return result;
    }

private:
    Key m_key;
}


@system unittest
{
    debug(winreg) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
    debug(winreg) writefln("std.windows.registry.unittest read");

/+
    // Mask for test speed up

    Key HKCR  = Registry.classesRoot;
    Key CLSID = HKCR.getKey("CLSID");

    foreach (Key key; CLSID.keys)
    {
        foreach (Value val; key.values)
        {
        }
    }
+/
    Key HKCU = Registry.currentUser;
    assert(HKCU);

    // Enumerate all subkeys of key Software
    Key softwareKey = HKCU.getKey("Software");
    assert(softwareKey);
    foreach (Key key; softwareKey.keys)
    {
        //writefln("Key %s", key.name);
        foreach (Value val; key.values)
        {
        }
    }
}

@system unittest
{
    debug(winreg) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
    debug(winreg) writefln("std.windows.registry.unittest write");

    // Warning: This unit test writes to the registry.
    // The test can fail if you don't have sufficient rights

    Key HKCU = Registry.currentUser;
    assert(HKCU);

    // Create a new key
    string unittestKeyName = "Temporary key for a D UnitTest which can be deleted afterwards";
    Key unittestKey = HKCU.createKey(unittestKeyName);
    assert(unittestKey);
    Key cityKey = unittestKey.createKey(
        "CityCollection using foreign names with umlauts and accents: "
        ~"\u00f6\u00e4\u00fc\u00d6\u00c4\u00dc\u00e0\u00e1\u00e2\u00df"
    );
    cityKey.setValue("K\u00f6ln", "Germany"); // Cologne
    cityKey.setValue("\u041c\u0438\u043d\u0441\u043a", "Belarus"); // Minsk
    cityKey.setValue("\u5317\u4eac", "China"); // Bejing
    bool foundCologne, foundMinsk, foundBeijing;
    foreach (Value v; cityKey.values)
    {
        auto vname = v.name;
        auto vvalue_SZ = v.value_SZ;
        if (v.name == "K\u00f6ln")
        {
            foundCologne = true;
            assert(v.value_SZ == "Germany");
        }
        if (v.name == "\u041c\u0438\u043d\u0441\u043a")
        {
            foundMinsk = true;
            assert(v.value_SZ == "Belarus");
        }
        if (v.name == "\u5317\u4eac")
        {
            foundBeijing = true;
            assert(v.value_SZ == "China");
        }
    }
    assert(foundCologne);
    assert(foundMinsk);
    assert(foundBeijing);

    Key stateKey = unittestKey.createKey("StateCollection");
    stateKey.setValue("Germany", ["D\u00fcsseldorf", "K\u00f6ln", "Hamburg"]);
    Value v = stateKey.getValue("Germany");
    string[] actual = v.value_MULTI_SZ;
    assert(actual.length == 3);
    assert(actual[0] == "D\u00fcsseldorf");
    assert(actual[1] == "K\u00f6ln");
    assert(actual[2] == "Hamburg");

    Key numberKey = unittestKey.createKey("Number");
    numberKey.setValue("One", 1);
    Value one = numberKey.getValue("One");
    assert(one.value_SZ == "1");
    assert(one.value_DWORD == 1);

    unittestKey.deleteKey(numberKey.name);
    unittestKey.deleteKey(stateKey.name);
    unittestKey.deleteKey(cityKey.name);
    HKCU.deleteKey(unittestKeyName);

    auto e = collectException!RegistryException(HKCU.getKey("cDhmxsX9K23a8Uf869uB"));
    assert(e.msg.endsWith(" (error 2)"));
}

@system unittest
{
    Key HKCU = Registry.currentUser;
    assert(HKCU);

    Key key = HKCU.getKey("Control Panel");
    assert(key);
    assert(key.keyCount >= 2);

    // Make sure `key` isn't garbage-collected while iterating over it.
    // Trigger a collection in the first iteration and check whether we
    // make it successfully to the second iteration.
    int i = 0;
    foreach (name; key.keyNames)
    {
        if (i++ > 0)
            break;

        import core.memory;
        GC.collect();
    }
    assert(i == 2);
}
