/*
 * Copyright 2012 Stefan Leichter
 * Copyright 2012 Jacek Caban 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
 */

#define COBJMACROS

#include "atlbase.h"
#include "atlcom.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(atl);

#define ATLVer1Size FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer)

HINSTANCE atl_instance;

typedef unsigned char cpp_bool;

static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t size)
{
    return HeapAlloc(GetProcessHeap(), 0, size);
}

static inline BOOL heap_free(void *mem)
{
    return HeapFree(GetProcessHeap(), 0, mem);
}

static ICatRegister *catreg;

/***********************************************************************
 *           AtlAdvise         [atl100.@]
 */
HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, DWORD *pdw)
{
    IConnectionPointContainer *container;
    IConnectionPoint *cp;
    HRESULT hres;

    TRACE("%p %p %p %p\n", pUnkCP, pUnk, iid, pdw);

    if(!pUnkCP)
        return E_INVALIDARG;

    hres = IUnknown_QueryInterface(pUnkCP, &IID_IConnectionPointContainer, (void**)&container);
    if(FAILED(hres))
        return hres;

    hres = IConnectionPointContainer_FindConnectionPoint(container, iid, &cp);
    IConnectionPointContainer_Release(container);
    if(FAILED(hres))
        return hres;

    hres = IConnectionPoint_Advise(cp, pUnk, pdw);
    IConnectionPoint_Release(cp);
    return hres;
}

/***********************************************************************
 *           AtlUnadvise         [atl100.@]
 */
HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw)
{
    IConnectionPointContainer *container;
    IConnectionPoint *cp;
    HRESULT hres;

    TRACE("%p %p %d\n", pUnkCP, iid, dw);

    if(!pUnkCP)
        return E_INVALIDARG;

    hres = IUnknown_QueryInterface(pUnkCP, &IID_IConnectionPointContainer, (void**)&container);
    if(FAILED(hres))
        return hres;

    hres = IConnectionPointContainer_FindConnectionPoint(container, iid, &cp);
    IConnectionPointContainer_Release(container);
    if(FAILED(hres))
        return hres;

    hres = IConnectionPoint_Unadvise(cp, dw);
    IConnectionPoint_Release(cp);
    return hres;
}

/***********************************************************************
 *           AtlFreeMarshalStream         [atl100.@]
 */
HRESULT WINAPI AtlFreeMarshalStream(IStream *stm)
{
    FIXME("%p\n", stm);
    return S_OK;
}

/***********************************************************************
 *           AtlMarshalPtrInProc         [atl100.@]
 */
HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **pstm)
{
    FIXME("%p %p %p\n", pUnk, iid, pstm);
    return E_FAIL;
}

/***********************************************************************
 *           AtlUnmarshalPtr              [atl100.@]
 */
HRESULT WINAPI AtlUnmarshalPtr(IStream *stm, const IID *iid, IUnknown **ppUnk)
{
    FIXME("%p %p %p\n", stm, iid, ppUnk);
    return E_FAIL;
}

/***********************************************************************
 *           AtlCreateTargetDC         [atl100.@]
 */
HDC WINAPI AtlCreateTargetDC( HDC hdc, DVTARGETDEVICE *dv )
{
    static const WCHAR displayW[] = {'d','i','s','p','l','a','y',0};
    const WCHAR *driver = NULL, *device = NULL, *port = NULL;
    DEVMODEW *devmode = NULL;

    TRACE( "(%p, %p)\n", hdc, dv );

    if (dv)
    {
        if (dv->tdDriverNameOffset) driver  = (WCHAR *)((char *)dv + dv->tdDriverNameOffset);
        if (dv->tdDeviceNameOffset) device  = (WCHAR *)((char *)dv + dv->tdDeviceNameOffset);
        if (dv->tdPortNameOffset)   port    = (WCHAR *)((char *)dv + dv->tdPortNameOffset);
        if (dv->tdExtDevmodeOffset) devmode = (DEVMODEW *)((char *)dv + dv->tdExtDevmodeOffset);
    }
    else
    {
        if (hdc) return hdc;
        driver = displayW;
    }
    return CreateDCW( driver, device, port, devmode );
}

