/*
 * Credential Management APIs
 *
 * Copyright 2007 Robert Shearman for CodeWeavers
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <time.h>

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wincred.h"
#include "winternl.h"

#ifdef __APPLE__
# include <Security/SecKeychain.h>
# include <Security/SecKeychainItem.h>
# include <Security/SecKeychainSearch.h>
#endif

#include "crypt.h"

#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(cred);

/* the size of the ARC4 key used to encrypt the password data */
#define KEY_SIZE 8

static const WCHAR wszCredentialManagerKey[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
    'C','r','e','d','e','n','t','i','a','l',' ','M','a','n','a','g','e','r',0};
static const WCHAR wszEncryptionKeyValue[] = {'E','n','c','r','y','p','t','i','o','n','K','e','y',0};

static const WCHAR wszFlagsValue[] = {'F','l','a','g','s',0};
static const WCHAR wszTypeValue[] = {'T','y','p','e',0};
static const WCHAR wszTargetNameValue[] = {'T','a','r','g','e','t','N','a','m','e',0};
static const WCHAR wszCommentValue[] = {'C','o','m','m','e','n','t',0};
static const WCHAR wszLastWrittenValue[] = {'L','a','s','t','W','r','i','t','t','e','n',0};
static const WCHAR wszPersistValue[] = {'P','e','r','s','i','s','t',0};
static const WCHAR wszTargetAliasValue[] = {'T','a','r','g','e','t','A','l','i','a','s',0};
static const WCHAR wszUserNameValue[] = {'U','s','e','r','N','a','m','e',0};
static const WCHAR wszPasswordValue[] = {'P','a','s','s','w','o','r','d',0};

static DWORD read_credential_blob(HKEY hkey, const BYTE key_data[KEY_SIZE],
                                  LPBYTE credential_blob,
                                  DWORD *credential_blob_size)
{
    DWORD ret;
    DWORD type;

    *credential_blob_size = 0;
    ret = RegQueryValueExW(hkey, wszPasswordValue, 0, &type, NULL, credential_blob_size);
    if (ret != ERROR_SUCCESS)
        return ret;
    else if (type != REG_BINARY)
        return ERROR_REGISTRY_CORRUPT;
    if (credential_blob)
    {
        struct ustring data;
        struct ustring key;

        ret = RegQueryValueExW(hkey, wszPasswordValue, 0, &type, (LPVOID)credential_blob,
                               credential_blob_size);
        if (ret != ERROR_SUCCESS)
            return ret;
        else if (type != REG_BINARY)
            return ERROR_REGISTRY_CORRUPT;

        key.Length = key.MaximumLength = sizeof(key_data);
        key.Buffer = (unsigned char *)key_data;

        data.Length = data.MaximumLength = *credential_blob_size;
        data.Buffer = credential_blob;
        SystemFunction032(&data, &key);
    }
    return ERROR_SUCCESS;
}

static DWORD registry_read_credential(HKEY hkey, PCREDENTIALW credential,
                                      const BYTE key_data[KEY_SIZE],
                                      char *buffer, DWORD *len)
{
    DWORD type;
    DWORD ret;
    DWORD count;

    ret = RegQueryValueExW(hkey, NULL, 0, &type, NULL, &count);
    if (ret != ERROR_SUCCESS)
        return ret;
    else if (type != REG_SZ)
        return ERROR_REGISTRY_CORRUPT;
    *len += count;
    if (credential)
    {
        credential->TargetName = (LPWSTR)buffer;
        ret = RegQueryValueExW(hkey, NULL, 0, &type, (LPVOID)credential->TargetName,
                               &count);
        if (ret != ERROR_SUCCESS || type != REG_SZ) return ret;
        buffer += count;
    }

    ret = RegQueryValueExW(hkey, wszCommentValue, 0, &type, NULL, &count);
    if (ret != ERROR_FILE_NOT_FOUND && ret != ERROR_SUCCESS)
        return ret;
    else if (type != REG_SZ)
        return ERROR_REGISTRY_CORRUPT;
    *len += count;
    if (credential)
    {
        credential->Comment = (LPWSTR)buffer;
        ret = RegQueryValueExW(hkey, wszCommentValue, 0, &type, (LPVOID)credential->Comment,
                               &count);
        if (ret == ERROR_FILE_NOT_FOUND)
            credential->Comment = NULL;
        else if (ret != ERROR_SUCCESS)
            return ret;
        else if (type != REG_SZ)
            return ERROR_REGISTRY_CORRUPT;
        else
            buffer += count;
    }

    ret = RegQueryValueExW(hkey, wszTargetAliasValue, 0, &type, NULL, &count);
    if (ret != ERROR_FILE_NOT_FOUND && ret != ERROR_SUCCESS)
        return ret;
    else if (type != REG_SZ)
        return ERROR_REGISTRY_CORRUPT;
    *len += count;
    if (credential)
    {
        credential->TargetAlias = (LPWSTR)buffer;
        ret = RegQueryValueExW(hkey, wszTargetAliasValue, 0, &type, (LPVOID)credential->TargetAlias,
                               &count);
        if (ret == ERROR_FILE_NOT_FOUND)
            credential->TargetAlias = NULL;
        else if (ret != ERROR_SUCCESS)
            return ret;
        else if (type != REG_SZ)
            return ERROR_REGISTRY_CORRUPT;
        else
            buffer += count;
    }

    ret = RegQueryValueExW(hkey, wszUserNameValue, 0, &type, NULL, &count);
    if (ret != ERROR_FILE_NOT_FOUND && ret != ERROR_SUCCESS)
        return ret;
    else if (type != REG_SZ)
        return ERROR_REGISTRY_CORRUPT;
    *len += count;
    if (credential)
    {
        credential->UserName = (LPWSTR)buffer;
        ret = RegQueryValueExW(hkey, wszUserNameValue, 0, &type, (LPVOID)credential->UserName,
                               &count);
        if (ret == ERROR_FILE_NOT_FOUND)
        {
            credential->UserName = NULL;
            ret = ERROR_SUCCESS;
        }
        else if (ret != ERROR_SUCCESS)
            return ret;
        else if (type != REG_SZ)
            return ERROR_REGISTRY_CORRUPT;
        else
            buffer += count;
    }

    ret = read_credential_blob(hkey, key_data, NULL, &count);
    if (ret != ERROR_FILE_NOT_FOUND && ret != ERROR_SUCCESS)
        return ret;
    *len += count;
    if (credential)
    {
        credential->CredentialBlob = (LPBYTE)buffer;
        ret = read_credential_blob(hkey, key_data, credential->CredentialBlob, &count);
        if (ret == ERROR_FILE_NOT_FOUND)
        {
            credential->CredentialBlob = NULL;
            ret = ERROR_SUCCESS;
        }
        else if (ret != ERROR_SUCCESS)
            return ret;
        credential->CredentialBlobSize = count;
        buffer += count;
    }

    /* FIXME: Attributes */
    if (credential)
    {
        credential->AttributeCount = 0;
        credential->Attributes = NULL;
    }

    if (!credential) return ERROR_SUCCESS;

    count = sizeof(credential->Flags);
    ret = RegQueryValueExW(hkey, wszFlagsValue, NULL, &type, (LPVOID)&credential->Flags,
                           &count);
    if (ret != ERROR_SUCCESS)
        return ret;
    else if (type != REG_DWORD)
        return ERROR_REGISTRY_CORRUPT;
    count = sizeof(credential->Type);
    ret = RegQueryValueExW(hkey, wszTypeValue, NULL, &type, (LPVOID)&credential->Type,
                           &count);
    if (ret != ERROR_SUCCESS)
        return ret;
    else if (type != REG_DWORD)
        return ERROR_REGISTRY_CORRUPT;

    count = sizeof(credential->LastWritten);
    ret = RegQueryValueExW(hkey, wszLastWrittenValue, NULL, &type, (LPVOID)&credential->LastWritten,
                           &count);
    if (ret != ERROR_SUCCESS)
        return ret;
    else if (type != REG_BINARY)
        return ERROR_REGISTRY_CORRUPT;
    count = sizeof(credential->Persist);
    ret = RegQueryValueExW(hkey, wszPersistValue, NULL, &type, (LPVOID)&credential->Persist,
                           &count);
    if (ret == ERROR_SUCCESS && type != REG_DWORD)
        return ERROR_REGISTRY_CORRUPT;
    return ret;
}

