Build and load import libraries directly from the dll directory where
[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 URLMON_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 URLMON_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     DWORD 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     URLMON_LockModule();
129     
130     return InterlockedIncrement(&This->ref);
131 }
132
133 static ULONG WINAPI CF_Release(LPCLASSFACTORY iface)
134 {
135     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
136
137     ULONG ref = InterlockedDecrement(&This->ref);
138
139     if (ref == 0)
140         HeapFree(GetProcessHeap(), 0, This);
141
142     URLMON_UnlockModule();
143
144     return ref;
145 }
146
147
148 static HRESULT WINAPI CF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
149                                         REFIID riid, LPVOID *ppobj)
150 {
151     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
152     HRESULT hres;
153     LPUNKNOWN punk;
154     
155     TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
156
157     *ppobj = NULL;
158     if(SUCCEEDED(hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk))) {
159         hres = IUnknown_QueryInterface(punk, riid, ppobj);
160         IUnknown_Release(punk);
161     }
162     return hres;
163 }
164
165 static HRESULT WINAPI CF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
166 {
167     TRACE("(%d)\n", dolock);
168
169     if (dolock)
170            URLMON_LockModule();
171     else
172            URLMON_UnlockModule();
173
174     return S_OK;
175 }
176
177 static IClassFactoryVtbl CF_Vtbl =
178 {
179     CF_QueryInterface,
180     CF_AddRef,
181     CF_Release,
182     CF_CreateInstance,
183     CF_LockServer
184 };
185
186 /*******************************************************************************
187  * DllGetClassObject [URLMON.@]
188  * Retrieves class object from a DLL object
189  *
190  * NOTES
191  *    Docs say returns STDAPI
192  *
193  * PARAMS
194  *    rclsid [I] CLSID for the class object
195  *    riid   [I] Reference to identifier of interface for class object
196  *    ppv    [O] Address of variable to receive interface pointer for riid
197  *
198  * RETURNS
199  *    Success: S_OK
200  *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
201  *             E_UNEXPECTED
202  */
203
204 DWORD WINAPI URLMON_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
205 {
206     int i;
207     IClassFactoryImpl *factory;
208     
209     TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
210     
211     if ( !IsEqualGUID( &IID_IClassFactory, riid )
212          && ! IsEqualGUID( &IID_IUnknown, riid) )
213         return E_NOINTERFACE;
214
215     for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
216     {
217         if (IsEqualGUID(object_creation[i].clsid, rclsid))
218             break;
219     }
220
221     if (i == sizeof(object_creation)/sizeof(object_creation[0]))
222     {
223         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
224         return CLASS_E_CLASSNOTAVAILABLE;
225     }
226
227     factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
228     if (factory == NULL) return E_OUTOFMEMORY;
229
230     factory->ITF_IClassFactory.lpVtbl = &CF_Vtbl;
231     factory->ref = 1;
232
233     factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
234
235     *ppv = &(factory->ITF_IClassFactory);
236     return S_OK;
237 }
238
239
240 /***********************************************************************
241  *              DllRegisterServerEx (URLMON.@)
242  */
243 HRESULT WINAPI URLMON_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 /**************************************************************************
273  *                 ObtainUserAgentString (URLMON.@)
274  */
275 HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPCSTR pcszUAOut, DWORD *cbSize)
276 {
277     FIXME("(%ld, %p, %p): stub\n", dwOption, pcszUAOut, cbSize);
278
279     if(dwOption) {
280       ERR("dwOption: %ld, must be zero\n", dwOption);
281     }
282
283     return S_OK;
284 }
285
286 HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags,
287                                     LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
288 {
289     HRESULT hres;
290     DWORD size = cchResult;
291     
292     TRACE("(%s,%s,0x%08lx,%p,%ld,%p,%ld)\n", debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl), dwCombineFlags,
293           pwzResult, cchResult, pcchResult, dwReserved);
294     hres = UrlCombineW(pwzBaseUrl, pwzRelativeUrl, pwzResult, &size, dwCombineFlags);
295     if(pcchResult) *pcchResult = size;
296     return hres;
297 }
298
299 HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
300 {
301     TRACE("(%s,%s,%08lx)\n", debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
302     return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags)==0?S_OK:S_FALSE;
303 }
304
305 /**************************************************************************
306  *                 IsValidURL (URLMON.@)
307  * 
308  * Determines if a specified string is a valid URL.
309  *
310  * PARAMS
311  *  pBC        [I] ignored, must be NULL.
312  *  szURL      [I] string that represents the URL in question.
313  *  dwReserved [I] reserved and must be zero.
314  *
315  * RETURNS
316  *  Success: S_OK.
317  *  Failure: S_FALSE.
318  *  returns E_INVALIDARG if one or more of the args is invalid.
319  *
320  * TODO:
321  *  test functionality against windows to see what a valid URL is.
322  */
323 HRESULT WINAPI IsValidURL(LPBC pBC, LPCWSTR szURL, DWORD dwReserved)
324 {
325     FIXME("(%p, %s, %ld): stub\n", pBC, debugstr_w(szURL), dwReserved);
326     
327     if (pBC != NULL || dwReserved != 0)
328         return E_INVALIDARG;
329     
330     return S_OK;
331 }
332
333 /**************************************************************************
334  *                 FaultInIEFeature (URLMON.@)
335  *
336  *  Undocumented.  Appears to be used by native shdocvw.dll.
337  */
338 HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
339                                  QUERYCONTEXT *pQuery, DWORD flags )
340 {
341     FIXME("%p %p %p %08lx\n", hwnd, pClassSpec, pQuery, flags);
342     return E_NOTIMPL;
343 }
344
345 /**************************************************************************
346  *                 CoGetClassObjectFromURL (URLMON.@)
347  */
348 HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWORD dwFileVersionMS,
349                                         DWORD dwFileVersionLS, LPCWSTR szContentType,
350                                         LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved,
351                                         REFIID riid, LPVOID *ppv )
352 {
353     FIXME("(%s %s %ld %ld %s %p %ld %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
354         dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved,
355         debugstr_guid(riid), ppv);
356     return E_NOINTERFACE;
357 }