/***********************************************************************
 *           AtlHiMetricToPixel              [atl100.@]
 */
void WINAPI AtlHiMetricToPixel(const SIZEL* lpHiMetric, SIZEL* lpPix)
{
    HDC dc = GetDC(NULL);
    lpPix->cx = lpHiMetric->cx * GetDeviceCaps( dc, LOGPIXELSX ) / 100;
    lpPix->cy = lpHiMetric->cy * GetDeviceCaps( dc, LOGPIXELSY ) / 100;
    ReleaseDC( NULL, dc );
}

/***********************************************************************
 *           AtlPixelToHiMetric              [atl100.@]
 */
void WINAPI AtlPixelToHiMetric(const SIZEL* lpPix, SIZEL* lpHiMetric)
{
    HDC dc = GetDC(NULL);
    lpHiMetric->cx = 100 * lpPix->cx / GetDeviceCaps( dc, LOGPIXELSX );
    lpHiMetric->cy = 100 * lpPix->cy / GetDeviceCaps( dc, LOGPIXELSY );
    ReleaseDC( NULL, dc );
}

/***********************************************************************
 *           AtlComPtrAssign              [atl100.@]
 */
IUnknown* WINAPI AtlComPtrAssign(IUnknown** pp, IUnknown *p)
{
    TRACE("(%p %p)\n", pp, p);

    if (p) IUnknown_AddRef(p);
    if (*pp) IUnknown_Release(*pp);
    *pp = p;
    return p;
}

/***********************************************************************
 *           AtlComQIPtrAssign              [atl100.@]
 */
IUnknown* WINAPI AtlComQIPtrAssign(IUnknown** pp, IUnknown *p, REFIID riid)
{
    IUnknown *new_p = NULL;

    TRACE("(%p %p %s)\n", pp, p, debugstr_guid(riid));

    if (p) IUnknown_QueryInterface(p, riid, (void **)&new_p);
    if (*pp) IUnknown_Release(*pp);
    *pp = new_p;
    return new_p;
}

/***********************************************************************
 *           AtlInternalQueryInterface     [atl100.@]
 */
HRESULT WINAPI AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY* pEntries,  REFIID iid, void** ppvObject)
{
    int i = 0;
    HRESULT rc = E_NOINTERFACE;
    TRACE("(%p, %p, %s, %p)\n",this, pEntries, debugstr_guid(iid), ppvObject);

    if (IsEqualGUID(iid,&IID_IUnknown))
    {
        TRACE("Returning IUnknown\n");
        *ppvObject = ((LPSTR)this+pEntries[0].dw);
        IUnknown_AddRef((IUnknown*)*ppvObject);
        return S_OK;
    }

    while (pEntries[i].pFunc != 0)
    {
        TRACE("Trying entry %i (%s %i %p)\n",i,debugstr_guid(pEntries[i].piid),
              pEntries[i].dw, pEntries[i].pFunc);

        if (!pEntries[i].piid || IsEqualGUID(iid,pEntries[i].piid))
        {
            TRACE("MATCH\n");
            if (pEntries[i].pFunc == (_ATL_CREATORARGFUNC*)1)
            {
                TRACE("Offset\n");
                *ppvObject = ((LPSTR)this+pEntries[i].dw);
                IUnknown_AddRef((IUnknown*)*ppvObject);
                return S_OK;
            }
            else
            {
                TRACE("Function\n");
                rc = pEntries[i].pFunc(this, iid, ppvObject, pEntries[i].dw);
                if(rc==S_OK || pEntries[i].piid)
                    return rc;
            }
        }
        i++;
    }
    TRACE("Done returning (0x%x)\n",rc);
    return rc;
}