#ifdef __APPLE__
static DWORD mac_read_credential_from_item(SecKeychainItemRef item, BOOL require_password,
                                           PCREDENTIALW credential, char *buffer,
                                           DWORD *len)
{
    OSStatus status;
    UInt32 i;
    UInt32 cred_blob_len;
    void *cred_blob;
    LPWSTR domain = NULL;
    LPWSTR user = NULL;
    SecKeychainAttributeInfo info;
    SecKeychainAttributeList *attr_list;
    UInt32 info_tags[] = { kSecServerItemAttr, kSecSecurityDomainItemAttr, kSecAccountItemAttr,
                           kSecCommentItemAttr, kSecCreationDateItemAttr };
    info.count = sizeof(info_tags)/sizeof(info_tags[0]);
    info.tag = info_tags;
    info.format = NULL;
    status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, &cred_blob_len, &cred_blob);
    if (status == errSecAuthFailed && !require_password)
    {
        cred_blob_len = 0;
        cred_blob = NULL;
        status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, &cred_blob_len, NULL);
    }
    if (status != noErr)
    {
        WARN("SecKeychainItemCopyAttributesAndData returned status %ld\n", status);
        return ERROR_NOT_FOUND;
    }
    if (buffer)
    {
        credential->Flags = 0;
        credential->Type = CRED_TYPE_DOMAIN_PASSWORD;
        credential->TargetName = NULL;
        credential->Comment = NULL;
        memset(&credential->LastWritten, 0, sizeof(credential->LastWritten));
        credential->CredentialBlobSize = 0;
        credential->CredentialBlob = NULL;
        credential->Persist = CRED_PERSIST_LOCAL_MACHINE;
        credential->AttributeCount = 0;
        credential->Attributes = NULL;
        credential->TargetAlias = NULL;
        credential->UserName = NULL;
    }
    for (i = 0; i < attr_list->count; i++)
    {
        switch (attr_list->attr[i].tag)
        {
            case kSecServerItemAttr:
                TRACE("kSecServerItemAttr: %.*s\n", (int)attr_list->attr[i].length,
                      (char *)attr_list->attr[i].data);
                if (!attr_list->attr[i].data) continue;
                if (buffer)
                {
                    INT str_len;
                    credential->TargetName = (LPWSTR)buffer;
                    str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
                                                  attr_list->attr[i].length, (LPWSTR)buffer, 0xffff);
                    credential->TargetName[str_len] = '\0';
                    buffer += (str_len + 1) * sizeof(WCHAR);
                    *len += (str_len + 1) * sizeof(WCHAR);
                }
                else
                {
                    INT str_len;
                    str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
                                                  attr_list->attr[i].length, NULL, 0);
                    *len += (str_len + 1) * sizeof(WCHAR);
                }
                break;
            case kSecAccountItemAttr:
            {
                INT str_len;
                TRACE("kSecAccountItemAttr: %.*s\n", (int)attr_list->attr[i].length,
                      (char *)attr_list->attr[i].data);
                if (!attr_list->attr[i].data) continue;
                str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
                                              attr_list->attr[i].length, NULL, 0);
                user = HeapAlloc(GetProcessHeap(), 0, (str_len + 1) * sizeof(WCHAR));
                MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
                                    attr_list->attr[i].length, user, str_len);
                user[str_len] = '\0';
                break;
            }
            case kSecCommentItemAttr:
                TRACE("kSecCommentItemAttr: %.*s\n", (int)attr_list->attr[i].length,
                      (char *)attr_list->attr[i].data);
                if (!attr_list->attr[i].data) continue;
                if (buffer)
                {
                    INT str_len;
                    credential->Comment = (LPWSTR)buffer;
                    str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
                                                  attr_list->attr[i].length, (LPWSTR)buffer, 0xffff);
                    credential->Comment[str_len] = '\0';
                    buffer += (str_len + 1) * sizeof(WCHAR);
                    *len += (str_len + 1) * sizeof(WCHAR);
                }
                else
                {
                    INT str_len;
                    str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
                                                  attr_list->attr[i].length, NULL, 0);
                    *len += (str_len + 1) * sizeof(WCHAR);
                }
                break;
            case kSecSecurityDomainItemAttr:
            {
                INT str_len;
                TRACE("kSecSecurityDomainItemAttr: %.*s\n", (int)attr_list->attr[i].length,
                      (char *)attr_list->attr[i].data);
                if (!attr_list->attr[i].data) continue;
                str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
                                              attr_list->attr[i].length, NULL, 0);
                domain = HeapAlloc(GetProcessHeap(), 0, (str_len + 1) * sizeof(WCHAR));
                MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
                                    attr_list->attr[i].length, domain, str_len);
                domain[str_len] = '\0';
                break;
            }
            case kSecCreationDateItemAttr:
                TRACE("kSecCreationDateItemAttr: %.*s\n", (int)attr_list->attr[i].length,
                      (char *)attr_list->attr[i].data);
                if (buffer)
                {
                    LARGE_INTEGER win_time;
                    struct tm tm;
                    time_t time;
                    memset(&tm, 0, sizeof(tm));
                    strptime(attr_list->attr[i].data, "%Y%m%d%H%M%SZ", &tm);
                    time = mktime(&tm);
                    RtlSecondsSince1970ToTime(time, &win_time);
                    credential->LastWritten.dwLowDateTime = win_time.u.LowPart;
                    credential->LastWritten.dwHighDateTime = win_time.u.HighPart;
                }
                break;
        }
    }

    if (user)
    {
        INT str_len;
        if (buffer)
            credential->UserName = (LPWSTR)buffer;
        if (domain)
        {
            str_len = strlenW(domain);
            *len += (str_len + 1) * sizeof(WCHAR);
            if (buffer)
            {
                memcpy(credential->UserName, domain, str_len * sizeof(WCHAR));
                /* FIXME: figure out when to use an '@' */
                credential->UserName[str_len] = '\\';
                buffer += (str_len + 1) * sizeof(WCHAR);
            }
        }
        str_len = strlenW(user);
        *len += (str_len + 1) * sizeof(WCHAR);
        if (buffer)
        {
            memcpy(buffer, user, (str_len + 1) * sizeof(WCHAR));
            buffer += (str_len + 1) * sizeof(WCHAR);
            TRACE("UserName = %s\n", debugstr_w(credential->UserName));
        }
    }
    HeapFree(GetProcessHeap(), 0, user);
    HeapFree(GetProcessHeap(), 0, domain);

    if (cred_blob)
    {
        if (buffer)
        {
            INT str_len;
            credential->CredentialBlob = (BYTE *)buffer;
            str_len = MultiByteToWideChar(CP_UTF8, 0, cred_blob, cred_blob_len,
                                          (LPWSTR)buffer, 0xffff);
            credential->CredentialBlobSize = str_len * sizeof(WCHAR);
            buffer += str_len * sizeof(WCHAR);
            *len += str_len * sizeof(WCHAR);
        }
        else
        {
            INT str_len;
            str_len = MultiByteToWideChar(CP_UTF8, 0, cred_blob, cred_blob_len,
                                          NULL, 0);
            *len += str_len * sizeof(WCHAR);
        }
    }
    SecKeychainItemFreeAttributesAndData(attr_list, cred_blob);
    return ERROR_SUCCESS;
}
#endif

