Intern all the atoms we'll need in one step to avoid multiple server
[wine] / dlls / mshtml / main.c
1 /*
2  *    MSHTML Class Factory
3  *
4  * Copyright 2002 Lionel Ulmer
5  * Copyright 2003 Mike McCormack
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <stdarg.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30
31 #include "uuids.h"
32
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36
37 extern HRESULT HTMLDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj);
38
39 /* For the moment, do nothing here. */
40 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
41 {
42     switch(fdwReason) {
43         case DLL_PROCESS_ATTACH:
44             DisableThreadLibraryCalls(hInstDLL);
45             break;
46         case DLL_PROCESS_DETACH:
47             break;
48     }
49     return TRUE;
50 }
51
52 /******************************************************************************
53  * MSHTML ClassFactory
54  */
55 typedef struct {
56     IClassFactory ITF_IClassFactory;
57
58     DWORD ref;
59     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
60 } IClassFactoryImpl;
61
62 struct object_creation_info
63 {
64     const CLSID *clsid;
65     LPCSTR szClassName;
66     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
67 };
68
69 static const struct object_creation_info object_creation[] =
70 {
71     { &CLSID_HTMLDocument, "HTMLDocument", HTMLDocument_create },
72 };
73
74 static HRESULT WINAPI
75 HTMLCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
76 {
77     ICOM_THIS(IClassFactoryImpl,iface);
78
79     if (IsEqualGUID(riid, &IID_IUnknown)
80         || IsEqualGUID(riid, &IID_IClassFactory))
81     {
82         IClassFactory_AddRef(iface);
83         *ppobj = This;
84         return S_OK;
85     }
86
87     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
88     return E_NOINTERFACE;
89 }
90
91 static ULONG WINAPI HTMLCF_AddRef(LPCLASSFACTORY iface) {
92     ICOM_THIS(IClassFactoryImpl,iface);
93     return ++(This->ref);
94 }
95
96 static ULONG WINAPI HTMLCF_Release(LPCLASSFACTORY iface) {
97     ICOM_THIS(IClassFactoryImpl,iface);
98
99     ULONG ref = --This->ref;
100
101     if (ref == 0)
102         HeapFree(GetProcessHeap(), 0, This);
103
104     return ref;
105 }
106
107
108 static HRESULT WINAPI HTMLCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
109                                           REFIID riid, LPVOID *ppobj) {
110     ICOM_THIS(IClassFactoryImpl,iface);
111     HRESULT hres;
112     LPUNKNOWN punk;
113     
114     TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
115
116     hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
117     if (FAILED(hres)) {
118         *ppobj = NULL;
119         return hres;
120     }
121     hres = IUnknown_QueryInterface(punk, riid, ppobj);
122     if (FAILED(hres)) {
123         *ppobj = NULL;
124         return hres;
125     }
126     IUnknown_Release(punk);
127     return hres;
128 }
129
130 static HRESULT WINAPI HTMLCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
131     ICOM_THIS(IClassFactoryImpl,iface);
132     FIXME("(%p)->(%d),stub!\n",This,dolock);
133     return S_OK;
134 }
135
136 static ICOM_VTABLE(IClassFactory) HTMLCF_Vtbl =
137 {
138     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
139     HTMLCF_QueryInterface,
140     HTMLCF_AddRef,
141     HTMLCF_Release,
142     HTMLCF_CreateInstance,
143     HTMLCF_LockServer
144 };
145
146
147 HRESULT WINAPI MSHTML_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
148 {
149     int i;
150     IClassFactoryImpl *factory;
151
152     TRACE("%s %s %p\n",debugstr_guid(rclsid), debugstr_guid(iid), ppv);
153     
154     if ( !IsEqualGUID( &IID_IClassFactory, iid )
155          && ! IsEqualGUID( &IID_IUnknown, iid) )
156         return E_NOINTERFACE;
157
158     for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
159     {
160         if (IsEqualGUID(object_creation[i].clsid, rclsid))
161             break;
162     }
163
164     if (i == sizeof(object_creation)/sizeof(object_creation[0]))
165     {
166         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
167         return CLASS_E_CLASSNOTAVAILABLE;
168     }
169
170     TRACE("Creating a class factory for %s\n",object_creation[i].szClassName);
171
172     factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
173     if (factory == NULL) return E_OUTOFMEMORY;
174
175     factory->ITF_IClassFactory.lpVtbl = &HTMLCF_Vtbl;
176     factory->ref = 1;
177
178     factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
179
180     *ppv = &(factory->ITF_IClassFactory);
181
182     TRACE("(%p) <- %p\n", ppv, &(factory->ITF_IClassFactory) );
183
184     return S_OK;
185 }
186
187 HRESULT WINAPI MSHTML_DllCanUnloadNow(void)
188 {
189     FIXME("\n");
190     return S_FALSE;
191 }
192
193 /* appears to have the same prototype as WinMain */
194 INT WINAPI RunHTMLApplication( HINSTANCE hinst, HINSTANCE hPrevInst,
195                                LPCSTR szCmdLine, INT nCmdShow )
196 {
197     FIXME("%p %p %s %d\n", hinst, hPrevInst, debugstr_a(szCmdLine), nCmdShow );
198     return 0;
199 }