/***********************************************************************
 *           AtlIPersistStreamInit_Load      [atl100.@]
 */
HRESULT WINAPI AtlIPersistStreamInit_Load( LPSTREAM pStm, ATL_PROPMAP_ENTRY *pMap,
                                           void *pThis, IUnknown *pUnk)
{
    FIXME("(%p, %p, %p, %p)\n", pStm, pMap, pThis, pUnk);

    return S_OK;
}

/***********************************************************************
 *           AtlIPersistStreamInit_Save      [atl100.@]
 */
HRESULT WINAPI AtlIPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty,
                                          ATL_PROPMAP_ENTRY *pMap, void *pThis,
                                          IUnknown *pUnk)
{
    FIXME("(%p, %d, %p, %p, %p)\n", pStm, fClearDirty, pMap, pThis, pUnk);

    return S_OK;
}

/***********************************************************************
 *           AtlIPersistPropertyBag_Load      [atl100.@]
 */
HRESULT WINAPI AtlIPersistPropertyBag_Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog,
                                           ATL_PROPMAP_ENTRY *pMap, void *pThis,
                                           IUnknown *pUnk)
{
    FIXME("(%p, %p, %p, %p, %p)\n", pPropBag, pErrorLog, pMap, pThis, pUnk);

    return S_OK;
}

/***********************************************************************
 *           AtlIPersistPropertyBag_Save     [atl100.@]
 */
HRESULT WINAPI AtlIPersistPropertyBag_Save(LPPROPERTYBAG pPropBag, BOOL fClearDirty,
                                           BOOL fSaveAll, ATL_PROPMAP_ENTRY *pMap,
                                           void *pThis, IUnknown *pUnk)
{
    FIXME("(%p, %d, %d, %p, %p, %p)\n", pPropBag, fClearDirty, fSaveAll, pMap, pThis, pUnk);

    return S_OK;
}

/***********************************************************************
 *           AtlModuleAddTermFunc            [atl100.@]
 */
HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULE *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw)
{
    _ATL_TERMFUNC_ELEM *termfunc_elem;

    TRACE("version %04x (%p %p %ld)\n", _ATL_VER, pM, pFunc, dw);

    if (_ATL_VER > _ATL_VER_30 || pM->cbSize > ATLVer1Size) {
        termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM));
        termfunc_elem->pFunc = pFunc;
        termfunc_elem->dw = dw;
        termfunc_elem->pNext = pM->m_pTermFuncs;

        pM->m_pTermFuncs = termfunc_elem;
    }

    return S_OK;
}

#if _ATL_VER > _ATL_VER_30

/***********************************************************************
 *           AtlCallTermFunc              [atl100.@]
 */
void WINAPI AtlCallTermFunc(_ATL_MODULE *pM)
{
    _ATL_TERMFUNC_ELEM *iter = pM->m_pTermFuncs, *tmp;

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

    while(iter) {
        iter->pFunc(iter->dw);
        tmp = iter;
        iter = iter->pNext;
        HeapFree(GetProcessHeap(), 0, tmp);
    }

    pM->m_pTermFuncs = NULL;
}

#endif

/***********************************************************************
 *           AtlLoadTypeLib             [atl100.56]
 */