static DWORD write_credential_blob(HKEY hkey, LPCWSTR target_name, DWORD type,
                                   const BYTE key_data[KEY_SIZE],
                                   const BYTE *credential_blob, DWORD credential_blob_size)
{
    LPBYTE encrypted_credential_blob;
    struct ustring data;
    struct ustring key;
    DWORD ret;

    key.Length = key.MaximumLength = sizeof(key_data);
    key.Buffer = (unsigned char *)key_data;

    encrypted_credential_blob = HeapAlloc(GetProcessHeap(), 0, credential_blob_size);
    if (!encrypted_credential_blob) return ERROR_OUTOFMEMORY;

    memcpy(encrypted_credential_blob, credential_blob, credential_blob_size);
    data.Length = data.MaximumLength = credential_blob_size;
    data.Buffer = encrypted_credential_blob;
    SystemFunction032(&data, &key);

    ret = RegSetValueExW(hkey, wszPasswordValue, 0, REG_BINARY, (LPVOID)encrypted_credential_blob, credential_blob_size);
    HeapFree(GetProcessHeap(), 0, encrypted_credential_blob);

    return ret;
}

static DWORD registry_write_credential(HKEY hkey, const CREDENTIALW *credential,
                                       const BYTE key_data[KEY_SIZE], BOOL preserve_blob)
{
    DWORD ret;
    FILETIME LastWritten;

    GetSystemTimeAsFileTime(&LastWritten);

    ret = RegSetValueExW(hkey, wszFlagsValue, 0, REG_DWORD, (LPVOID)&credential->Flags,
                         sizeof(credential->Flags));
    if (ret != ERROR_SUCCESS) return ret;
    ret = RegSetValueExW(hkey, wszTypeValue, 0, REG_DWORD, (LPVOID)&credential->Type,
                         sizeof(credential->Type));
    if (ret != ERROR_SUCCESS) return ret;
    ret = RegSetValueExW(hkey, NULL, 0, REG_SZ, (LPVOID)credential->TargetName,
                         sizeof(WCHAR)*(strlenW(credential->TargetName)+1));
    if (ret != ERROR_SUCCESS) return ret;
    if (credential->Comment)
    {
        ret = RegSetValueExW(hkey, wszCommentValue, 0, REG_SZ, (LPVOID)credential->Comment,
                             sizeof(WCHAR)*(strlenW(credential->Comment)+1));
        if (ret != ERROR_SUCCESS) return ret;
    }
    ret = RegSetValueExW(hkey, wszLastWrittenValue, 0, REG_BINARY, (LPVOID)&LastWritten,
                         sizeof(LastWritten));
    if (ret != ERROR_SUCCESS) return ret;
    ret = RegSetValueExW(hkey, wszPersistValue, 0, REG_DWORD, (LPVOID)&credential->Persist,
                         sizeof(credential->Persist));
    if (ret != ERROR_SUCCESS) return ret;
    /* FIXME: Attributes */
    if (credential->TargetAlias)
    {
        ret = RegSetValueExW(hkey, wszTargetAliasValue, 0, REG_SZ, (LPVOID)credential->TargetAlias,
                             sizeof(WCHAR)*(strlenW(credential->TargetAlias)+1));
        if (ret != ERROR_SUCCESS) return ret;
    }
    if (credential->UserName)
    {
        ret = RegSetValueExW(hkey, wszUserNameValue, 0, REG_SZ, (LPVOID)credential->UserName,
                             sizeof(WCHAR)*(strlenW(credential->UserName)+1));
        if (ret != ERROR_SUCCESS) return ret;
    }
    if (!preserve_blob)
    {
        ret = write_credential_blob(hkey, credential->TargetName, credential->Type,
                                    key_data, credential->CredentialBlob,
                                    credential->CredentialBlobSize);
    }
    return ret;
}

#ifdef __APPLE__
static DWORD mac_write_credential(const CREDENTIALW *credential, BOOL preserve_blob)
{
    OSStatus status;
    SecKeychainItemRef keychain_item;
    char *username;
    char *domain = NULL;
    char *password;
    char *servername;
    UInt32 userlen;
    UInt32 domainlen = 0;
    UInt32 pwlen;
    UInt32 serverlen;
    LPCWSTR p;
    SecKeychainAttribute attrs[1];
    SecKeychainAttributeList attr_list;

    if (credential->Flags)
        FIXME("Flags 0x%x not written\n", credential->Flags);
    if (credential->Type != CRED_TYPE_DOMAIN_PASSWORD)
        FIXME("credential type of %d not supported\n", credential->Type);
    if (credential->Persist != CRED_PERSIST_LOCAL_MACHINE)
        FIXME("persist value of %d not supported\n", credential->Persist);
    if (credential->AttributeCount)
        FIXME("custom attributes not supported\n");

    p = strchrW(credential->UserName, '\\');
    if (p)
    {
        domainlen = WideCharToMultiByte(CP_UTF8, 0, credential->UserName,
                                        p - credential->UserName, NULL, 0, NULL, NULL);
        domain = HeapAlloc(GetProcessHeap(), 0, (domainlen + 1) * sizeof(*domain));
        WideCharToMultiByte(CP_UTF8, 0, credential->UserName, p - credential->UserName,
                            domain, domainlen, NULL, NULL);
        domain[domainlen] = '\0';
        p++;
    }
    else
        p = credential->UserName;
    userlen = WideCharToMultiByte(CP_UTF8, 0, p, -1, NULL, 0, NULL, NULL);
    username = HeapAlloc(GetProcessHeap(), 0, userlen * sizeof(*username));
    WideCharToMultiByte(CP_UTF8, 0, p, -1, username, userlen, NULL, NULL);

    serverlen = WideCharToMultiByte(CP_UTF8, 0, credential->TargetName, -1, NULL, 0, NULL, NULL);
    servername = HeapAlloc(GetProcessHeap(), 0, serverlen * sizeof(*servername));
    WideCharToMultiByte(CP_UTF8, 0, credential->TargetName, -1, servername, serverlen, NULL, NULL);
    pwlen = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)credential->CredentialBlob,
                                credential->CredentialBlobSize / sizeof(WCHAR), NULL, 0, NULL, NULL);
    password = HeapAlloc(GetProcessHeap(), 0, pwlen * sizeof(*domain));
    WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)credential->CredentialBlob,
                        credential->CredentialBlobSize / sizeof(WCHAR), password, pwlen, NULL, NULL);

    TRACE("adding server %s, domain %s, username %s using Keychain\n", servername, domain, username);
    status = SecKeychainAddInternetPassword(NULL, strlen(servername), servername,
                                            strlen(domain), domain, strlen(username),
                                            username, 0, NULL, 0,
                                            0 /* no protocol */,
                                            kSecAuthenticationTypeDefault,
                                            strlen(password), password, &keychain_item);
    if (status != noErr)
        ERR("SecKeychainAddInternetPassword returned %ld\n", status);
    if (status == errSecDuplicateItem)
    {
        SecKeychainItemRef keychain_item;

        status = SecKeychainFindInternetPassword(NULL, strlen(servername), servername,
                                                 strlen(domain), domain,
                                                 strlen(username), username,
                                                 0, NULL /* any path */, 0,
                                                 0 /* any protocol */,
                                                 0 /* any authentication type */,
                                                 0, NULL, &keychain_item);
        if (status != noErr)
            ERR("SecKeychainFindInternetPassword returned %ld\n", status);
    }
    HeapFree(GetProcessHeap(), 0, domain);
    HeapFree(GetProcessHeap(), 0, username);
    HeapFree(GetProcessHeap(), 0, servername);
    if (status != noErr)
    {
        HeapFree(GetProcessHeap(), 0, password);
        return ERROR_GEN_FAILURE;
    }
    if (credential->Comment)
    {
        attr_list.count = 1;
        attr_list.attr = attrs;
        attrs[0].tag = kSecCommentItemAttr;
        attrs[0].length = WideCharToMultiByte(CP_UTF8, 0, credential->Comment, -1, NULL, 0, NULL, NULL);
        if (attrs[0].length) attrs[0].length--;
        attrs[0].data = HeapAlloc(GetProcessHeap(), 0, attrs[0].length);
        WideCharToMultiByte(CP_UTF8, 0, credential->Comment, -1, attrs[0].data, attrs[0].length, NULL, NULL);
    }
    else
    {
        attr_list.count = 0;
        attr_list.attr = NULL;
    }
    status = SecKeychainItemModifyAttributesAndData(keychain_item, &attr_list,
                                                    preserve_blob ? 0 : strlen(password),
                                                    preserve_blob ? NULL : password);
    if (credential->Comment)
        HeapFree(GetProcessHeap(), 0, attrs[0].data);
    HeapFree(GetProcessHeap(), 0, password);
    /* FIXME: set TargetAlias attribute */
    CFRelease(keychain_item);
    return ERROR_SUCCESS;
}
#endif

