/*
 * Copyright 2005 Jacek Caban
 *
 * 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>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "objbase.h"
#include "oaidl.h"
#include "rpcproxy.h"
#include "atliface.h"
#include "atlbase.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(atl);

static LONG dll_count;

/**************************************************************
 * ATLRegistrar implementation
 */

static const struct {
    WCHAR name[22];
    HKEY  key;
} root_keys[] = {
    {{'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T',0},
                    HKEY_CLASSES_ROOT},
    {{'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R',0},
                    HKEY_CURRENT_USER},
    {{'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0},
                    HKEY_LOCAL_MACHINE},
    {{'H','K','E','Y','_','U','S','E','R','S',0},
                    HKEY_USERS},
    {{'H','K','E','Y','_','P','E','R','F','O','R','M','A','N','C','E','_','D','A','T','A',0},
                    HKEY_PERFORMANCE_DATA},
    {{'H','K','E','Y','_','D','Y','N','_','D','A','T','A',0},
                    HKEY_DYN_DATA},
    {{'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0},
                    HKEY_CURRENT_CONFIG},
    {{'H','K','C','R',0}, HKEY_CLASSES_ROOT},
    {{'H','K','C','U',0}, HKEY_CURRENT_USER},
    {{'H','K','L','M',0}, HKEY_LOCAL_MACHINE},
    {{'H','K','U',0},     HKEY_USERS},
    {{'H','K','P','D',0}, HKEY_PERFORMANCE_DATA},
    {{'H','K','D','D',0}, HKEY_DYN_DATA},
    {{'H','K','C','C',0}, HKEY_CURRENT_CONFIG}
};

typedef struct rep_list_str {
    LPOLESTR key;
    LPOLESTR item;
    int key_len;
    struct rep_list_str *next;
} rep_list;

typedef struct {
    IRegistrar IRegistrar_iface;
    LONG ref;
    rep_list *rep;
} Registrar;

typedef struct {
    LPOLESTR str;
    DWORD alloc;
    DWORD len;
} strbuf;

static inline Registrar *impl_from_IRegistrar(IRegistrar *iface)
{
    return CONTAINING_RECORD(iface, Registrar, IRegistrar_iface);
}

static void strbuf_init(strbuf *buf)
{
    buf->str = HeapAlloc(GetProcessHeap(), 0, 128*sizeof(WCHAR));
    buf->alloc = 128;
    buf->len = 0;
}

static void strbuf_write(LPCOLESTR str, strbuf *buf, int len)
{
    if(len == -1)
        len = lstrlenW(str);
    if(buf->len+len+1 >= buf->alloc) {
        buf->alloc = (buf->len+len)<<1;
        buf->str = HeapReAlloc(GetProcessHeap(), 0, buf->str, buf->alloc*sizeof(WCHAR));
    }
    memcpy(buf->str+buf->len, str, len*sizeof(OLECHAR));
    buf->len += len;
    buf->str[buf->len] = '\0';
}

static HRESULT get_word(LPCOLESTR *str, strbuf *buf)
{
    LPCOLESTR iter, iter2 = *str;

    buf->len = 0;
    buf->str[0] = '\0';

    while(isspaceW(*iter2))
        iter2++;
    iter = iter2;
    if(!*iter) {
        *str = iter;
        return S_OK;
    }

    if(*iter == '}' || *iter == '=') {
        strbuf_write(iter++, buf, 1);
    }else if(*iter == '\'') {
        iter2 = ++iter;
        iter = strchrW(iter, '\'');
        if(!iter) {
            WARN("Unexpected end of script\n");
            *str = iter;
            return DISP_E_EXCEPTION;
        }
        strbuf_write(iter2, buf, iter-iter2);
        iter++;
    }else {
        while(*iter && !isspaceW(*iter))
            iter++;
        strbuf_write(iter2, buf, iter-iter2);
    }

    while(isspaceW(*iter))
        iter++;
    *str = iter;
    return S_OK;
}

static HRESULT do_preprocess(const Registrar *This, LPCOLESTR data, strbuf *buf)
{
    LPCOLESTR iter, iter2 = data;
    rep_list *rep_iter;
    static const WCHAR wstr[] = {'%',0};

    iter = strchrW(data, '%');
    while(iter) {
        strbuf_write(iter2, buf, iter-iter2);

        iter2 = ++iter;
        if(!*iter2)
            return DISP_E_EXCEPTION;
        iter = strchrW(iter2, '%');
        if(!iter)
            return DISP_E_EXCEPTION;

        if(iter == iter2) {
            strbuf_write(wstr, buf, 1);
        }else {
            for(rep_iter = This->rep; rep_iter; rep_iter = rep_iter->next) {
                if(rep_iter->key_len == iter-iter2
                        && !memicmpW(iter2, rep_iter->key, rep_iter->key_len))
                    break;
            }
            if(!rep_iter) {
                WARN("Could not find replacement: %s\n", debugstr_wn(iter2, iter-iter2));
                return DISP_E_EXCEPTION;
            }

            strbuf_write(rep_iter->item, buf, -1);
        }

        iter2 = ++iter;
        iter = strchrW(iter, '%');
    }

    strbuf_write(iter2, buf, -1);
    TRACE("%s\n", debugstr_w(buf->str));

    return S_OK;
}

static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register)
{
    LPCOLESTR iter = *pstr;
    HRESULT hres;
    LONG lres;
    HKEY hkey = 0;
    strbuf name;
    
    enum {
        NORMAL,
        NO_REMOVE,
        IS_VAL,
        FORCE_REMOVE,
        DO_DELETE
    } key_type = NORMAL; 

    static const WCHAR wstrNoRemove[] = {'N','o','R','e','m','o','v','e',0};
    static const WCHAR wstrForceRemove[] = {'F','o','r','c','e','R','e','m','o','v','e',0};
    static const WCHAR wstrDelete[] = {'D','e','l','e','t','e',0};
    static const WCHAR wstrval[] = {'v','a','l',0};

    iter = *pstr;
    hres = get_word(&iter, buf);
    if(FAILED(hres))
        return hres;
    strbuf_init(&name);

    while(buf->str[1] || buf->str[0] != '}') {
        key_type = NORMAL;
        if(!lstrcmpiW(buf->str, wstrNoRemove))
            key_type = NO_REMOVE;
        else if(!lstrcmpiW(buf->str, wstrForceRemove))
            key_type = FORCE_REMOVE;
        else if(!lstrcmpiW(buf->str, wstrval))
            key_type = IS_VAL;
        else if(!lstrcmpiW(buf->str, wstrDelete))
            key_type = DO_DELETE;

        if(key_type != NORMAL) {
            hres = get_word(&iter, buf);
            if(FAILED(hres))
                break;
        }
        TRACE("name = %s\n", debugstr_w(buf->str));
    
        if(do_register) {
            if(key_type == IS_VAL) {
                hkey = parent_key;
                strbuf_write(buf->str, &name, -1);
            }else if(key_type == DO_DELETE) {
                TRACE("Deleting %s\n", debugstr_w(buf->str));
                RegDeleteTreeW(parent_key, buf->str);
            }else {
                if(key_type == FORCE_REMOVE)
                    RegDeleteTreeW(parent_key, buf->str);
                lres = RegCreateKeyW(parent_key, buf->str, &hkey);
                if(lres != ERROR_SUCCESS) {
                    WARN("Could not create(open) key: %08x\n", lres);
                    hres = HRESULT_FROM_WIN32(lres);
                    break;
                }
            }
        }else if(key_type != IS_VAL && key_type != DO_DELETE) {
            strbuf_write(buf->str, &name, -1);
            lres = RegOpenKeyW(parent_key, buf->str, &hkey);
              if(lres != ERROR_SUCCESS)
                WARN("Could not open key %s: %08x\n", debugstr_w(name.str), lres);
        }

        if(key_type != DO_DELETE && *iter == '=') {
            iter++;
            hres = get_word(&iter, buf);
            if(FAILED(hres))
                break;
            if(buf->len != 1) {
                WARN("Wrong registry type: %s\n", debugstr_w(buf->str));
                hres = DISP_E_EXCEPTION;
                break;
            }
            if(do_register) {
                switch(buf->str[0]) {
                case 's':
                    hres = get_word(&iter, buf);
                    if(FAILED(hres))
                        break;
                    lres = RegSetValueExW(hkey, name.len ? name.str :  NULL, 0, REG_SZ, (PBYTE)buf->str,
                            (lstrlenW(buf->str)+1)*sizeof(WCHAR));
                    if(lres != ERROR_SUCCESS) {
                        WARN("Could set value of key: %08x\n", lres);
                        hres = HRESULT_FROM_WIN32(lres);
                        break;
                    }
                    break;
                case 'd': {
                    DWORD dw;
                    hres = get_word(&iter, buf);
                    if(FAILED(hres))
                        break;
                    dw = atoiW(buf->str);
                    lres = RegSetValueExW(hkey, name.len ? name.str :  NULL, 0, REG_DWORD,
                            (PBYTE)&dw, sizeof(dw));
                    if(lres != ERROR_SUCCESS) {
                        WARN("Could set value of key: %08x\n", lres);
                        hres = HRESULT_FROM_WIN32(lres);
                        break;
                    }
                    break;
                }
                case 'b': {
                    BYTE *bytes;
                    DWORD count;
                    DWORD i;
                    hres = get_word(&iter, buf);
                    if(FAILED(hres))
                        break;
                    count = (lstrlenW(buf->str) + 1) / 2;
                    bytes = HeapAlloc(GetProcessHeap(), 0, count);
                    if(bytes == NULL) {
                        hres = E_OUTOFMEMORY;
                        break;
                    }
                    for(i = 0; i < count && buf->str[2*i]; i++) {
                        WCHAR digits[3];
                        if(!isxdigitW(buf->str[2*i]) || !isxdigitW(buf->str[2*i + 1])) {
                            hres = E_FAIL;
                            break;
                        }
                        digits[0] = buf->str[2*i];
                        digits[1] = buf->str[2*i + 1];
                        digits[2] = 0;
                        bytes[i] = (BYTE) strtoulW(digits, NULL, 16);
                    }
                    if(SUCCEEDED(hres)) {
                        lres = RegSetValueExW(hkey, name.len ? name.str :  NULL, 0, REG_BINARY,
                            bytes, count);
                        if(lres != ERROR_SUCCESS) {
                            WARN("Could not set value of key: 0x%08x\n", lres);
                            hres = HRESULT_FROM_WIN32(lres);
                        }
                    }
                    HeapFree(GetProcessHeap(), 0, bytes);
                    break;
                }
                default:
                    WARN("Wrong resource type: %s\n", debugstr_w(buf->str));
                    hres = DISP_E_EXCEPTION;
                };
                if(FAILED(hres))
                    break;
            }else {
                if(*iter == '-')
                    iter++;
                hres = get_word(&iter, buf);
                if(FAILED(hres))
                    break;
            }
        }else if(key_type == IS_VAL) {
            WARN("value not set!\n");
            hres = DISP_E_EXCEPTION;
            break;
        }

        if(key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && isspaceW(iter[1])) {
            hres = get_word(&iter, buf);
            if(FAILED(hres))
                break;
            hres = do_process_key(&iter, hkey, buf, do_register);
            if(FAILED(hres))
                break;
        }

        TRACE("%x %x\n", do_register, key_type);
        if(!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) {
            TRACE("Deleting %s\n", debugstr_w(name.str));
            RegDeleteKeyW(parent_key, name.str);
        }

        if(hkey && key_type != IS_VAL)
            RegCloseKey(hkey);
        hkey = 0;
        name.len = 0;
        
        hres = get_word(&iter, buf);
        if(FAILED(hres))
            break;
    }

    HeapFree(GetProcessHeap(), 0, name.str);
    if(hkey && key_type != IS_VAL)
        RegCloseKey(hkey);
    *pstr = iter;
    return hres;
}

static HRESULT do_process_root_key(LPCOLESTR data, BOOL do_register)
{
    LPCOLESTR iter = data;
    strbuf buf;
    HRESULT hres = S_OK;
    unsigned int i;

    strbuf_init(&buf);
    hres = get_word(&iter, &buf);
    if(FAILED(hres))
        return hres;

    while(*iter) {
        if(!buf.len) {
            WARN("ward.len == 0, failed\n");
            hres = DISP_E_EXCEPTION;
            break;
        }
        for(i=0; i<sizeof(root_keys)/sizeof(root_keys[0]); i++) {
            if(!lstrcmpiW(buf.str, root_keys[i].name))
                break;
        }
        if(i == sizeof(root_keys)/sizeof(root_keys[0])) {
            WARN("Wrong root key name: %s\n", debugstr_w(buf.str));
            hres = DISP_E_EXCEPTION;
            break;
        }
        hres = get_word(&iter, &buf);
        if(FAILED(hres))
            break;
        if(buf.str[1] || buf.str[0] != '{') {
            WARN("Failed, expected '{', got %s\n", debugstr_w(buf.str));
            hres = DISP_E_EXCEPTION;
            break;
        }
        hres = do_process_key(&iter, root_keys[i].key, &buf, do_register);
        if(FAILED(hres)) {
            WARN("Processing key failed: %08x\n", hres);
            break;
        }
        hres = get_word(&iter, &buf);
        if(FAILED(hres))
            break;
    }
    HeapFree(GetProcessHeap(), 0, buf.str);
    return hres;
}

static HRESULT string_register(Registrar *This, LPCOLESTR data, BOOL do_register)
{
    strbuf buf;
    HRESULT hres;

    TRACE("(%p %s %x)\n", This, debugstr_w(data), do_register);

    strbuf_init(&buf);
    hres = do_preprocess(This, data, &buf);
    if(FAILED(hres)) {
        WARN("preprocessing failed!\n");
        HeapFree(GetProcessHeap(), 0, buf.str);
        return hres;
    }

    hres = do_process_root_key(buf.str, do_register);
    if(FAILED(hres) && do_register)
        do_process_root_key(buf.str, FALSE);

    HeapFree(GetProcessHeap(), 0, buf.str);
    return hres;
}

static HRESULT resource_register(Registrar *This, LPCOLESTR resFileName,
                        LPCOLESTR szID, LPCOLESTR szType, BOOL do_register)
{
    HINSTANCE hins;
    HRSRC src;
    LPSTR regstra;
    LPWSTR regstrw;
    DWORD len, reslen;
    HRESULT hres;

    hins = LoadLibraryExW(resFileName, NULL, LOAD_LIBRARY_AS_DATAFILE);
    if(hins) {
        src = FindResourceW(hins, szID, szType);
        if(src) {
            regstra = LoadResource(hins, src);
            reslen = SizeofResource(hins, src);
            if(regstra) {
                len = MultiByteToWideChar(CP_ACP, 0, regstra, reslen, NULL, 0)+1;
                regstrw = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR));
                MultiByteToWideChar(CP_ACP, 0, regstra, reslen, regstrw, len);
                regstrw[len-1] = '\0';

                hres = string_register(This, regstrw, do_register);

                HeapFree(GetProcessHeap(), 0, regstrw);
            }else {
                WARN("could not load resource\n");
                hres = HRESULT_FROM_WIN32(GetLastError());
            }
        }else {
            WARN("Could not find source\n");
            hres = HRESULT_FROM_WIN32(GetLastError());
        }
        FreeLibrary(hins);
    }else {
        WARN("Could not load resource file\n");
        hres = HRESULT_FROM_WIN32(GetLastError());
    }

    return hres;
}