HRESULT WINAPI AtlLoadTypeLib(HINSTANCE inst, LPCOLESTR lpszIndex,
        BSTR *pbstrPath, ITypeLib **ppTypeLib)
{
    size_t path_len, index_len;
    ITypeLib *typelib = NULL;
    WCHAR *path;
    HRESULT hres;

    static const WCHAR tlb_extW[] = {'.','t','l','b',0};

    TRACE("(%p %s %p %p)\n", inst, debugstr_w(lpszIndex), pbstrPath, ppTypeLib);

    index_len = lpszIndex ? strlenW(lpszIndex) : 0;
    path = heap_alloc((MAX_PATH+index_len)*sizeof(WCHAR) + sizeof(tlb_extW));
    if(!path)
        return E_OUTOFMEMORY;

    path_len = GetModuleFileNameW(inst, path, MAX_PATH);
    if(!path_len) {
        heap_free(path);
        return HRESULT_FROM_WIN32(GetLastError());
    }

    if(index_len)
        memcpy(path+path_len, lpszIndex, (index_len+1)*sizeof(WCHAR));

    hres = LoadTypeLib(path, &typelib);
    if(FAILED(hres)) {
        WCHAR *ptr;

        for(ptr = path+path_len-1; ptr > path && *ptr != '\\' && *ptr != '.'; ptr--);
        if(*ptr != '.')
            ptr = path+path_len;
        memcpy(ptr, tlb_extW, sizeof(tlb_extW));
        hres = LoadTypeLib(path, &typelib);
    }

    if(SUCCEEDED(hres)) {
        *pbstrPath = SysAllocString(path);
        if(!*pbstrPath) {
            ITypeLib_Release(typelib);
            hres = E_OUTOFMEMORY;
        }
    }

    heap_free(path);
    if(FAILED(hres))
        return hres;

    *ppTypeLib = typelib;
    return S_OK;
}

#if _ATL_VER <= _ATL_VER_80

/***********************************************************************
 *           AtlRegisterTypeLib         [atl80.19]
 */
HRESULT WINAPI AtlRegisterTypeLib(HINSTANCE inst, const WCHAR *index)
{
    ITypeLib *typelib;
    BSTR path;
    HRESULT hres;

    TRACE("(%p %s)\n", inst, debugstr_w(index));

    hres = AtlLoadTypeLib(inst, index, &path, &typelib);
    if(FAILED(hres))
        return hres;

    hres = RegisterTypeLib(typelib, path, NULL); /* FIXME: pass help directory */
    ITypeLib_Release(typelib);
    SysFreeString(path);
    return hres;
}

#endif

#if _ATL_VER > _ATL_VER_30

/***********************************************************************
 *           AtlWinModuleInit                          [atl100.65]
 */
HRESULT WINAPI AtlWinModuleInit(_ATL_WIN_MODULE *winmod)
{
    TRACE("(%p)\n", winmod);

    if(winmod->cbSize != sizeof(*winmod))
        return E_INVALIDARG;

    InitializeCriticalSection(&winmod->m_csWindowCreate);
    winmod->m_pCreateWndList = NULL;
    return S_OK;
}

/***********************************************************************
 *           AtlWinModuleAddCreateWndData              [atl100.43]
 */
void WINAPI AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pM, _AtlCreateWndData *pData, void *pvObject)
{
    TRACE("(%p, %p, %p)\n", pM, pData, pvObject);

    pData->m_pThis = pvObject;
    pData->m_dwThreadID = GetCurrentThreadId();

    EnterCriticalSection(&pM->m_csWindowCreate);
    pData->m_pNext = pM->m_pCreateWndList;
    pM->m_pCreateWndList = pData;
    LeaveCriticalSection(&pM->m_csWindowCreate);
}

/***********************************************************************
 *           AtlWinModuleExtractCreateWndData          [atl100.44]
 */
void* WINAPI AtlWinModuleExtractCreateWndData(_ATL_WIN_MODULE *winmod)
{
    _AtlCreateWndData *iter, *prev = NULL;
    DWORD thread_id;

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

    thread_id = GetCurrentThreadId();

    EnterCriticalSection(&winmod->m_csWindowCreate);

    for(iter = winmod->m_pCreateWndList; iter && iter->m_dwThreadID != thread_id; iter = iter->m_pNext)
        prev = iter;
    if(iter) {
        if(prev)
            prev->m_pNext = iter->m_pNext;
        else
            winmod->m_pCreateWndList = iter->m_pNext;
    }

    LeaveCriticalSection(&winmod->m_csWindowCreate);

    return iter ? iter->m_pThis : NULL;
}