static DWORD open_cred_mgr_key(HKEY *hkey, BOOL open_for_write)
{
    return RegCreateKeyExW(HKEY_CURRENT_USER, wszCredentialManagerKey, 0,
                           NULL, REG_OPTION_NON_VOLATILE,
                           KEY_READ | (open_for_write ? KEY_WRITE : 0), NULL, hkey, NULL);
}

static DWORD get_cred_mgr_encryption_key(HKEY hkeyMgr, BYTE key_data[KEY_SIZE])
{
    static const BYTE my_key_data[KEY_SIZE] = { 0 };
    DWORD type;
    DWORD count;
    FILETIME ft;
    ULONG seed;
    ULONG value;
    DWORD ret;

    memcpy(key_data, my_key_data, KEY_SIZE);

    count = KEY_SIZE;
    ret = RegQueryValueExW(hkeyMgr, wszEncryptionKeyValue, NULL, &type, (LPVOID)key_data,
                           &count);
    if (ret == ERROR_SUCCESS)
    {
        if (type != REG_BINARY)
            return ERROR_REGISTRY_CORRUPT;
        else
            return ERROR_SUCCESS;
    }
    if (ret != ERROR_FILE_NOT_FOUND)
        return ret;

    GetSystemTimeAsFileTime(&ft);
    seed = ft.dwLowDateTime;
    value = RtlUniform(&seed);
    *(DWORD *)key_data = value;
    seed = ft.dwHighDateTime;
    value = RtlUniform(&seed);
    *(DWORD *)(key_data + 4) = value;

    ret = RegSetValueExW(hkeyMgr, wszEncryptionKeyValue, 0, REG_BINARY,
                         (LPVOID)key_data, KEY_SIZE);
    if (ret == ERROR_ACCESS_DENIED)
    {
        ret = open_cred_mgr_key(&hkeyMgr, TRUE);
        if (ret == ERROR_SUCCESS)
        {
            ret = RegSetValueExW(hkeyMgr, wszEncryptionKeyValue, 0, REG_BINARY,
                                 (LPVOID)key_data, KEY_SIZE);
            RegCloseKey(hkeyMgr);
        }
    }
    return ret;
}

static LPWSTR get_key_name_for_target(LPCWSTR target_name, DWORD type)
{
    static const WCHAR wszGenericPrefix[] = {'G','e','n','e','r','i','c',':',' ',0};
    static const WCHAR wszDomPasswdPrefix[] = {'D','o','m','P','a','s','s','w','d',':',' ',0};
    INT len;
    LPCWSTR prefix = NULL;
    LPWSTR key_name, p;

    len = strlenW(target_name);
    if (type == CRED_TYPE_GENERIC)
    {
        prefix = wszGenericPrefix;
        len += sizeof(wszGenericPrefix)/sizeof(wszGenericPrefix[0]);
    }
    else
    {
        prefix = wszDomPasswdPrefix;
        len += sizeof(wszDomPasswdPrefix)/sizeof(wszDomPasswdPrefix[0]);
    }

    key_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!key_name) return NULL;

    strcpyW(key_name, prefix);
    strcatW(key_name, target_name);

    for (p = key_name; *p; p++)
        if (*p == '\\') *p = '_';

    return key_name;
}

static BOOL credential_matches_filter(HKEY hkeyCred, LPCWSTR filter)
{
    LPWSTR target_name;
    DWORD ret;
    DWORD type;
    DWORD count;
    LPCWSTR p;

    if (!filter) return TRUE;

    ret = RegQueryValueExW(hkeyCred, NULL, 0, &type, NULL, &count);
    if (ret != ERROR_SUCCESS)
        return FALSE;
    else if (type != REG_SZ)
        return FALSE;

    target_name = HeapAlloc(GetProcessHeap(), 0, count);
    if (!target_name)
        return FALSE;
    ret = RegQueryValueExW(hkeyCred, NULL, 0, &type, (LPVOID)target_name, &count);
    if (ret != ERROR_SUCCESS || type != REG_SZ)
    {
        HeapFree(GetProcessHeap(), 0, target_name);
        return FALSE;
    }

    TRACE("comparing filter %s to target name %s\n", debugstr_w(filter),
          debugstr_w(target_name));

    p = strchrW(filter, '*');
    ret = CompareStringW(GetThreadLocale(), 0, filter,
                         (p && !p[1] ? p - filter : -1), target_name,
                         (p && !p[1] ? p - filter : -1)) == CSTR_EQUAL;

    HeapFree(GetProcessHeap(), 0, target_name);
    return ret;
}