static HRESULT file_register(Registrar *This, LPCOLESTR fileName, BOOL do_register)
{
    HANDLE file;
    DWORD filelen, len;
    LPWSTR regstrw;
    LPSTR regstra;
    LRESULT lres;
    HRESULT hres;

    file = CreateFileW(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
    if(file != INVALID_HANDLE_VALUE) {
        filelen = GetFileSize(file, NULL);
        regstra = HeapAlloc(GetProcessHeap(), 0, filelen);
        lres = ReadFile(file, regstra, filelen, NULL, NULL);
        if(lres == ERROR_SUCCESS) {
            len = MultiByteToWideChar(CP_ACP, 0, regstra, filelen, NULL, 0)+1;
            regstrw = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR));
            MultiByteToWideChar(CP_ACP, 0, regstra, filelen, regstrw, len);
            regstrw[len-1] = '\0';
            
            hres = string_register(This, regstrw, do_register);

            HeapFree(GetProcessHeap(), 0, regstrw);
        }else {
            WARN("Failed to read faile\n");
            hres = HRESULT_FROM_WIN32(lres);
        }
        HeapFree(GetProcessHeap(), 0, regstra);
        CloseHandle(file);
    }else {
        WARN("Could not open file\n");
        hres = HRESULT_FROM_WIN32(GetLastError());
    }

    return hres;
}