/***********************************************************************
 *           AtlComModuleGetClassObject                [atl100.15]
 */
#if _ATL_VER < _ATL_VER_110
HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, REFIID riid, void **ppv)
{
    _ATL_OBJMAP_ENTRY **iter;
    HRESULT hres;

    TRACE("(%p %s %s %p)\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if(!pm)
        return E_INVALIDARG;

    for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) {
        if(IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) {
            if(!(*iter)->pCF)
                hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCF);
            if((*iter)->pCF)
                hres = IUnknown_QueryInterface((*iter)->pCF, riid, ppv);
            TRACE("returning %p (%08x)\n", *ppv, hres);
            return hres;
        }
    }

    WARN("Class %s not found\n", debugstr_guid(rclsid));
    return CLASS_E_CLASSNOTAVAILABLE;
}
#else
HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, REFIID riid, void **ppv)
{
    _ATL_OBJMAP_ENTRY_EX **iter;
    HRESULT hres;

    TRACE("(%p %s %s %p)\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if(!pm)
        return E_INVALIDARG;

    for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) {
        if(IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) {
            if(!(*iter)->pCache->pCF)
                hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCache->pCF);
            if((*iter)->pCache->pCF)
                hres = IUnknown_QueryInterface((*iter)->pCache->pCF, riid, ppv);
            TRACE("returning %p (%08x)\n", *ppv, hres);
            return hres;
        }
    }

    WARN("Class %s not found\n", debugstr_guid(rclsid));
    return CLASS_E_CLASSNOTAVAILABLE;
}
#endif

/***********************************************************************
 *           AtlComModuleRegisterClassObjects   [atl100.17]
 */
#if _ATL_VER < _ATL_VER_110
HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD context, DWORD flags)
{
    _ATL_OBJMAP_ENTRY **iter;
    IUnknown *unk;
    HRESULT hres;

    TRACE("(%p %x %x)\n", module, context, flags);

    if(!module)
        return E_INVALIDARG;

    for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
        if(!(*iter)->pfnGetClassObject)
            continue;

        hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&unk);
        if(FAILED(hres))
            return hres;

        hres = CoRegisterClassObject((*iter)->pclsid, unk, context, flags, &(*iter)->dwRegister);
        IUnknown_Release(unk);
        if(FAILED(hres))
            return hres;
    }

   return S_OK;
}
#else
HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD context, DWORD flags)
{
    _ATL_OBJMAP_ENTRY_EX **iter;
    IUnknown *unk;
    HRESULT hres;

    TRACE("(%p %x %x)\n", module, context, flags);

    if(!module)
        return E_INVALIDARG;

    for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
        if(!(*iter)->pfnGetClassObject)
            continue;

        hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&unk);
        if(FAILED(hres))
            return hres;

        hres = CoRegisterClassObject((*iter)->pclsid, unk, context, flags, &(*iter)->pCache->dwRegister);
        IUnknown_Release(unk);
        if(FAILED(hres))
            return hres;
    }

   return S_OK;
}
#endif

/***********************************************************************
 *           AtlComModuleRevokeClassObjects   [atl100.20]
 */
#if _ATL_VER < _ATL_VER_110
HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module)
{
    _ATL_OBJMAP_ENTRY **iter;
    HRESULT hres;

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

    if(!module)
        return E_INVALIDARG;

    for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
        hres = CoRevokeClassObject((*iter)->dwRegister);
        if(FAILED(hres))
            return hres;
    }

    return S_OK;
}
#else
HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module)
{
    _ATL_OBJMAP_ENTRY_EX **iter;
    HRESULT hres;

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

    if(!module)
        return E_INVALIDARG;

    for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) {
        hres = CoRevokeClassObject((*iter)->pCache->dwRegister);
        if(FAILED(hres))
            return hres;
    }

    return S_OK;
}
#endif

/***********************************************************************
 *           AtlComModuleUnregisterServer       [atl100.22]
 */