static DWORD registry_enumerate_credentials(HKEY hkeyMgr, LPCWSTR filter,
                                            LPWSTR target_name,
                                            DWORD target_name_len, BYTE key_data[KEY_SIZE],
                                            PCREDENTIALW *credentials, char **buffer,
                                            DWORD *len, DWORD *count)
{
    DWORD i;
    DWORD ret;
    for (i = 0;; i++)
    {
        HKEY hkeyCred;
        ret = RegEnumKeyW(hkeyMgr, i, target_name, target_name_len+1);
        if (ret == ERROR_NO_MORE_ITEMS)
        {
            ret = ERROR_SUCCESS;
            break;
        }
        else if (ret != ERROR_SUCCESS)
        {
            ret = ERROR_SUCCESS;
            continue;
        }
        TRACE("target_name = %s\n", debugstr_w(target_name));
        ret = RegOpenKeyExW(hkeyMgr, target_name, 0, KEY_QUERY_VALUE, &hkeyCred);
        if (ret != ERROR_SUCCESS)
        {
            ret = ERROR_SUCCESS;
            continue;
        }
        if (!credential_matches_filter(hkeyCred, filter))
        {
            RegCloseKey(hkeyCred);
            continue;
        }
        if (buffer)
        {
            *len = sizeof(CREDENTIALW);
            credentials[*count] = (PCREDENTIALW)*buffer;
        }
        else
            *len += sizeof(CREDENTIALW);
        ret = registry_read_credential(hkeyCred, buffer ? credentials[*count] : NULL,
                                       key_data, buffer ? *buffer + sizeof(CREDENTIALW) : NULL,
                                       len);
        RegCloseKey(hkeyCred);
        if (ret != ERROR_SUCCESS) break;
        if (buffer) *buffer += *len;
        (*count)++;
    }
    return ret;
}

#ifdef __APPLE__
static DWORD mac_enumerate_credentials(LPCWSTR filter, PCREDENTIALW *credentials,
                                       char *buffer, DWORD *len, DWORD *count)
{
    SecKeychainSearchRef search;
    SecKeychainItemRef item;
    OSStatus status;
    Boolean saved_user_interaction_allowed;
    DWORD ret;

    SecKeychainGetUserInteractionAllowed(&saved_user_interaction_allowed);
    SecKeychainSetUserInteractionAllowed(false);

    status = SecKeychainSearchCreateFromAttributes(NULL, kSecInternetPasswordItemClass, NULL, &search);
    if (status == noErr)
    {
        while (SecKeychainSearchCopyNext(search, &item) == noErr)
        {
            SecKeychainAttributeInfo info;
            SecKeychainAttributeList *attr_list;
            UInt32 info_tags[] = { kSecServerItemAttr };
            info.count = sizeof(info_tags)/sizeof(info_tags[0]);
            info.tag = info_tags;
            info.format = NULL;
            status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, NULL, NULL);
            if (status != noErr)
            {
                WARN("SecKeychainItemCopyAttributesAndData returned status %ld\n", status);
                continue;
            }
            if (buffer)
            {
                *len = sizeof(CREDENTIALW);
                credentials[*count] = (PCREDENTIALW)buffer;
            }
            else
                *len += sizeof(CREDENTIALW);
            if (attr_list->count != 1 || attr_list->attr[0].tag != kSecServerItemAttr) continue;
            TRACE("server item: %.*s\n", (int)attr_list->attr[0].length, (char *)attr_list->attr[0].data);
            /* FIXME: filter based on attr_list->attr[0].data */
            SecKeychainItemFreeAttributesAndData(attr_list, NULL);
            ret = mac_read_credential_from_item(item, FALSE,
                                                buffer ? credentials[*count] : NULL,
                                                buffer ? buffer + sizeof(CREDENTIALW) : NULL,
                                                len);
            CFRelease(item);
            if (ret == ERROR_SUCCESS)
            {
                (*count)++;
                if (buffer) buffer += *len;
            }
        }
        CFRelease(search);
    }
    else
        ERR("SecKeychainSearchCreateFromAttributes returned status %ld\n", status);
    SecKeychainSetUserInteractionAllowed(saved_user_interaction_allowed);
    return ERROR_SUCCESS;
}

static DWORD mac_delete_credential(LPCWSTR TargetName)
{
    OSStatus status;
    SecKeychainSearchRef search;
    status = SecKeychainSearchCreateFromAttributes(NULL, kSecInternetPasswordItemClass, NULL, &search);
    if (status == noErr)
    {
        SecKeychainItemRef item;
        while (SecKeychainSearchCopyNext(search, &item) == noErr)
        {
            SecKeychainAttributeInfo info;
            SecKeychainAttributeList *attr_list;
            UInt32 info_tags[] = { kSecServerItemAttr };
            LPWSTR target_name;
            INT str_len;
            info.count = sizeof(info_tags)/sizeof(info_tags[0]);
            info.tag = info_tags;
            info.format = NULL;
            status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, NULL, NULL);
            if (status != noErr)
            {
                WARN("SecKeychainItemCopyAttributesAndData returned status %ld\n", status);
                continue;
            }
            if (attr_list->count != 1 || attr_list->attr[0].tag != kSecServerItemAttr)
            {
                CFRelease(item);
                continue;
            }
            str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, NULL, 0);
            target_name = HeapAlloc(GetProcessHeap(), 0, (str_len + 1) * sizeof(WCHAR));
            MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, target_name, str_len);
            /* nul terminate */
            target_name[str_len] = '\0';
            if (strcmpiW(TargetName, target_name))
            {
                CFRelease(item);
                HeapFree(GetProcessHeap(), 0, target_name);
                continue;
            }
            HeapFree(GetProcessHeap(), 0, target_name);
            SecKeychainItemFreeAttributesAndData(attr_list, NULL);
            SecKeychainItemDelete(item);
            CFRelease(item);
            CFRelease(search);

            return ERROR_SUCCESS;
        }
        CFRelease(search);
    }
    return ERROR_NOT_FOUND;
}
#endif

static void convert_PCREDENTIALW_to_PCREDENTIALA(const CREDENTIALW *CredentialW, PCREDENTIALA CredentialA, DWORD *len)
{
    char *buffer = (char *)CredentialA + sizeof(CREDENTIALA);
    INT string_len;

    *len += sizeof(CREDENTIALA);
    if (!CredentialA)
    {
        if (CredentialW->TargetName) *len += WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetName, -1, NULL, 0, NULL, NULL);
        if (CredentialW->Comment) *len += WideCharToMultiByte(CP_ACP, 0, CredentialW->Comment, -1, NULL, 0, NULL, NULL);
        *len += CredentialW->CredentialBlobSize;
        if (CredentialW->TargetAlias) *len += WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetAlias, -1, NULL, 0, NULL, NULL);
        if (CredentialW->UserName) *len += WideCharToMultiByte(CP_ACP, 0, CredentialW->UserName, -1, NULL, 0, NULL, NULL);

        return;
    }

    CredentialA->Flags = CredentialW->Flags;
    CredentialA->Type = CredentialW->Type;
    if (CredentialW->TargetName)
    {
        CredentialA->TargetName = buffer;
        string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetName, -1, CredentialA->TargetName, -1, NULL, NULL);
        buffer += string_len;
        *len += string_len;
    }
    else
        CredentialA->TargetName = NULL;
    if (CredentialW->Comment)
    {
        CredentialA->Comment = buffer;
        string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->Comment, -1, CredentialA->Comment, -1, NULL, NULL);
        buffer += string_len;
        *len += string_len;
    }
    else
        CredentialA->Comment = NULL;
    CredentialA->LastWritten = CredentialW->LastWritten;
    CredentialA->CredentialBlobSize = CredentialW->CredentialBlobSize;
    if (CredentialW->CredentialBlobSize)
    {
        CredentialA->CredentialBlob =(LPBYTE)buffer;
        memcpy(CredentialA->CredentialBlob, CredentialW->CredentialBlob,
               CredentialW->CredentialBlobSize);
        buffer += CredentialW->CredentialBlobSize;
        *len += CredentialW->CredentialBlobSize;
    }
    else
        CredentialA->CredentialBlob = NULL;
    CredentialA->Persist = CredentialW->Persist;
    CredentialA->AttributeCount = 0;
    CredentialA->Attributes = NULL; /* FIXME */
    if (CredentialW->TargetAlias)
    {
        CredentialA->TargetAlias = buffer;
        string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetAlias, -1, CredentialA->TargetAlias, -1, NULL, NULL);
        buffer += string_len;
        *len += string_len;
    }
    else
        CredentialA->TargetAlias = NULL;
    if (CredentialW->UserName)
    {
        CredentialA->UserName = buffer;
        string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->UserName, -1, CredentialA->UserName, -1, NULL, NULL);
        buffer += string_len;
        *len += string_len;
    }
    else
        CredentialA->UserName = NULL;
}

