| /* |
| * Implementation of Active Template Library (atl.dll) |
| * |
| * Copyright 2004 Aric Stewart 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include <stdarg.h> |
| #include <stdio.h> |
| |
| #define COBJMACROS |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winerror.h" |
| #include "winuser.h" |
| #include "wine/debug.h" |
| #include "objbase.h" |
| #include "objidl.h" |
| #include "ole2.h" |
| #include "atlbase.h" |
| #include "atliface.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(atl); |
| |
| HINSTANCE hInst; |
| |
| BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) |
| { |
| TRACE("(0x%p, %ld, %p)\n",hinstDLL,fdwReason,lpvReserved); |
| |
| if (fdwReason == DLL_PROCESS_ATTACH) { |
| DisableThreadLibraryCalls(hinstDLL); |
| hInst = hinstDLL; |
| } |
| return TRUE; |
| } |
| |
| #define ATLVer1Size 100 |
| |
| HRESULT WINAPI AtlModuleInit(_ATL_MODULEA* pM, _ATL_OBJMAP_ENTRYA* p, HINSTANCE h) |
| { |
| INT i; |
| UINT size; |
| |
| FIXME("SEMI-STUB (%p %p %p)\n",pM,p,h); |
| |
| size = pM->cbSize; |
| if (size != sizeof(_ATL_MODULEA) && size != ATLVer1Size) |
| { |
| FIXME("Unknown structure version (size %i)\n",size); |
| return E_INVALIDARG; |
| } |
| |
| memset(pM,0,pM->cbSize); |
| pM->cbSize = size; |
| pM->m_hInst = h; |
| pM->m_hInstResource = h; |
| pM->m_hInstTypeLib = h; |
| pM->m_pObjMap = p; |
| pM->m_hHeap = GetProcessHeap(); |
| |
| InitializeCriticalSection(&pM->u.m_csTypeInfoHolder); |
| InitializeCriticalSection(&pM->m_csWindowCreate); |
| InitializeCriticalSection(&pM->m_csObjMap); |
| |
| /* call mains */ |
| i = 0; |
| if (pM->m_pObjMap != NULL && size > ATLVer1Size) |
| { |
| while (pM->m_pObjMap[i].pclsid != NULL) |
| { |
| TRACE("Initializing object %i %p\n",i,p[i].pfnObjectMain); |
| if (p[i].pfnObjectMain) |
| p[i].pfnObjectMain(TRUE); |
| i++; |
| } |
| } |
| |
| return S_OK; |
| } |
| |
| HRESULT WINAPI AtlModuleTerm(_ATL_MODULEA* 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); |
| } |
| |
| HeapFree(GetProcessHeap(), 0, pM); |
| |
| return S_OK; |
| } |
| |
| HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULEW *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw) |
| { |
| _ATL_TERMFUNC_ELEM *termfunc_elem; |
| |
| TRACE("(%p %p %ld)\n", pM, pFunc, dw); |
| |
| 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; |
| } |
| |
| HRESULT WINAPI AtlModuleRegisterClassObjects(_ATL_MODULEA *pM, DWORD dwClsContext, |
| DWORD dwFlags) |
| { |
| HRESULT hRes = S_OK; |
| int i=0; |
| |
| TRACE("(%p %li %li)\n",pM, dwClsContext, dwFlags); |
| |
| if (pM == NULL) |
| return E_INVALIDARG; |
| |
| while(pM->m_pObjMap[i].pclsid != NULL) |
| { |
| IUnknown* pUnknown; |
| _ATL_OBJMAP_ENTRYA *obj = &(pM->m_pObjMap[i]); |
| HRESULT rc; |
| |
| TRACE("Registering object %i\n",i); |
| if (obj->pfnGetClassObject) |
| { |
| rc = obj->pfnGetClassObject(obj->pfnCreateInstance, &IID_IUnknown, |
| (LPVOID*)&pUnknown); |
| if (SUCCEEDED (rc) ) |
| { |
| CoRegisterClassObject(obj->pclsid, pUnknown, dwClsContext, |
| dwFlags, &obj->dwRegister); |
| if (pUnknown) |
| IUnknown_Release(pUnknown); |
| } |
| } |
| i++; |
| } |
| |
| return hRes; |
| } |
| |
| HRESULT WINAPI AtlModuleUnregisterServerEx(_ATL_MODULEA* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID) |
| { |
| FIXME("(%p, %i, %p) stub\n", pM, bUnRegTypeLib, pCLSID); |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * AtlAxWinInit [ATL.@] |
| * Initializes the control-hosting code: registering the AtlAxWin7 and AtlAxWinLic7 window |
| * classes and some messages. |
| * |
| * RETURNS |
| * TRUE or FALSE |
| */ |
| |
| BOOL WINAPI AtlAxWinInit(void) |
| { |
| FIXME("Try use native atl.dll if possible\n"); |
| return FALSE; |
| } |
| |
| |
| 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; |
| } |
| |
| |
| HRESULT WINAPI AtlInternalQueryInterface(LPVOID this, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, LPVOID* ppvObject) |
| { |
| int i = 0; |
| HRESULT rc = E_NOINTERFACE; |
| TRACE("(%p, %p, %p, %p)\n",this, pEntries, iid, ppvObject); |
| |
| if (IsEqualGUID(iid,&IID_IUnknown)) |
| { |
| TRACE("Returning IUnknown\n"); |
| *ppvObject = this; |
| IUnknown_AddRef((IUnknown*)this); |
| return S_OK; |
| } |
| |
| while (pEntries[i].pFunc != 0) |
| { |
| TRACE("Trying entry %i (%p %li %p)\n",i,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*)this); |
| rc = S_OK; |
| } |
| else |
| { |
| TRACE("Function\n"); |
| rc = pEntries[i].pFunc(this, iid, ppvObject,0); |
| } |
| break; |
| } |
| i++; |
| } |
| TRACE("Done returning (0x%lx)\n",rc); |
| return rc; |
| } |
| |
| /*********************************************************************** |
| * AtlModuleRegisterServer [ATL.@] |
| * |
| */ |
| HRESULT WINAPI AtlModuleRegisterServer(_ATL_MODULEW* pM, BOOL bRegTypeLib, const CLSID* clsid) |
| { |
| FIXME("%p %d %s\n", pM, bRegTypeLib, debugstr_guid(clsid)); |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * AtlAdvise [ATL.@] |
| */ |
| HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, LPDWORD pdw) |
| { |
| FIXME("%p %p %p %p\n", pUnkCP, pUnk, iid, pdw); |
| return E_FAIL; |
| } |
| |
| /*********************************************************************** |
| * AtlUnadvise [ATL.@] |
| */ |
| HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw) |
| { |
| FIXME("%p %p %ld\n", pUnkCP, iid, dw); |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * AtlFreeMarshalStream [ATL.@] |
| */ |
| HRESULT WINAPI AtlFreeMarshalStream(IStream *stm) |
| { |
| FIXME("%p\n", stm); |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * AtlMarshalPtrInProc [ATL.@] |
| */ |
| HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **pstm) |
| { |
| FIXME("%p %p %p\n", pUnk, iid, pstm); |
| return E_FAIL; |
| } |
| |
| /*********************************************************************** |
| * AtlUnmarshalPtr [ATL.@] |
| */ |
| HRESULT WINAPI AtlUnmarshalPtr(IStream *stm, const IID *iid, IUnknown **ppUnk) |
| { |
| FIXME("%p %p %p\n", stm, iid, ppUnk); |
| return E_FAIL; |
| } |
| |
| /*********************************************************************** |
| * AtlModuleGetClassObject [ATL.@] |
| */ |
| HRESULT WINAPI AtlModuleGetClassObject(_ATL_MODULEW *pm, REFCLSID rclsid, |
| REFIID riid, LPVOID *ppv) |
| { |
| FIXME("%p %p %p %p\n", pm, rclsid, riid, ppv); |
| return E_FAIL; |
| } |
| |
| /*********************************************************************** |
| * AtlModuleGetClassObject [ATL.@] |
| */ |
| HRESULT WINAPI AtlModuleRegisterTypeLib(_ATL_MODULEW *pm, LPCOLESTR lpszIndex) |
| { |
| FIXME("%p %s\n", pm, debugstr_w(lpszIndex)); |
| return E_FAIL; |
| } |
| |
| /*********************************************************************** |
| * AtlModuleRevokeClassObjects [ATL.@] |
| */ |
| HRESULT WINAPI AtlModuleRevokeClassObjects(_ATL_MODULEW *pm) |
| { |
| FIXME("%p\n", pm); |
| return E_FAIL; |
| } |
| |
| /*********************************************************************** |
| * AtlModuleUnregisterServer [ATL.@] |
| */ |
| HRESULT WINAPI AtlModuleUnregisterServer(_ATL_MODULEW *pm, const CLSID *clsid) |
| { |
| FIXME("%p %s\n", pm, debugstr_guid(clsid)); |
| return E_FAIL; |
| } |
| |
| /*********************************************************************** |
| * AtlAxCreateControl [ATL.@] |
| */ |
| HRESULT WINAPI AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd, |
| IStream *pStream, IUnknown **ppUnkContainer) |
| { |
| FIXME("%s %p %p %p)\n", debugstr_w(lpszName), hWnd, pStream, ppUnkContainer); |
| return E_NOTIMPL; |
| } |