4 * Copyright (c) 2000 Patrik Stridvall
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.
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.
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
29 #define NO_SHLWAPI_REG
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
37 #include "urlmon_main.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(urlmon
);
41 LONG URLMON_refCount
= 0;
43 HINSTANCE URLMON_hInstance
= 0;
45 /***********************************************************************
46 * DllMain (URLMON.init)
48 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID fImpLoad
)
50 TRACE("%p 0x%lx %p\n", hinstDLL
, fdwReason
, fImpLoad
);
53 case DLL_PROCESS_ATTACH
:
54 DisableThreadLibraryCalls(hinstDLL
);
55 URLMON_hInstance
= hinstDLL
;
58 case DLL_PROCESS_DETACH
:
66 /***********************************************************************
67 * DllInstall (URLMON.@)
69 HRESULT WINAPI
DllInstall(BOOL bInstall
, LPCWSTR cmdline
)
71 FIXME("(%s, %s): stub\n", bInstall
?"TRUE":"FALSE",
77 /***********************************************************************
78 * DllCanUnloadNow (URLMON.@)
80 HRESULT WINAPI
DllCanUnloadNow(void)
82 return URLMON_refCount
!= 0 ? S_FALSE
: S_OK
;
87 /******************************************************************************
91 IClassFactory ITF_IClassFactory
;
94 HRESULT (*pfnCreateInstance
)(IUnknown
*pUnkOuter
, LPVOID
*ppObj
);
97 struct object_creation_info
100 HRESULT (*pfnCreateInstance
)(IUnknown
*pUnkOuter
, LPVOID
*ppObj
);
103 static const struct object_creation_info object_creation
[] =
105 { &CLSID_FileProtocol
, FileProtocol_Construct
},
106 { &CLSID_InternetSecurityManager
, &SecManagerImpl_Construct
},
107 { &CLSID_InternetZoneManager
, ZoneMgrImpl_Construct
}
110 static HRESULT WINAPI
111 CF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
)
113 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
115 if (IsEqualGUID(riid
, &IID_IUnknown
)
116 || IsEqualGUID(riid
, &IID_IClassFactory
))
118 IClassFactory_AddRef(iface
);
123 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppobj
);
124 return E_NOINTERFACE
;
127 static ULONG WINAPI
CF_AddRef(LPCLASSFACTORY iface
)
129 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
130 return InterlockedIncrement(&This
->ref
);
133 static ULONG WINAPI
CF_Release(LPCLASSFACTORY iface
)
135 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
137 ULONG ref
= InterlockedDecrement(&This
->ref
);
140 HeapFree(GetProcessHeap(), 0, This
);
141 URLMON_UnlockModule();
148 static HRESULT WINAPI
CF_CreateInstance(LPCLASSFACTORY iface
, LPUNKNOWN pOuter
,
149 REFIID riid
, LPVOID
*ppobj
)
151 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
155 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
158 if(SUCCEEDED(hres
= This
->pfnCreateInstance(pOuter
, (LPVOID
*) &punk
))) {
159 hres
= IUnknown_QueryInterface(punk
, riid
, ppobj
);
160 IUnknown_Release(punk
);
165 static HRESULT WINAPI
CF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
)
167 TRACE("(%d)\n", dolock
);
172 URLMON_UnlockModule();
177 static const IClassFactoryVtbl CF_Vtbl
=
186 /*******************************************************************************
187 * DllGetClassObject [URLMON.@]
188 * Retrieves class object from a DLL object
191 * Docs say returns STDAPI
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
200 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
204 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
207 IClassFactoryImpl
*factory
;
209 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
211 if ( !IsEqualGUID( &IID_IClassFactory
, riid
)
212 && ! IsEqualGUID( &IID_IUnknown
, riid
) )
213 return E_NOINTERFACE
;
215 for (i
=0; i
< sizeof(object_creation
)/sizeof(object_creation
[0]); i
++)
217 if (IsEqualGUID(object_creation
[i
].clsid
, rclsid
))
221 if (i
== sizeof(object_creation
)/sizeof(object_creation
[0]))
223 FIXME("%s: no class found.\n", debugstr_guid(rclsid
));
224 return CLASS_E_CLASSNOTAVAILABLE
;
227 factory
= HeapAlloc(GetProcessHeap(), 0, sizeof(*factory
));
228 if (factory
== NULL
) return E_OUTOFMEMORY
;
230 factory
->ITF_IClassFactory
.lpVtbl
= &CF_Vtbl
;
232 factory
->pfnCreateInstance
= object_creation
[i
].pfnCreateInstance
;
234 *ppv
= &(factory
->ITF_IClassFactory
);
242 /***********************************************************************
243 * DllRegisterServerEx (URLMON.@)
245 HRESULT WINAPI
DllRegisterServerEx(void)
247 FIXME("(void): stub\n");
252 /**************************************************************************
253 * UrlMkSetSessionOption (URLMON.@)
255 HRESULT WINAPI
UrlMkSetSessionOption(DWORD dwOption
, LPVOID pBuffer
, DWORD dwBufferLength
,
258 FIXME("(%#lx, %p, %#lx): stub\n", dwOption
, pBuffer
, dwBufferLength
);
263 /**************************************************************************
264 * UrlMkGetSessionOption (URLMON.@)
266 HRESULT WINAPI
UrlMkGetSessionOption(DWORD dwOption
, LPVOID pBuffer
, DWORD dwBufferLength
,
267 DWORD
* pdwBufferLength
, DWORD dwReserved
)
269 FIXME("(%#lx, %p, %#lx, %p): stub\n", dwOption
, pBuffer
, dwBufferLength
, pdwBufferLength
);
274 static const CHAR Agent
[] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)";
276 /**************************************************************************
277 * ObtainUserAgentString (URLMON.@)
279 HRESULT WINAPI
ObtainUserAgentString(DWORD dwOption
, LPSTR pcszUAOut
, DWORD
*cbSize
)
281 FIXME("(%ld, %p, %p): stub\n", dwOption
, pcszUAOut
, cbSize
);
284 ERR("dwOption: %ld, must be zero\n", dwOption
);
287 if (sizeof(Agent
) < *cbSize
)
288 *cbSize
= sizeof(Agent
);
289 lstrcpynA(pcszUAOut
, Agent
, *cbSize
);
294 HRESULT WINAPI
CoInternetCombineUrl(LPCWSTR pwzBaseUrl
, LPCWSTR pwzRelativeUrl
, DWORD dwCombineFlags
,
295 LPWSTR pwzResult
, DWORD cchResult
, DWORD
*pcchResult
, DWORD dwReserved
)
298 DWORD size
= cchResult
;
300 TRACE("(%s,%s,0x%08lx,%p,%ld,%p,%ld)\n", debugstr_w(pwzBaseUrl
), debugstr_w(pwzRelativeUrl
), dwCombineFlags
,
301 pwzResult
, cchResult
, pcchResult
, dwReserved
);
302 hres
= UrlCombineW(pwzBaseUrl
, pwzRelativeUrl
, pwzResult
, &size
, dwCombineFlags
);
303 if(pcchResult
) *pcchResult
= size
;
307 HRESULT WINAPI
CoInternetCompareUrl(LPCWSTR pwzUrl1
, LPCWSTR pwzUrl2
, DWORD dwCompareFlags
)
309 TRACE("(%s,%s,%08lx)\n", debugstr_w(pwzUrl1
), debugstr_w(pwzUrl2
), dwCompareFlags
);
310 return UrlCompareW(pwzUrl1
, pwzUrl2
, dwCompareFlags
)==0?S_OK
:S_FALSE
;
313 /**************************************************************************
314 * IsValidURL (URLMON.@)
316 * Determines if a specified string is a valid URL.
319 * pBC [I] ignored, must be NULL.
320 * szURL [I] string that represents the URL in question.
321 * dwReserved [I] reserved and must be zero.
326 * returns E_INVALIDARG if one or more of the args is invalid.
329 * test functionality against windows to see what a valid URL is.
331 HRESULT WINAPI
IsValidURL(LPBC pBC
, LPCWSTR szURL
, DWORD dwReserved
)
333 FIXME("(%p, %s, %ld): stub\n", pBC
, debugstr_w(szURL
), dwReserved
);
335 if (pBC
!= NULL
|| dwReserved
!= 0)
341 /**************************************************************************
342 * FaultInIEFeature (URLMON.@)
344 * Undocumented. Appears to be used by native shdocvw.dll.
346 HRESULT WINAPI
FaultInIEFeature( HWND hwnd
, uCLSSPEC
* pClassSpec
,
347 QUERYCONTEXT
*pQuery
, DWORD flags
)
349 FIXME("%p %p %p %08lx\n", hwnd
, pClassSpec
, pQuery
, flags
);
353 /**************************************************************************
354 * CoGetClassObjectFromURL (URLMON.@)
356 HRESULT WINAPI
CoGetClassObjectFromURL( REFCLSID rclsid
, LPCWSTR szCodeURL
, DWORD dwFileVersionMS
,
357 DWORD dwFileVersionLS
, LPCWSTR szContentType
,
358 LPBINDCTX pBindCtx
, DWORD dwClsContext
, LPVOID pvReserved
,
359 REFIID riid
, LPVOID
*ppv
)
361 FIXME("(%s %s %ld %ld %s %p %ld %p %s %p) Stub!\n", debugstr_guid(rclsid
), debugstr_w(szCodeURL
),
362 dwFileVersionMS
, dwFileVersionLS
, debugstr_w(szContentType
), pBindCtx
, dwClsContext
, pvReserved
,
363 debugstr_guid(riid
), ppv
);
364 return E_NOINTERFACE
;
367 /***********************************************************************
368 * ReleaseBindInfo (URLMON.@)
370 * Release the resources used by the specified BINDINFO structure.
373 * pbindinfo [I] BINDINFO to release.
378 void WINAPI
ReleaseBindInfo(BINDINFO
* pbindinfo
)
380 TRACE("(%p)\n", pbindinfo
);
385 CoTaskMemFree(pbindinfo
->szExtraInfo
);
388 IUnknown_Release(pbindinfo
->pUnk
);
391 /***********************************************************************
392 * FindMimeFromData (URLMON.@)
394 * Determines the Multipurpose Internet Mail Extensions (MIME) type from the data provided.
396 HRESULT WINAPI
FindMimeFromData(LPBC pBC
, LPCWSTR pwzUrl
, LPVOID pBuffer
,
397 DWORD cbSize
, LPCWSTR pwzMimeProposed
, DWORD dwMimeFlags
,
398 LPWSTR
* ppwzMimeOut
, DWORD dwReserved
)
400 TRACE("(%p,%s,%p,%ld,%s,0x%lx,%p,0x%lx)\n", pBC
, debugstr_w(pwzUrl
), pBuffer
, cbSize
,
401 debugstr_w(pwzMimeProposed
), dwMimeFlags
, ppwzMimeOut
, dwReserved
);
404 WARN("dwMimeFlags=%08lx\n", dwMimeFlags
);
406 WARN("dwReserved=%ld\n", dwReserved
);
408 /* pBC seams to not be used */
410 if(!ppwzMimeOut
|| (!pwzUrl
&& !pBuffer
))
413 if(pwzMimeProposed
&& (!pwzUrl
|| !pBuffer
|| (pBuffer
&& !cbSize
))) {
419 len
= strlenW(pwzMimeProposed
)+1;
420 *ppwzMimeOut
= CoTaskMemAlloc(len
*sizeof(WCHAR
));
421 memcpy(*ppwzMimeOut
, pwzMimeProposed
, len
*sizeof(WCHAR
));
426 UCHAR
*ptr
= pBuffer
;
430 static const WCHAR wszAppOctetStream
[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
431 'o','c','t','e','t','-','s','t','r','e','a','m','\0'};
432 static const WCHAR wszTextPlain
[] = {'t','e','x','t','/','p','l','a','i','n','\0'};
438 for(ptr
= pBuffer
; ptr
< (UCHAR
*)pBuffer
+cbSize
-1; ptr
++) {
439 if(*ptr
< 0x20 && *ptr
!= '\n' && *ptr
!= '\r' && *ptr
!= '\t') {
440 ret
= wszAppOctetStream
;
445 len
= strlenW(ret
)+1;
446 *ppwzMimeOut
= CoTaskMemAlloc(len
*sizeof(WCHAR
));
447 memcpy(*ppwzMimeOut
, ret
, len
*sizeof(WCHAR
));
457 static const WCHAR wszContentType
[] =
458 {'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
460 ptr
= strrchrW(pwzUrl
, '.');
464 res
= RegOpenKeyW(HKEY_CLASSES_ROOT
, ptr
, &hkey
);
465 if(res
!= ERROR_SUCCESS
)
469 res
= RegQueryValueExW(hkey
, wszContentType
, NULL
, NULL
, (LPBYTE
)mime
, &size
);
471 if(res
!= ERROR_SUCCESS
)
474 *ppwzMimeOut
= CoTaskMemAlloc(size
);
475 memcpy(*ppwzMimeOut
, mime
, size
);