static HRESULT WINAPI Registrar_QueryInterface(IRegistrar *iface, REFIID riid, void **ppvObject)
{
    TRACE("(%p)->(%s %p\n", iface, debugstr_guid(riid), ppvObject);

    if(IsEqualGUID(&IID_IUnknown, riid)
       || IsEqualGUID(&IID_IRegistrar, riid)
       || IsEqualGUID(&IID_IRegistrarBase, riid)) {
        IRegistrar_AddRef(iface);
        *ppvObject = iface;
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI Registrar_AddRef(IRegistrar *iface)
{
    Registrar *This = impl_from_IRegistrar(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ->%d\n", This, ref);
    return ref;
}

static ULONG WINAPI Registrar_Release(IRegistrar *iface)
{
    Registrar *This = impl_from_IRegistrar(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ->%d\n", This, ref);
    if(!ref) {
        IRegistrar_ClearReplacements(iface);
        HeapFree(GetProcessHeap(), 0, This);
        InterlockedDecrement(&dll_count);
    }
    return ref;
}

static HRESULT WINAPI Registrar_AddReplacement(IRegistrar *iface, LPCOLESTR Key, LPCOLESTR item)
{
    Registrar *This = impl_from_IRegistrar(iface);
    int len;
    rep_list *new_rep;

    TRACE("(%p)->(%s %s)\n", This, debugstr_w(Key), debugstr_w(item));

    new_rep = HeapAlloc(GetProcessHeap(), 0, sizeof(rep_list));

    new_rep->key_len  = lstrlenW(Key);
    new_rep->key = HeapAlloc(GetProcessHeap(), 0, (new_rep->key_len + 1) * sizeof(OLECHAR));
    memcpy(new_rep->key, Key, (new_rep->key_len+1)*sizeof(OLECHAR));

    len = lstrlenW(item)+1;
    new_rep->item = HeapAlloc(GetProcessHeap(), 0, len*sizeof(OLECHAR));
    memcpy(new_rep->item, item, len*sizeof(OLECHAR));

    new_rep->next = This->rep;
    This->rep = new_rep;
    
    return S_OK;
}

static HRESULT WINAPI Registrar_ClearReplacements(IRegistrar *iface)
{
    Registrar *This = impl_from_IRegistrar(iface);
    rep_list *iter, *iter2;

    TRACE("(%p)\n", This);

    if(!This->rep)
        return S_OK;

    iter = This->rep;
    while(iter) {
        iter2 = iter->next;
        HeapFree(GetProcessHeap(), 0, iter->key);
        HeapFree(GetProcessHeap(), 0, iter->item);
        HeapFree(GetProcessHeap(), 0, iter);
        iter = iter2;
    }

    This->rep = NULL;
    return S_OK;
}

static HRESULT WINAPI Registrar_ResourceRegisterSz(IRegistrar* iface, LPCOLESTR resFileName,
                LPCOLESTR szID, LPCOLESTR szType)
{
    Registrar *This = impl_from_IRegistrar(iface);
    TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(resFileName), debugstr_w(szID), debugstr_w(szType));
    return resource_register(This, resFileName, szID, szType, TRUE);
}

static HRESULT WINAPI Registrar_ResourceUnregisterSz(IRegistrar* iface, LPCOLESTR resFileName,
                LPCOLESTR szID, LPCOLESTR szType)
{
    Registrar *This = impl_from_IRegistrar(iface);
    TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(resFileName), debugstr_w(szID), debugstr_w(szType));
    return resource_register(This, resFileName, szID, szType, FALSE);
}

static HRESULT WINAPI Registrar_FileRegister(IRegistrar* iface, LPCOLESTR fileName)
{
    Registrar *This = impl_from_IRegistrar(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(fileName));
    return file_register(This, fileName, TRUE);
}

static HRESULT WINAPI Registrar_FileUnregister(IRegistrar* iface, LPCOLESTR fileName)
{
    Registrar *This = impl_from_IRegistrar(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(fileName));
    return file_register(This, fileName, FALSE);
}

static HRESULT WINAPI Registrar_StringRegister(IRegistrar* iface, LPCOLESTR data)
{
    Registrar *This = impl_from_IRegistrar(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(data));
    return string_register(This, data, TRUE);
}

static HRESULT WINAPI Registrar_StringUnregister(IRegistrar* iface, LPCOLESTR data)
{
    Registrar *This = impl_from_IRegistrar(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_w(data));
    return string_register(This, data, FALSE);
}

static HRESULT WINAPI Registrar_ResourceRegister(IRegistrar* iface, LPCOLESTR resFileName,
                UINT nID, LPCOLESTR szType)
{
    Registrar *This = impl_from_IRegistrar(iface);
    TRACE("(%p)->(%s %d %s)\n", iface, debugstr_w(resFileName), nID, debugstr_w(szType));
    return resource_register(This, resFileName, MAKEINTRESOURCEW(nID), szType, TRUE);
}

static HRESULT WINAPI Registrar_ResourceUnregister(IRegistrar* iface, LPCOLESTR resFileName,
                UINT nID, LPCOLESTR szType)
{
    Registrar *This = impl_from_IRegistrar(iface);
    TRACE("(%p)->(%s %d %s)\n", This, debugstr_w(resFileName), nID, debugstr_w(szType));
    return resource_register(This, resFileName, MAKEINTRESOURCEW(nID), szType, FALSE);
}

static const IRegistrarVtbl RegistrarVtbl = {
    Registrar_QueryInterface,
    Registrar_AddRef,
    Registrar_Release,
    Registrar_AddReplacement,
    Registrar_ClearReplacements,
    Registrar_ResourceRegisterSz,
    Registrar_ResourceUnregisterSz,
    Registrar_FileRegister,
    Registrar_FileUnregister,
    Registrar_StringRegister,
    Registrar_StringUnregister,
    Registrar_ResourceRegister,
    Registrar_ResourceUnregister,
};

static HRESULT Registrar_create(const IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
{
    Registrar *ret;

    if(!IsEqualGUID(&IID_IUnknown, riid) && !IsEqualGUID(&IID_IRegistrar, riid))
        return E_NOINTERFACE;

    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(Registrar));
    ret->IRegistrar_iface.lpVtbl = &RegistrarVtbl;
    ret->ref = 1;
    ret->rep = NULL;
    *ppvObject = ret;

    InterlockedIncrement(&dll_count);

    return S_OK;
}

/**************************************************************
 * ClassFactory implementation
 */

static HRESULT WINAPI RegistrarCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject)
{
    TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);

    if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
        *ppvObject = iface;
        IClassFactory_AddRef( iface );
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI RegistrarCF_AddRef(IClassFactory *iface)
{
    InterlockedIncrement(&dll_count);
    return 2;
}

static ULONG WINAPI RegistrarCF_Release(IClassFactory *iface)
{
    InterlockedDecrement(&dll_count);
    return 1;
}

static HRESULT WINAPI RegistrarCF_CreateInstance(IClassFactory *iface, LPUNKNOWN pUnkOuter,
                                                REFIID riid, void **ppvObject)
{
    TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
    return Registrar_create(pUnkOuter, riid, ppvObject);
}

static HRESULT WINAPI RegistrarCF_LockServer(IClassFactory *iface, BOOL lock)
{
    TRACE("(%p)->(%x)\n", iface, lock);

    if(lock)
        InterlockedIncrement(&dll_count);
    else
        InterlockedDecrement(&dll_count);

    return S_OK;
}

static const IClassFactoryVtbl IRegistrarCFVtbl = {
    RegistrarCF_QueryInterface,
    RegistrarCF_AddRef,
    RegistrarCF_Release,
    RegistrarCF_CreateInstance,
    RegistrarCF_LockServer
};

static IClassFactory RegistrarCF = { &IRegistrarCFVtbl };

/**************************************************************
 * DllGetClassObject (ATL.2)
 */
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, LPVOID *ppvObject)
{
    TRACE("(%s %s %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppvObject);

    if(IsEqualGUID(&CLSID_Registrar, clsid))
        return IClassFactory_QueryInterface( &RegistrarCF, riid, ppvObject );

    FIXME("Not supported class %s\n", debugstr_guid(clsid));
    return CLASS_E_CLASSNOTAVAILABLE;
}

extern HINSTANCE hInst;

static HRESULT do_register_dll_server(IRegistrar *pRegistrar, LPCOLESTR wszDll,
                                      LPCOLESTR wszId, BOOL do_register,
                                      const struct _ATL_REGMAP_ENTRY* pMapEntries)
{
    IRegistrar *registrar;
    HRESULT hres;
    const struct _ATL_REGMAP_ENTRY *pMapEntry;

    static const WCHAR wszModule[] = {'M','O','D','U','L','E',0};
    static const WCHAR wszRegistry[] = {'R','E','G','I','S','T','R','Y',0};

    if (pRegistrar)
        registrar = pRegistrar;
    else
        Registrar_create(NULL, &IID_IRegistrar, (void**)&registrar);

    IRegistrar_AddReplacement(registrar, wszModule, wszDll);

    for (pMapEntry = pMapEntries; pMapEntry && pMapEntry->szKey; pMapEntry++)
        IRegistrar_AddReplacement(registrar, pMapEntry->szKey, pMapEntry->szData);

    if(do_register)
        hres = IRegistrar_ResourceRegisterSz(registrar, wszDll, wszId, wszRegistry);
    else
        hres = IRegistrar_ResourceUnregisterSz(registrar, wszDll, wszId, wszRegistry);

    if(registrar != pRegistrar)
        IRegistrar_Release(registrar);
    return hres;
}

/***********************************************************************
 *           AtlModuleUpdateRegistryFromResourceD         [ATL.@]
 *
 */
HRESULT WINAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULEW* pM, LPCOLESTR lpszRes,
		BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg)
{
    HINSTANCE lhInst = pM->m_hInst;
    /* everything inside this function below this point
     * should go into atl71.AtlUpdateRegistryFromResourceD
     */
    WCHAR module_name[MAX_PATH];

    if(!GetModuleFileNameW(lhInst, module_name, MAX_PATH)) {
        FIXME("hinst %p: did not get module name\n",
        lhInst);
        return E_FAIL;
    }

    TRACE("%p (%s), %s, %d, %p, %p\n", hInst, debugstr_w(module_name),
	debugstr_w(lpszRes), bRegister, pMapEntries, pReg);

    return do_register_dll_server(pReg, module_name, lpszRes, bRegister, pMapEntries);
}

/***********************************************************************
 *              DllRegisterServer (ATL.@)
 */
HRESULT WINAPI DllRegisterServer(void)
{
    return __wine_register_resources( hInst );
}

/***********************************************************************
 *              DllUnRegisterServer (ATL.@)
 */
HRESULT WINAPI DllUnregisterServer(void)
{
    return __wine_unregister_resources( hInst );
}

/***********************************************************************
 *              DllCanUnloadNow (ATL.@)
 */
HRESULT WINAPI DllCanUnloadNow(void)
{
    TRACE("dll_count = %u\n", dll_count);
    return dll_count ? S_FALSE : S_OK;
}