#if _ATL_VER < _ATL_VER_110
HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const CLSID *clsid)
{
    const struct _ATL_CATMAP_ENTRY *catmap;
    _ATL_OBJMAP_ENTRY **iter;
    HRESULT hres;

    TRACE("(%p %x %s)\n", mod, bRegTypeLib, debugstr_guid(clsid));

    for(iter = mod->m_ppAutoObjMapFirst; iter < mod->m_ppAutoObjMapLast; iter++) {
        if(!*iter || (clsid && !IsEqualCLSID((*iter)->pclsid, clsid)))
            continue;

        TRACE("Unregistering clsid %s\n", debugstr_guid((*iter)->pclsid));

        catmap = (*iter)->pfnGetCategoryMap();
        if(catmap) {
            hres = AtlRegisterClassCategoriesHelper((*iter)->pclsid, catmap, FALSE);
            if(FAILED(hres))
                return hres;
        }

        hres = (*iter)->pfnUpdateRegistry(FALSE);
        if(FAILED(hres))
            return hres;
    }

    if(bRegTypeLib) {
        ITypeLib *typelib;
        TLIBATTR *attr;
        BSTR path;

        hres = AtlLoadTypeLib(mod->m_hInstTypeLib, NULL, &path, &typelib);
        if(FAILED(hres))
            return hres;

        SysFreeString(path);
        hres = ITypeLib_GetLibAttr(typelib, &attr);
        if(SUCCEEDED(hres)) {
            hres = UnRegisterTypeLib(&attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, attr->lcid, attr->syskind);
            ITypeLib_ReleaseTLibAttr(typelib, attr);
        }
        ITypeLib_Release(typelib);
        if(FAILED(hres))
            return hres;
    }

    return S_OK;
}
#else
HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib, const CLSID *clsid)
{
    const struct _ATL_CATMAP_ENTRY *catmap;
    _ATL_OBJMAP_ENTRY_EX **iter;
    HRESULT hres;

    TRACE("(%p %x %s)\n", mod, bRegTypeLib, debugstr_guid(clsid));

    for(iter = mod->m_ppAutoObjMapFirst; iter < mod->m_ppAutoObjMapLast; iter++) {
        if(!*iter || (clsid && !IsEqualCLSID((*iter)->pclsid, clsid)))
            continue;

        TRACE("Unregistering clsid %s\n", debugstr_guid((*iter)->pclsid));

        catmap = (*iter)->pfnGetCategoryMap();
        if(catmap) {
            hres = AtlRegisterClassCategoriesHelper((*iter)->pclsid, catmap, FALSE);
            if(FAILED(hres))
                return hres;
        }

        hres = (*iter)->pfnUpdateRegistry(FALSE);
        if(FAILED(hres))
            return hres;
    }

    if(bRegTypeLib) {
        ITypeLib *typelib;
        TLIBATTR *attr;
        BSTR path;

        hres = AtlLoadTypeLib(mod->m_hInstTypeLib, NULL, &path, &typelib);
        if(FAILED(hres))
            return hres;

        SysFreeString(path);
        hres = ITypeLib_GetLibAttr(typelib, &attr);
        if(SUCCEEDED(hres)) {
            hres = UnRegisterTypeLib(&attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, attr->lcid, attr->syskind);
            ITypeLib_ReleaseTLibAttr(typelib, attr);
        }
        ITypeLib_Release(typelib);
        if(FAILED(hres))
            return hres;
    }

    return S_OK;
}
#endif

#endif

/***********************************************************************
 *           AtlRegisterClassCategoriesHelper          [atl100.49]
 */
