EnumThemeColors() and EnumThemeSizes() actually do not return a single
[wine] / dlls / urlmon / urlmon_main.c
1 /*
2  * UrlMon
3  *
4  * Copyright (c) 2000 Patrik Stridvall
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22
23 #define COBJMACROS
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "wtypes.h"
29 #define NO_SHLWAPI_REG
30 #include "shlwapi.h"
31
32 #include "wine/debug.h"
33
34 #include "winuser.h"
35 #include "urlmon.h"
36 #include "urlmon_main.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
39
40 LONG URLMON_refCount = 0;
41
42 HINSTANCE URLMON_hInstance = 0;
43
44 /***********************************************************************
45  *              DllMain (URLMON.init)
46  */
47 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
48 {
49     TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
50
51     switch(fdwReason) {
52     case DLL_PROCESS_ATTACH:
53         DisableThreadLibraryCalls(hinstDLL);
54         URLMON_hInstance = hinstDLL;
55         break;
56
57     case DLL_PROCESS_DETACH:
58         URLMON_hInstance = 0;
59         break;
60     }
61     return TRUE;
62 }
63
64
65 /***********************************************************************
66  *              DllInstall (URLMON.@)
67  */
68 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
69 {
70   FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
71         debugstr_w(cmdline));
72
73   return S_OK;
74 }
75
76 /***********************************************************************
77  *              DllCanUnloadNow (URLMON.@)
78  */
79 HRESULT WINAPI DllCanUnloadNow(void)
80 {
81     return URLMON_refCount != 0 ? S_FALSE : S_OK;
82 }
83
84
85
86 /******************************************************************************
87  * Urlmon ClassFactory
88  */
89 typedef struct {
90     IClassFactory ITF_IClassFactory;
91
92     LONG ref;
93     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
94 } IClassFactoryImpl;
95
96 struct object_creation_info
97 {
98     const CLSID *clsid;
99     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
100 };
101  
102 static const struct object_creation_info object_creation[] =
103 {
104     { &CLSID_InternetSecurityManager, &SecManagerImpl_Construct },
105     { &CLSID_InternetZoneManager, ZoneMgrImpl_Construct }
106 };
107
108 static HRESULT WINAPI
109 CF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
110 {
111     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
112
113     if (IsEqualGUID(riid, &IID_IUnknown)
114         || IsEqualGUID(riid, &IID_IClassFactory))
115     {
116         IClassFactory_AddRef(iface);
117         *ppobj = This;
118         return S_OK;
119     }
120
121     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
122     return E_NOINTERFACE;
123 }
124
125 static ULONG WINAPI CF_AddRef(LPCLASSFACTORY iface)
126 {
127     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
128     return InterlockedIncrement(&This->ref);
129 }
130
131 static ULONG WINAPI CF_Release(LPCLASSFACTORY iface)
132 {
133     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
134
135     ULONG ref = InterlockedDecrement(&This->ref);
136
137     if (ref == 0) {
138         HeapFree(GetProcessHeap(), 0, This);
139         URLMON_UnlockModule();
140     }
141
142     return ref;
143 }
144
145
146 static HRESULT WINAPI CF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
147                                         REFIID riid, LPVOID *ppobj)
148 {
149     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
150     HRESULT hres;
151     LPUNKNOWN punk;
152     
153     TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
154
155     *ppobj = NULL;
156     if(SUCCEEDED(hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk))) {
157         hres = IUnknown_QueryInterface(punk, riid, ppobj);
158         IUnknown_Release(punk);
159     }
160     return hres;
161 }
162
163 static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
164 {
165     TRACE("(%d)\n", dolock);
166
167     if (dolock)
168            URLMON_LockModule();
169     else
170            URLMON_UnlockModule();
171
172     return S_OK;
173 }
174
175 static const IClassFactoryVtbl CF_Vtbl =
176 {
177     CF_QueryInterface,
178     CF_AddRef,
179     CF_Release,
180     CF_CreateInstance,
181     CF_LockServer
182 };
183
184 /*******************************************************************************
185  * DllGetClassObject [URLMON.@]
186  * Retrieves class object from a DLL object
187  *
188  * NOTES
189  *    Docs say returns STDAPI
190  *
191  * PARAMS
192  *    rclsid [I] CLSID for the class object
193  *    riid   [I] Reference to identifier of interface for class object
194  *    ppv    [O] Address of variable to receive interface pointer for riid
195  *
196  * RETURNS
197  *    Success: S_OK
198  *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
199  *             E_UNEXPECTED
200  */
201
202 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
203 {
204     int i;
205     IClassFactoryImpl *factory;
206     
207     TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
208     
209     if ( !IsEqualGUID( &IID_IClassFactory, riid )
210          && ! IsEqualGUID( &IID_IUnknown, riid) )
211         return E_NOINTERFACE;
212
213     for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
214     {
215         if (IsEqualGUID(object_creation[i].clsid, rclsid))
216             break;
217     }
218
219     if (i == sizeof(object_creation)/sizeof(object_creation[0]))
220     {
221         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
222         return CLASS_E_CLASSNOTAVAILABLE;
223     }
224
225     factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
226     if (factory == NULL) return E_OUTOFMEMORY;
227
228     factory->ITF_IClassFactory.lpVtbl = &CF_Vtbl;
229     factory->ref = 1;
230     factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
231
232     *ppv = &(factory->ITF_IClassFactory);
233
234     URLMON_LockModule();
235
236     return S_OK;
237 }
238
239
240 /***********************************************************************
241  *              DllRegisterServerEx (URLMON.@)
242  */
243 HRESULT WINAPI DllRegisterServerEx(void)
244 {
245     FIXME("(void): stub\n");
246
247     return E_FAIL;
248 }
249
250 /**************************************************************************
251  *                 UrlMkSetSessionOption (URLMON.@)
252  */
253 HRESULT WINAPI UrlMkSetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
254                                         DWORD Reserved)
255 {
256     FIXME("(%#lx, %p, %#lx): stub\n", dwOption, pBuffer, dwBufferLength);
257
258     return S_OK;
259 }
260
261 /**************************************************************************
262  *                 UrlMkGetSessionOption (URLMON.@)
263  */
264 HRESULT WINAPI UrlMkGetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
265                                         DWORD* pdwBufferLength, DWORD dwReserved)
266 {
267     FIXME("(%#lx, %p, %#lx, %p): stub\n", dwOption, pBuffer, dwBufferLength, pdwBufferLength);
268
269     return S_OK;
270 }
271
272 static const CHAR Agent[] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)";
273
274 /**************************************************************************
275  *                 ObtainUserAgentString (URLMON.@)
276  */
277 HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbSize)
278 {
279     FIXME("(%ld, %p, %p): stub\n", dwOption, pcszUAOut, cbSize);
280
281     if(dwOption) {
282       ERR("dwOption: %ld, must be zero\n", dwOption);
283     }
284
285     if (sizeof(Agent) < *cbSize)
286         *cbSize = sizeof(Agent);
287     lstrcpynA(pcszUAOut, Agent, *cbSize); 
288
289     return S_OK;
290 }
291
292 HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
293                                     LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
294 {
295     HRESULT hres;
296     DWORD size = cchResult;
297     
298     TRACE("(%s,%s,0x%08lx,%p,%ld,%p,%ld)\n", debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl), dwCombineFlags,
299           pwzResult, cchResult, pcchResult, dwReserved);
300     hres = UrlCombineW(pwzBaseUrl, pwzRelativeUrl, pwzResult, &size, dwCombineFlags);
301     if(pcchResult) *pcchResult = size;
302     return hres;
303 }
304
305 HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
306 {
307     TRACE("(%s,%s,%08lx)\n", debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
308     return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags)==0?S_OK:S_FALSE;
309 }
310
311 /**************************************************************************
312  *                 IsValidURL (URLMON.@)
313  * 
314  * Determines if a specified string is a valid URL.
315  *
316  * PARAMS
317  *  pBC        [I] ignored, must be NULL.
318  *  szURL      [I] string that represents the URL in question.
319  *  dwReserved [I] reserved and must be zero.
320  *
321  * RETURNS
322  *  Success: S_OK.
323  *  Failure: S_FALSE.
324  *  returns E_INVALIDARG if one or more of the args is invalid.
325  *
326  * TODO:
327  *  test functionality against windows to see what a valid URL is.
328  */
329 HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
330 {
331     FIXME("(%p, %s, %ld): stub\n", pBC, debugstr_w(szURL), dwReserved);
332     
333     if (pBC != NULL || dwReserved != 0)
334         return E_INVALIDARG;
335     
336     return S_OK;
337 }
338
339 /**************************************************************************
340  *                 FaultInIEFeature (URLMON.@)
341  *
342  *  Undocumented.  Appears to be used by native shdocvw.dll.
343  */
344 HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
345                                  QUERYCONTEXT *pQuery, DWORD flags )
346 {
347     FIXME("%p %p %p %08lx\n", hwnd, pClassSpec, pQuery, flags);
348     return E_NOTIMPL;
349 }
350
351 /**************************************************************************
352  *                 CoGetClassObjectFromURL (URLMON.@)
353  */
354 HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWORD dwFileVersionMS,
355                                         DWORD dwFileVersionLS, LPCWSTR szContentType,
356                                         LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved,
357                                         REFIID riid, LPVOID *ppv )
358 {
359     FIXME("(%s %s %ld %ld %s %p %ld %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
360         dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved,
361         debugstr_guid(riid), ppv);
362     return E_NOINTERFACE;
363 }