static void convert_PCREDENTIALA_to_PCREDENTIALW(const CREDENTIALA *CredentialA, PCREDENTIALW CredentialW, DWORD *len)
{
    char *buffer = (char *)CredentialW + sizeof(CREDENTIALW);
    INT string_len;

    *len += sizeof(CREDENTIALW);
    if (!CredentialW)
    {
        if (CredentialA->TargetName) *len += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetName, -1, NULL, 0);
        if (CredentialA->Comment) *len += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->Comment, -1, NULL, 0);
        *len += CredentialA->CredentialBlobSize;
        if (CredentialA->TargetAlias) *len += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetAlias, -1, NULL, 0);
        if (CredentialA->UserName) *len += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->UserName, -1, NULL, 0);

        return;
    }

    CredentialW->Flags = CredentialA->Flags;
    CredentialW->Type = CredentialA->Type;
    if (CredentialA->TargetName)
    {
        CredentialW->TargetName = (LPWSTR)buffer;
        string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetName, -1, CredentialW->TargetName, -1);
        buffer += sizeof(WCHAR) * string_len;
        *len += sizeof(WCHAR) * string_len;
    }
    else
        CredentialW->TargetName = NULL;
    if (CredentialA->Comment)
    {
        CredentialW->Comment = (LPWSTR)buffer;
        string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->Comment, -1, CredentialW->Comment, -1);
        buffer += sizeof(WCHAR) * string_len;
        *len += sizeof(WCHAR) * string_len;
    }
    else
        CredentialW->Comment = NULL;
    CredentialW->LastWritten = CredentialA->LastWritten;
    CredentialW->CredentialBlobSize = CredentialA->CredentialBlobSize;
    if (CredentialA->CredentialBlobSize)
    {
        CredentialW->CredentialBlob =(LPBYTE)buffer;
        memcpy(CredentialW->CredentialBlob, CredentialA->CredentialBlob,
               CredentialA->CredentialBlobSize);
        buffer += CredentialA->CredentialBlobSize;
        *len += CredentialA->CredentialBlobSize;
    }
    else
        CredentialW->CredentialBlob = NULL;
    CredentialW->Persist = CredentialA->Persist;
    CredentialW->AttributeCount = 0;
    CredentialW->Attributes = NULL; /* FIXME */
    if (CredentialA->TargetAlias)
    {
        CredentialW->TargetAlias = (LPWSTR)buffer;
        string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetAlias, -1, CredentialW->TargetAlias, -1);
        buffer += sizeof(WCHAR) * string_len;
        *len += sizeof(WCHAR) * string_len;
    }
    else
        CredentialW->TargetAlias = NULL;
    if (CredentialA->UserName)
    {
        CredentialW->UserName = (LPWSTR)buffer;
        string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->UserName, -1, CredentialW->UserName, -1);
        buffer += sizeof(WCHAR) * string_len;
        *len += sizeof(WCHAR) * string_len;
    }
    else
        CredentialW->UserName = NULL;
}

/******************************************************************************
 * CredDeleteA [ADVAPI32.@]
 */
BOOL WINAPI CredDeleteA(LPCSTR TargetName, DWORD Type, DWORD Flags)
{
    LPWSTR TargetNameW;
    DWORD len;
    BOOL ret;

    TRACE("(%s, %d, 0x%x)\n", debugstr_a(TargetName), Type, Flags);

    if (!TargetName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    len = MultiByteToWideChar(CP_ACP, 0, TargetName, -1, NULL, 0);
    TargetNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!TargetNameW)
    {
        SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }
    MultiByteToWideChar(CP_ACP, 0, TargetName, -1, TargetNameW, len);

    ret = CredDeleteW(TargetNameW, Type, Flags);

    HeapFree(GetProcessHeap(), 0, TargetNameW);

    return ret;
}

/******************************************************************************
 * CredDeleteW [ADVAPI32.@]
 */
BOOL WINAPI CredDeleteW(LPCWSTR TargetName, DWORD Type, DWORD Flags)
{
    HKEY hkeyMgr;
    DWORD ret;
    LPWSTR key_name;

    TRACE("(%s, %d, 0x%x)\n", debugstr_w(TargetName), Type, Flags);

    if (!TargetName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (Type != CRED_TYPE_GENERIC && Type != CRED_TYPE_DOMAIN_PASSWORD)
    {
        FIXME("unhandled type %d\n", Type);
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (Flags)
    {
        FIXME("unhandled flags 0x%x\n", Flags);
        SetLastError(ERROR_INVALID_FLAGS);
        return FALSE;
    }

#ifdef __APPLE__
    if (Type == CRED_TYPE_DOMAIN_PASSWORD)
    {
        ret = mac_delete_credential(TargetName);
        if (ret == ERROR_SUCCESS)
            return TRUE;
    }
#endif

    ret = open_cred_mgr_key(&hkeyMgr, TRUE);
    if (ret != ERROR_SUCCESS)
    {
        WARN("couldn't open/create manager key, error %d\n", ret);
        SetLastError(ERROR_NO_SUCH_LOGON_SESSION);
        return FALSE;
    }

    key_name = get_key_name_for_target(TargetName, Type);
    ret = RegDeleteKeyW(hkeyMgr, key_name);
    HeapFree(GetProcessHeap(), 0, key_name);
    RegCloseKey(hkeyMgr);
    if (ret != ERROR_SUCCESS)
    {
        SetLastError(ERROR_NOT_FOUND);
        return FALSE;
    }

    return TRUE;
}

/******************************************************************************
 * CredEnumerateA [ADVAPI32.@]
 */
BOOL WINAPI CredEnumerateA(LPCSTR Filter, DWORD Flags, DWORD *Count,
                           PCREDENTIALA **Credentials)
{
    LPWSTR FilterW;
    PCREDENTIALW *CredentialsW;
    DWORD i;
    DWORD len;
    char *buffer;

    TRACE("(%s, 0x%x, %p, %p)\n", debugstr_a(Filter), Flags, Count, Credentials);

    if (Filter)
    {
        len = MultiByteToWideChar(CP_ACP, 0, Filter, -1, NULL, 0);
        FilterW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (!FilterW)
        {
            SetLastError(ERROR_OUTOFMEMORY);
            return FALSE;
        }
        MultiByteToWideChar(CP_ACP, 0, Filter, -1, FilterW, len);
    }
    else
        FilterW = NULL;

    if (!CredEnumerateW(FilterW, Flags, Count, &CredentialsW))
    {
        HeapFree(GetProcessHeap(), 0, FilterW);
        return FALSE;
    }
    HeapFree(GetProcessHeap(), 0, FilterW);

    len = *Count * sizeof(PCREDENTIALA);
    for (i = 0; i < *Count; i++)
        convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], NULL, &len);

    *Credentials = HeapAlloc(GetProcessHeap(), 0, len);
    if (!*Credentials)
    {
        CredFree(CredentialsW);
        SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }

    buffer = (char *)&(*Credentials)[*Count];
    for (i = 0; i < *Count; i++)
    {
        len = 0;
        (*Credentials)[i] = (PCREDENTIALA)buffer;
        convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], (*Credentials)[i], &len);
        buffer += len;
    }

    CredFree(CredentialsW);

    return TRUE;
}

