Declare RtlGUIDFromString and RtlStringFromGUID.
[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 const 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 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 }