atl100: Added AtlComModuleGetClassObject implementation (based on AtlModuleGetClassOb...
[wine] / dlls / atl100 / atl.c
1 /*
2  * Copyright 2012 Stefan Leichter
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20
21 #include "atlbase.h"
22
23 #include "wine/debug.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(atl100);
26
27 /***********************************************************************
28  *           AtlAdvise         [atl100.@]
29  */
30 HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, LPDWORD pdw)
31 {
32     FIXME("%p %p %p %p\n", pUnkCP, pUnk, iid, pdw);
33     return E_FAIL;
34 }
35
36 /***********************************************************************
37  *           AtlUnadvise         [atl100.@]
38  */
39 HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw)
40 {
41     FIXME("%p %p %d\n", pUnkCP, iid, dw);
42     return S_OK;
43 }
44
45 /***********************************************************************
46  *           AtlFreeMarshalStream         [atl100.@]
47  */
48 HRESULT WINAPI AtlFreeMarshalStream(IStream *stm)
49 {
50     FIXME("%p\n", stm);
51     return S_OK;
52 }
53
54 /***********************************************************************
55  *           AtlMarshalPtrInProc         [atl100.@]
56  */
57 HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **pstm)
58 {
59     FIXME("%p %p %p\n", pUnk, iid, pstm);
60     return E_FAIL;
61 }
62
63 /***********************************************************************
64  *           AtlUnmarshalPtr              [atl100.@]
65  */
66 HRESULT WINAPI AtlUnmarshalPtr(IStream *stm, const IID *iid, IUnknown **ppUnk)
67 {
68     FIXME("%p %p %p\n", stm, iid, ppUnk);
69     return E_FAIL;
70 }
71
72 /***********************************************************************
73  *           AtlCreateTargetDC         [atl100.@]
74  */
75 HDC WINAPI AtlCreateTargetDC( HDC hdc, DVTARGETDEVICE *dv )
76 {
77     static const WCHAR displayW[] = {'d','i','s','p','l','a','y',0};
78     const WCHAR *driver = NULL, *device = NULL, *port = NULL;
79     DEVMODEW *devmode = NULL;
80
81     TRACE( "(%p, %p)\n", hdc, dv );
82
83     if (dv)
84     {
85         if (dv->tdDriverNameOffset) driver  = (WCHAR *)((char *)dv + dv->tdDriverNameOffset);
86         if (dv->tdDeviceNameOffset) device  = (WCHAR *)((char *)dv + dv->tdDeviceNameOffset);
87         if (dv->tdPortNameOffset)   port    = (WCHAR *)((char *)dv + dv->tdPortNameOffset);
88         if (dv->tdExtDevmodeOffset) devmode = (DEVMODEW *)((char *)dv + dv->tdExtDevmodeOffset);
89     }
90     else
91     {
92         if (hdc) return hdc;
93         driver = displayW;
94     }
95     return CreateDCW( driver, device, port, devmode );
96 }
97
98 /***********************************************************************
99  *           AtlHiMetricToPixel              [atl100.@]
100  */
101 void WINAPI AtlHiMetricToPixel(const SIZEL* lpHiMetric, SIZEL* lpPix)
102 {
103     HDC dc = GetDC(NULL);
104     lpPix->cx = lpHiMetric->cx * GetDeviceCaps( dc, LOGPIXELSX ) / 100;
105     lpPix->cy = lpHiMetric->cy * GetDeviceCaps( dc, LOGPIXELSY ) / 100;
106     ReleaseDC( NULL, dc );
107 }
108
109 /***********************************************************************
110  *           AtlPixelToHiMetric              [atl100.@]
111  */
112 void WINAPI AtlPixelToHiMetric(const SIZEL* lpPix, SIZEL* lpHiMetric)
113 {
114     HDC dc = GetDC(NULL);
115     lpHiMetric->cx = 100 * lpPix->cx / GetDeviceCaps( dc, LOGPIXELSX );
116     lpHiMetric->cy = 100 * lpPix->cy / GetDeviceCaps( dc, LOGPIXELSY );
117     ReleaseDC( NULL, dc );
118 }
119
120 /***********************************************************************
121  *           AtlComPtrAssign              [atl100.@]
122  */
123 IUnknown* WINAPI AtlComPtrAssign(IUnknown** pp, IUnknown *p)
124 {
125     TRACE("(%p %p)\n", pp, p);
126
127     if (p) IUnknown_AddRef(p);
128     if (*pp) IUnknown_Release(*pp);
129     *pp = p;
130     return p;
131 }
132
133 /***********************************************************************
134  *           AtlComQIPtrAssign              [atl100.@]
135  */
136 IUnknown* WINAPI AtlComQIPtrAssign(IUnknown** pp, IUnknown *p, REFIID riid)
137 {
138     IUnknown *new_p = NULL;
139
140     TRACE("(%p %p %s)\n", pp, p, debugstr_guid(riid));
141
142     if (p) IUnknown_QueryInterface(p, riid, (void **)&new_p);
143     if (*pp) IUnknown_Release(*pp);
144     *pp = new_p;
145     return new_p;
146 }
147
148 /***********************************************************************
149  *           AtlInternalQueryInterface     [atl100.@]
150  */
151 HRESULT WINAPI AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY* pEntries,  REFIID iid, void** ppvObject)
152 {
153     int i = 0;
154     HRESULT rc = E_NOINTERFACE;
155     TRACE("(%p, %p, %s, %p)\n",this, pEntries, debugstr_guid(iid), ppvObject);
156
157     if (IsEqualGUID(iid,&IID_IUnknown))
158     {
159         TRACE("Returning IUnknown\n");
160         *ppvObject = ((LPSTR)this+pEntries[0].dw);
161         IUnknown_AddRef((IUnknown*)*ppvObject);
162         return S_OK;
163     }
164
165     while (pEntries[i].pFunc != 0)
166     {
167         TRACE("Trying entry %i (%s %i %p)\n",i,debugstr_guid(pEntries[i].piid),
168               pEntries[i].dw, pEntries[i].pFunc);
169
170         if (!pEntries[i].piid || IsEqualGUID(iid,pEntries[i].piid))
171         {
172             TRACE("MATCH\n");
173             if (pEntries[i].pFunc == (_ATL_CREATORARGFUNC*)1)
174             {
175                 TRACE("Offset\n");
176                 *ppvObject = ((LPSTR)this+pEntries[i].dw);
177                 IUnknown_AddRef((IUnknown*)*ppvObject);
178                 return S_OK;
179             }
180             else
181             {
182                 TRACE("Function\n");
183                 rc = pEntries[i].pFunc(this, iid, ppvObject, pEntries[i].dw);
184                 if(rc==S_OK || pEntries[i].piid)
185                     return rc;
186             }
187         }
188         i++;
189     }
190     TRACE("Done returning (0x%x)\n",rc);
191     return rc;
192 }
193
194 /* FIXME: should be in a header file */
195 typedef struct ATL_PROPMAP_ENTRY
196 {
197     LPCOLESTR szDesc;
198     DISPID dispid;
199     const CLSID* pclsidPropPage;
200     const IID* piidDispatch;
201     DWORD dwOffsetData;
202     DWORD dwSizeData;
203     VARTYPE vt;
204 } ATL_PROPMAP_ENTRY;
205
206 /***********************************************************************
207  *           AtlIPersistStreamInit_Load      [atl100.@]
208  */
209 HRESULT WINAPI AtlIPersistStreamInit_Load( LPSTREAM pStm, ATL_PROPMAP_ENTRY *pMap,
210                                            void *pThis, IUnknown *pUnk)
211 {
212     FIXME("(%p, %p, %p, %p)\n", pStm, pMap, pThis, pUnk);
213
214     return S_OK;
215 }
216
217 /***********************************************************************
218  *           AtlIPersistStreamInit_Save      [atl100.@]
219  */
220 HRESULT WINAPI AtlIPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty,
221                                           ATL_PROPMAP_ENTRY *pMap, void *pThis,
222                                           IUnknown *pUnk)
223 {
224     FIXME("(%p, %d, %p, %p, %p)\n", pStm, fClearDirty, pMap, pThis, pUnk);
225
226     return S_OK;
227 }
228
229 /***********************************************************************
230  *           AtlModuleAddTermFunc            [atl100.@]
231  */
232 HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULE *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw)
233 {
234     _ATL_TERMFUNC_ELEM *termfunc_elem;
235
236     TRACE("(%p %p %ld)\n", pM, pFunc, dw);
237
238     termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM));
239     termfunc_elem->pFunc = pFunc;
240     termfunc_elem->dw = dw;
241     termfunc_elem->pNext = pM->m_pTermFuncs;
242
243     pM->m_pTermFuncs = termfunc_elem;
244
245     return S_OK;
246 }
247
248 /***********************************************************************
249  *           AtlCallTermFunc              [atl100.@]
250  */
251 void WINAPI AtlCallTermFunc(_ATL_MODULE *pM)
252 {
253     _ATL_TERMFUNC_ELEM *iter = pM->m_pTermFuncs, *tmp;
254
255     TRACE("(%p)\n", pM);
256
257     while(iter) {
258         iter->pFunc(iter->dw);
259         tmp = iter;
260         iter = iter->pNext;
261         HeapFree(GetProcessHeap(), 0, tmp);
262     }
263
264     pM->m_pTermFuncs = NULL;
265 }
266
267 /***********************************************************************
268  *           AtlLoadTypeLib             [atl100.@]
269  */
270 HRESULT WINAPI AtlLoadTypeLib(HINSTANCE inst, LPCOLESTR lpszIndex,
271         BSTR *pbstrPath, ITypeLib **ppTypeLib)
272 {
273     OLECHAR path[MAX_PATH+8]; /* leave some space for index */
274     HRESULT hres;
275
276     TRACE("(%p %s %p %p)\n", inst, debugstr_w(lpszIndex), pbstrPath, ppTypeLib);
277
278     GetModuleFileNameW(inst, path, MAX_PATH);
279     if(lpszIndex)
280         lstrcatW(path, lpszIndex);
281
282     hres = LoadTypeLib(path, ppTypeLib);
283     if(FAILED(hres))
284         return hres;
285
286     *pbstrPath = SysAllocString(path);
287     return S_OK;
288 }
289
290 /***********************************************************************
291  *           AtlWinModuleAddCreateWndData              [atl100.43]
292  */
293 void WINAPI AtlWinModuleAddCreateWndData(_ATL_WIN_MODULE *pM, _AtlCreateWndData *pData, void *pvObject)
294 {
295     TRACE("(%p, %p, %p)\n", pM, pData, pvObject);
296
297     pData->m_pThis = pvObject;
298     pData->m_dwThreadID = GetCurrentThreadId();
299
300     EnterCriticalSection(&pM->m_csWindowCreate);
301     pData->m_pNext = pM->m_pCreateWndList;
302     pM->m_pCreateWndList = pData;
303     LeaveCriticalSection(&pM->m_csWindowCreate);
304 }
305
306 /***********************************************************************
307  *           AtlComModuleGetClassObject                [atl100.15]
308  */
309 HRESULT WINAPI AtlComModuleGetClassObject(_ATL_COM_MODULE *pm, REFCLSID rclsid, REFIID riid, void **ppv)
310 {
311     _ATL_OBJMAP_ENTRY **iter;
312     HRESULT hres;
313
314     TRACE("(%p %s %s %p)\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv);
315
316     if(!pm)
317         return E_INVALIDARG;
318
319     for(iter = pm->m_ppAutoObjMapFirst; iter < pm->m_ppAutoObjMapLast; iter++) {
320         if(IsEqualCLSID((*iter)->pclsid, rclsid) && (*iter)->pfnGetClassObject) {
321             if(!(*iter)->pCF)
322                 hres = (*iter)->pfnGetClassObject((*iter)->pfnCreateInstance, &IID_IUnknown, (void**)&(*iter)->pCF);
323             if((*iter)->pCF)
324                 hres = IUnknown_QueryInterface((*iter)->pCF, riid, ppv);
325             TRACE("returning %p (%08x)\n", *ppv, hres);
326             return hres;
327         }
328     }
329
330     WARN("Class %s not found\n", debugstr_guid(rclsid));
331     return CLASS_E_CLASSNOTAVAILABLE;
332 }
333
334 /***********************************************************************
335  *           AtlRegisterClassCategoriesHelper          [atl100.49]
336  */
337 HRESULT WINAPI AtlRegisterClassCategoriesHelper(REFCLSID clsid, const struct _ATL_CATMAP_ENTRY *catmap, BOOL reg)
338 {
339     FIXME("(%s %p %x)\n", debugstr_guid(clsid), catmap, reg);
340     return E_NOTIMPL;
341 }
342
343 /***********************************************************************
344  *           AtlGetVersion              [atl100.@]
345  */
346 DWORD WINAPI AtlGetVersion(void *pReserved)
347 {
348    return _ATL_VER;
349 }