/******************************************************************************
 * CredEnumerateW [ADVAPI32.@]
 */
BOOL WINAPI CredEnumerateW(LPCWSTR Filter, DWORD Flags, DWORD *Count,
                           PCREDENTIALW **Credentials)
{
    HKEY hkeyMgr;
    DWORD ret;
    LPWSTR target_name;
    DWORD target_name_len;
    DWORD len;
    char *buffer;
    BYTE key_data[KEY_SIZE];

    TRACE("(%s, 0x%x, %p, %p)\n", debugstr_w(Filter), Flags, Count, Credentials);

    if (Flags)
    {
        SetLastError(ERROR_INVALID_FLAGS);
        return FALSE;
    }

    ret = open_cred_mgr_key(&hkeyMgr, FALSE);
    if (ret != ERROR_SUCCESS)
    {
        WARN("couldn't open/create manager key, error %d\n", ret);
        SetLastError(ERROR_NO_SUCH_LOGON_SESSION);
        return FALSE;
    }

    ret = get_cred_mgr_encryption_key(hkeyMgr, key_data);
    if (ret != ERROR_SUCCESS)
    {
        RegCloseKey(hkeyMgr);
        SetLastError(ret);
        return FALSE;
    }

    ret = RegQueryInfoKeyW(hkeyMgr, NULL, NULL, NULL, NULL, &target_name_len, NULL, NULL, NULL, NULL, NULL, NULL);
    if (ret != ERROR_SUCCESS)
    {
        RegCloseKey(hkeyMgr);
        SetLastError(ret);
        return FALSE;
    }

    target_name = HeapAlloc(GetProcessHeap(), 0, (target_name_len+1)*sizeof(WCHAR));
    if (!target_name)
    {
        RegCloseKey(hkeyMgr);
        SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }

    *Count = 0;
    len = 0;
    ret = registry_enumerate_credentials(hkeyMgr, Filter, target_name, target_name_len,
                                         key_data, NULL, NULL, &len, Count);
#ifdef __APPLE__
    if (ret == ERROR_SUCCESS)
        ret = mac_enumerate_credentials(Filter, NULL, NULL, &len, Count);
#endif
    if (ret == ERROR_SUCCESS && *Count == 0)
        ret = ERROR_NOT_FOUND;
    if (ret != ERROR_SUCCESS)
    {
        HeapFree(GetProcessHeap(), 0, target_name);
        RegCloseKey(hkeyMgr);
        SetLastError(ret);
        return FALSE;
    }
    len += *Count * sizeof(PCREDENTIALW);

    if (ret == ERROR_SUCCESS)
    {
        buffer = HeapAlloc(GetProcessHeap(), 0, len);
        *Credentials = (PCREDENTIALW *)buffer;
        if (buffer)
        {
            buffer += *Count * sizeof(PCREDENTIALW);
            *Count = 0;
            ret = registry_enumerate_credentials(hkeyMgr, Filter, target_name,
                                                 target_name_len, key_data,
                                                 *Credentials, &buffer, &len,
                                                 Count);
#ifdef __APPLE__
            if (ret == ERROR_SUCCESS)
                ret = mac_enumerate_credentials(Filter, *Credentials,
                                                buffer, &len, Count);
#endif
        }
        else
            ret = ERROR_OUTOFMEMORY;
    }

    HeapFree(GetProcessHeap(), 0, target_name);
    RegCloseKey(hkeyMgr);

    if (ret != ERROR_SUCCESS)
    {
        SetLastError(ret);
        return FALSE;
    }
    return TRUE;
}

/******************************************************************************
 * CredFree [ADVAPI32.@]
 */
VOID WINAPI CredFree(PVOID Buffer)
{
    HeapFree(GetProcessHeap(), 0, Buffer);
}

/******************************************************************************
 * CredReadA [ADVAPI32.@]
 */
BOOL WINAPI CredReadA(LPCSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALA *Credential)
{
    LPWSTR TargetNameW;
    PCREDENTIALW CredentialW;
    DWORD len;

    TRACE("(%s, %d, 0x%x, %p)\n", debugstr_a(TargetName), Type, Flags, Credential);

    if (!TargetName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    len = MultiByteToWideChar(CP_ACP, 0, TargetName, -1, NULL, 0);
    TargetNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    if (!TargetNameW)
    {
        SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }
    MultiByteToWideChar(CP_ACP, 0, TargetName, -1, TargetNameW, len);

    if (!CredReadW(TargetNameW, Type, Flags, &CredentialW))
    {
        HeapFree(GetProcessHeap(), 0, TargetNameW);
        return FALSE;
    }
    HeapFree(GetProcessHeap(), 0, TargetNameW);

    len = 0;
    convert_PCREDENTIALW_to_PCREDENTIALA(CredentialW, NULL, &len);
    *Credential = HeapAlloc(GetProcessHeap(), 0, len);
    if (!*Credential)
    {
        SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }
    len = 0;
    convert_PCREDENTIALW_to_PCREDENTIALA(CredentialW, *Credential, &len);

    CredFree(CredentialW);

    return TRUE;
}

/******************************************************************************
 * CredReadW [ADVAPI32.@]
 */
BOOL WINAPI CredReadW(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW *Credential)
{
    HKEY hkeyMgr;
    HKEY hkeyCred;
    DWORD ret;
    LPWSTR key_name;
    DWORD len;
    BYTE key_data[KEY_SIZE];

    TRACE("(%s, %d, 0x%x, %p)\n", debugstr_w(TargetName), Type, Flags, Credential);

    if (!TargetName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (Type != CRED_TYPE_GENERIC && Type != CRED_TYPE_DOMAIN_PASSWORD)
    {
        FIXME("unhandled type %d\n", Type);
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (Flags)
    {
        FIXME("unhandled flags 0x%x\n", Flags);
        SetLastError(ERROR_INVALID_FLAGS);
        return FALSE;
    }

#ifdef __APPLE__
    if (Type == CRED_TYPE_DOMAIN_PASSWORD)
    {
        OSStatus status;
        SecKeychainSearchRef search;
        status = SecKeychainSearchCreateFromAttributes(NULL, kSecInternetPasswordItemClass, NULL, &search);
        if (status == noErr)
        {
            SecKeychainItemRef item;
            while (SecKeychainSearchCopyNext(search, &item) == noErr)
            {
                SecKeychainAttributeInfo info;
                SecKeychainAttributeList *attr_list;
                UInt32 info_tags[] = { kSecServerItemAttr };
                LPWSTR target_name;
                INT str_len;
                info.count = sizeof(info_tags)/sizeof(info_tags[0]);
                info.tag = info_tags;
                info.format = NULL;
                status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, NULL, NULL);
                len = sizeof(**Credential);
                if (status != noErr)
                {
                    WARN("SecKeychainItemCopyAttributesAndData returned status %ld\n", status);
                    continue;
                }
                if (attr_list->count != 1 || attr_list->attr[0].tag != kSecServerItemAttr)
                {
                    CFRelease(item);
                    continue;
                }
                str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, NULL, 0);
                target_name = HeapAlloc(GetProcessHeap(), 0, (str_len + 1) * sizeof(WCHAR));
                MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, target_name, str_len);
                /* nul terminate */
                target_name[str_len] = '\0';
                if (strcmpiW(TargetName, target_name))
                {
                    CFRelease(item);
                    HeapFree(GetProcessHeap(), 0, target_name);
                    continue;
                }
                HeapFree(GetProcessHeap(), 0, target_name);
                SecKeychainItemFreeAttributesAndData(attr_list, NULL);
                ret = mac_read_credential_from_item(item, TRUE, NULL, NULL, &len);
                if (ret == ERROR_SUCCESS)
                {
                    *Credential = HeapAlloc(GetProcessHeap(), 0, len);
                    if (*Credential)
                    {
                        len = sizeof(**Credential);
                        ret = mac_read_credential_from_item(item, TRUE, *Credential,
                                                            (char *)(*Credential + 1), &len);
                    }
                    else
                        ret = ERROR_OUTOFMEMORY;
                    CFRelease(item);
                    CFRelease(search);
                    if (ret != ERROR_SUCCESS)
                    {
                        SetLastError(ret);
                        return FALSE;
                    }
                    return TRUE;
                }
                CFRelease(item);
            }
            CFRelease(search);
        }
    }
#endif

    ret = open_cred_mgr_key(&hkeyMgr, FALSE);
    if (ret != ERROR_SUCCESS)
    {
        WARN("couldn't open/create manager key, error %d\n", ret);
        SetLastError(ERROR_NO_SUCH_LOGON_SESSION);
        return FALSE;
    }

    ret = get_cred_mgr_encryption_key(hkeyMgr, key_data);
    if (ret != ERROR_SUCCESS)
    {
        RegCloseKey(hkeyMgr);
        SetLastError(ret);
        return FALSE;
    }

    key_name = get_key_name_for_target(TargetName, Type);
    ret = RegOpenKeyExW(hkeyMgr, key_name, 0, KEY_QUERY_VALUE, &hkeyCred);
    HeapFree(GetProcessHeap(), 0, key_name);
    if (ret != ERROR_SUCCESS)
    {
        TRACE("credentials for target name %s not found\n", debugstr_w(TargetName));
        SetLastError(ERROR_NOT_FOUND);
        return FALSE;
    }

    len = sizeof(**Credential);
    ret = registry_read_credential(hkeyCred, NULL, key_data, NULL, &len);
    if (ret == ERROR_SUCCESS)
    {
        *Credential = HeapAlloc(GetProcessHeap(), 0, len);
        if (*Credential)
        {
            len = sizeof(**Credential);
            ret = registry_read_credential(hkeyCred, *Credential, key_data,
                                           (char *)(*Credential + 1), &len);
        }
        else
            ret = ERROR_OUTOFMEMORY;
    }

    RegCloseKey(hkeyCred);
    RegCloseKey(hkeyMgr);

    if (ret != ERROR_SUCCESS)
    {
        SetLastError(ret);
        return FALSE;
    }
    return TRUE;
}