HRESULT WINAPI AtlRegisterClassCategoriesHelper(REFCLSID clsid, const struct _ATL_CATMAP_ENTRY *catmap, BOOL reg)
{
    const struct _ATL_CATMAP_ENTRY *iter;
    HRESULT hres;

    TRACE("(%s %p %x)\n", debugstr_guid(clsid), catmap, reg);

    if(!catmap)
        return S_OK;

    if(!catreg) {
        ICatRegister *new_catreg;

        hres = CoCreateInstance(&CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER,
                &IID_ICatRegister, (void**)&new_catreg);
        if(FAILED(hres))
            return hres;

        if(InterlockedCompareExchangePointer((void**)&catreg, new_catreg, NULL))
            ICatRegister_Release(new_catreg);
    }

    for(iter = catmap; iter->iType != _ATL_CATMAP_ENTRY_END; iter++) {
        CATID catid = *iter->pcatid; /* For stupid lack of const in ICatRegister declaration. */

        if(iter->iType == _ATL_CATMAP_ENTRY_IMPLEMENTED) {
            if(reg)
                hres = ICatRegister_RegisterClassImplCategories(catreg, clsid, 1, &catid);
            else
                hres = ICatRegister_UnRegisterClassImplCategories(catreg, clsid, 1, &catid);
        }else {
            if(reg)
                hres = ICatRegister_RegisterClassReqCategories(catreg, clsid, 1, &catid);
            else
                hres = ICatRegister_UnRegisterClassReqCategories(catreg, clsid, 1, &catid);
        }
        if(FAILED(hres))
            return hres;
    }

    if(!reg) {
        WCHAR reg_path[256] = {'C','L','S','I','D','\\'}, *ptr = reg_path+6;

        static const WCHAR implemented_catW[] =
            {'I','m','p','l','e','m','e','n','t','e','d',' ','C','a','t','e','g','o','r','i','e','s',0};
        static const WCHAR required_catW[] =
            {'R','e','q','u','i','r','e','d',' ','C','a','t','e','g','o','r','i','e','s',0};

        ptr += StringFromGUID2(clsid, ptr, 64)-1;
        *ptr++ = '\\';

        memcpy(ptr, implemented_catW, sizeof(implemented_catW));
        RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);

        memcpy(ptr, required_catW, sizeof(required_catW));
        RegDeleteKeyW(HKEY_CLASSES_ROOT, reg_path);
    }

    return S_OK;
}

/***********************************************************************
 *           AtlWaitWithMessageLoop     [atl100.24]
 */
BOOL WINAPI AtlWaitWithMessageLoop(HANDLE handle)
{
    MSG msg;
    DWORD res;

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

    while(1) {
        res = MsgWaitForMultipleObjects(1, &handle, FALSE, INFINITE, QS_ALLINPUT);
        switch(res) {
        case WAIT_OBJECT_0:
            return TRUE;
        case WAIT_OBJECT_0+1:
            if(GetMessageW(&msg, NULL, 0, 0) < 0)
                return FALSE;

            TranslateMessage(&msg);
            DispatchMessageW(&msg);
            break;
        default:
            return FALSE;
        }
    }
}

static HRESULT get_default_source(ITypeLib *typelib, const CLSID *clsid, IID *iid)
{
    ITypeInfo *typeinfo, *src_typeinfo = NULL;
    TYPEATTR *attr;
    int type_flags;
    unsigned i;
    HRESULT hres;

    hres = ITypeLib_GetTypeInfoOfGuid(typelib, clsid, &typeinfo);
    if(FAILED(hres))
        return hres;

    hres = ITypeInfo_GetTypeAttr(typeinfo, &attr);
    if(FAILED(hres)) {
        ITypeInfo_Release(typeinfo);
        return hres;
    }

    for(i=0; i < attr->cImplTypes; i++) {
        hres = ITypeInfo_GetImplTypeFlags(typeinfo, i, &type_flags);
        if(SUCCEEDED(hres) && type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) {
            HREFTYPE ref;

            hres = ITypeInfo_GetRefTypeOfImplType(typeinfo, i, &ref);
            if(SUCCEEDED(hres))
                hres = ITypeInfo_GetRefTypeInfo(typeinfo, ref, &src_typeinfo);
            break;
        }
    }

    ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
    ITypeInfo_Release(typeinfo);
    if(FAILED(hres))
        return hres;

    if(!src_typeinfo) {
        *iid = IID_NULL;
        return S_OK;
    }

    hres = ITypeInfo_GetTypeAttr(src_typeinfo, &attr);
    if(SUCCEEDED(hres)) {
        *iid = attr->guid;
        ITypeInfo_ReleaseTypeAttr(src_typeinfo, attr);
    }
    ITypeInfo_Release(src_typeinfo);
    return hres;
}

/***********************************************************************
 *           AtlGetObjectSourceInterface    [atl100.54]
 */
HRESULT WINAPI AtlGetObjectSourceInterface(IUnknown *unk, GUID *libid, IID *iid, unsigned short *major, unsigned short *minor)
{
    IProvideClassInfo2 *classinfo;
    ITypeInfo *typeinfo;
    ITypeLib *typelib;
    IPersist *persist;
    IDispatch *disp;
    HRESULT hres;

    TRACE("(%p %p %p %p %p)\n", unk, libid, iid, major, minor);

    hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
    if(FAILED(hres))
        return hres;

    hres = IDispatch_GetTypeInfo(disp, 0, 0, &typeinfo);
    IDispatch_Release(disp);
    if(FAILED(hres))
        return hres;

    hres = ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, 0);
    ITypeInfo_Release(typeinfo);
    if(SUCCEEDED(hres)) {
        TLIBATTR *attr;

        hres = ITypeLib_GetLibAttr(typelib, &attr);
        if(SUCCEEDED(hres)) {
            *libid = attr->guid;
            *major = attr->wMajorVerNum;
            *minor = attr->wMinorVerNum;
            ITypeLib_ReleaseTLibAttr(typelib, attr);
        }else {
            ITypeLib_Release(typelib);
        }
    }
    if(FAILED(hres))
        return hres;

    hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo2, (void**)&classinfo);
    if(SUCCEEDED(hres)) {
        hres = IProvideClassInfo2_GetGUID(classinfo, GUIDKIND_DEFAULT_SOURCE_DISP_IID, iid);
        IProvideClassInfo2_Release(classinfo);
        ITypeLib_Release(typelib);
        return hres;
    }

    hres = IUnknown_QueryInterface(unk, &IID_IPersist, (void**)&persist);
    if(SUCCEEDED(hres)) {
        CLSID clsid;

        hres = IPersist_GetClassID(persist, &clsid);
        if(SUCCEEDED(hres))
            hres = get_default_source(typelib, &clsid, iid);
        IPersist_Release(persist);
    }

    return hres;
}

#if _ATL_VER >= _ATL_VER90

/***********************************************************************
 *           AtlSetPerUserRegistration [atl100.67]
 */
HRESULT WINAPI AtlSetPerUserRegistration(cpp_bool bEnable)
{
    FIXME("stub: bEnable: %d\n", bEnable);
    return E_NOTIMPL;
}

/***********************************************************************
 *           AtlGetPerUserRegistration  [atl100.68]
 */
HRESULT WINAPI AtlGetPerUserRegistration(cpp_bool *pbEnabled)
{
    FIXME("stub: returning false\n");
    *pbEnabled = 0;
    return S_OK;
}

#endif

/***********************************************************************
 *           AtlGetVersion              [atl100.@]
 */
DWORD WINAPI AtlGetVersion(void *pReserved)
{
    TRACE("version %04x (%p)\n", _ATL_VER, pReserved);
    return _ATL_VER;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);

    switch(fdwReason) {
    case DLL_PROCESS_ATTACH:
        atl_instance = hinstDLL;
        DisableThreadLibraryCalls(hinstDLL);
        break;
    case DLL_PROCESS_DETACH:
        if (lpvReserved) break;
        if(catreg)
            ICatRegister_Release(catreg);
    }

    return TRUE;
}