/******************************************************************************
 * CredWriteA [ADVAPI32.@]
 */
BOOL WINAPI CredWriteA(PCREDENTIALA Credential, DWORD Flags)
{
    BOOL ret;
    DWORD len;
    PCREDENTIALW CredentialW;

    TRACE("(%p, 0x%x)\n", Credential, Flags);

    if (!Credential || !Credential->TargetName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    len = 0;
    convert_PCREDENTIALA_to_PCREDENTIALW(Credential, NULL, &len);
    CredentialW = HeapAlloc(GetProcessHeap(), 0, len);
    if (!CredentialW)
    {
        SetLastError(ERROR_OUTOFMEMORY);
        return FALSE;
    }
    len = 0;
    convert_PCREDENTIALA_to_PCREDENTIALW(Credential, CredentialW, &len);

    ret = CredWriteW(CredentialW, Flags);

    HeapFree(GetProcessHeap(), 0, CredentialW);

    return ret;
}

/******************************************************************************
 * CredWriteW [ADVAPI32.@]
 */
BOOL WINAPI CredWriteW(PCREDENTIALW Credential, DWORD Flags)
{
    HKEY hkeyMgr;
    HKEY hkeyCred;
    DWORD ret;
    LPWSTR key_name;
    BYTE key_data[KEY_SIZE];

    TRACE("(%p, 0x%x)\n", Credential, Flags);

    if (!Credential || !Credential->TargetName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (Flags & ~CRED_PRESERVE_CREDENTIAL_BLOB)
    {
        FIXME("unhandled flags 0x%x\n", Flags);
        SetLastError(ERROR_INVALID_FLAGS);
        return FALSE;
    }

    if (Credential->Type != CRED_TYPE_GENERIC && Credential->Type != CRED_TYPE_DOMAIN_PASSWORD)
    {
        FIXME("unhandled type %d\n", Credential->Type);
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    TRACE("Credential->TargetName = %s\n", debugstr_w(Credential->TargetName));
    TRACE("Credential->UserName = %s\n", debugstr_w(Credential->UserName));

    if (Credential->Type == CRED_TYPE_DOMAIN_PASSWORD)
    {
        if (!Credential->UserName ||
            (!strchrW(Credential->UserName, '\\') && !strchrW(Credential->UserName, '@')))
        {
            ERR("bad username %s\n", debugstr_w(Credential->UserName));
            SetLastError(ERROR_BAD_USERNAME);
            return FALSE;
        }
    }

#ifdef __APPLE__
    if (!Credential->AttributeCount &&
        Credential->Type == CRED_TYPE_DOMAIN_PASSWORD &&
        (Credential->Persist == CRED_PERSIST_LOCAL_MACHINE || Credential->Persist == CRED_PERSIST_ENTERPRISE))
    {
        ret = mac_write_credential(Credential, Flags & CRED_PRESERVE_CREDENTIAL_BLOB);
        if (ret != ERROR_SUCCESS)
        {
            SetLastError(ret);
            return FALSE;
        }
        return TRUE;
    }
#endif

    ret = open_cred_mgr_key(&hkeyMgr, FALSE);
    if (ret != ERROR_SUCCESS)
    {
        WARN("couldn't open/create manager key, error %d\n", ret);
        SetLastError(ERROR_NO_SUCH_LOGON_SESSION);
        return FALSE;
    }

    ret = get_cred_mgr_encryption_key(hkeyMgr, key_data);
    if (ret != ERROR_SUCCESS)
    {
        RegCloseKey(hkeyMgr);
        SetLastError(ret);
        return FALSE;
    }

    key_name = get_key_name_for_target(Credential->TargetName, Credential->Type);
    ret = RegCreateKeyExW(hkeyMgr, key_name, 0, NULL,
                          Credential->Persist == CRED_PERSIST_SESSION ? REG_OPTION_VOLATILE : REG_OPTION_NON_VOLATILE,
                          KEY_READ|KEY_WRITE, NULL, &hkeyCred, NULL);
    HeapFree(GetProcessHeap(), 0, key_name);
    if (ret != ERROR_SUCCESS)
    {
        TRACE("credentials for target name %s not found\n",
              debugstr_w(Credential->TargetName));
        SetLastError(ERROR_NOT_FOUND);
        return FALSE;
    }

    ret = registry_write_credential(hkeyCred, Credential, key_data,
                                    Flags & CRED_PRESERVE_CREDENTIAL_BLOB);

    RegCloseKey(hkeyCred);
    RegCloseKey(hkeyMgr);

    if (ret != ERROR_SUCCESS)
    {
        SetLastError(ret);
        return FALSE;
    }
    return TRUE;
}
