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_FtpProtocol
, FtpProtocol_Construct
},
107 { &CLSID_HttpProtocol
, HttpProtocol_Construct
},
108 { &CLSID_InternetSecurityManager
, &SecManagerImpl_Construct
},
109 { &CLSID_InternetZoneManager
, ZoneMgrImpl_Construct
}
112 static HRESULT WINAPI
113 CF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
)
115 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
117 if (IsEqualGUID(riid
, &IID_IUnknown
)
118 || IsEqualGUID(riid
, &IID_IClassFactory
))
120 IClassFactory_AddRef(iface
);
125 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppobj
);
126 return E_NOINTERFACE
;
129 static ULONG WINAPI
CF_AddRef(LPCLASSFACTORY iface
)
131 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
132 return InterlockedIncrement(&This
->ref
);
135 static ULONG WINAPI
CF_Release(LPCLASSFACTORY iface
)
137 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
139 ULONG ref
= InterlockedDecrement(&This
->ref
);
142 HeapFree(GetProcessHeap(), 0, This
);
143 URLMON_UnlockModule();
150 static HRESULT WINAPI
CF_CreateInstance(LPCLASSFACTORY iface
, LPUNKNOWN pOuter
,
151 REFIID riid
, LPVOID
*ppobj
)
153 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
157 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
160 if(SUCCEEDED(hres
= This
->pfnCreateInstance(pOuter
, (LPVOID
*) &punk
))) {
161 hres
= IUnknown_QueryInterface(punk
, riid
, ppobj
);
162 IUnknown_Release(punk
);
167 static HRESULT WINAPI
CF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
)
169 TRACE("(%d)\n", dolock
);
174 URLMON_UnlockModule();
179 static const IClassFactoryVtbl CF_Vtbl
=
188 /*******************************************************************************
189 * DllGetClassObject [URLMON.@]
190 * Retrieves class object from a DLL object
193 * Docs say returns STDAPI
196 * rclsid [I] CLSID for the class object
197 * riid [I] Reference to identifier of interface for class object
198 * ppv [O] Address of variable to receive interface pointer for riid
202 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
206 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
209 IClassFactoryImpl
*factory
;
211 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
213 if ( !IsEqualGUID( &IID_IClassFactory
, riid
)
214 && ! IsEqualGUID( &IID_IUnknown
, riid
) )
215 return E_NOINTERFACE
;
217 for (i
=0; i
< sizeof(object_creation
)/sizeof(object_creation
[0]); i
++)
219 if (IsEqualGUID(object_creation
[i
].clsid
, rclsid
))
223 if (i
== sizeof(object_creation
)/sizeof(object_creation
[0]))
225 FIXME("%s: no class found.\n", debugstr_guid(rclsid
));
226 return CLASS_E_CLASSNOTAVAILABLE
;
229 factory
= HeapAlloc(GetProcessHeap(), 0, sizeof(*factory
));
230 if (factory
== NULL
) return E_OUTOFMEMORY
;
232 factory
->ITF_IClassFactory
.lpVtbl
= &CF_Vtbl
;
234 factory
->pfnCreateInstance
= object_creation
[i
].pfnCreateInstance
;
236 *ppv
= &(factory
->ITF_IClassFactory
);
244 /***********************************************************************
245 * DllRegisterServerEx (URLMON.@)
247 HRESULT WINAPI
DllRegisterServerEx(void)
249 FIXME("(void): stub\n");
254 /**************************************************************************
255 * UrlMkSetSessionOption (URLMON.@)
257 HRESULT WINAPI
UrlMkSetSessionOption(DWORD dwOption
, LPVOID pBuffer
, DWORD dwBufferLength
,
260 FIXME("(%#lx, %p, %#lx): stub\n", dwOption
, pBuffer
, dwBufferLength
);
265 /**************************************************************************
266 * UrlMkGetSessionOption (URLMON.@)
268 HRESULT WINAPI
UrlMkGetSessionOption(DWORD dwOption
, LPVOID pBuffer
, DWORD dwBufferLength
,
269 DWORD
* pdwBufferLength
, DWORD dwReserved
)
271 FIXME("(%#lx, %p, %#lx, %p): stub\n", dwOption
, pBuffer
, dwBufferLength
, pdwBufferLength
);
276 static const CHAR Agent
[] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)";
278 /**************************************************************************
279 * ObtainUserAgentString (URLMON.@)
281 HRESULT WINAPI
ObtainUserAgentString(DWORD dwOption
, LPSTR pcszUAOut
, DWORD
*cbSize
)
283 FIXME("(%ld, %p, %p): stub\n", dwOption
, pcszUAOut
, cbSize
);
286 ERR("dwOption: %ld, must be zero\n", dwOption
);
289 if (sizeof(Agent
) < *cbSize
)
290 *cbSize
= sizeof(Agent
);
291 lstrcpynA(pcszUAOut
, Agent
, *cbSize
);
296 HRESULT WINAPI
CoInternetCombineUrl(LPCWSTR pwzBaseUrl
, LPCWSTR pwzRelativeUrl
, DWORD dwCombineFlags
,
297 LPWSTR pwzResult
, DWORD cchResult
, DWORD
*pcchResult
, DWORD dwReserved
)
300 DWORD size
= cchResult
;
302 TRACE("(%s,%s,0x%08lx,%p,%ld,%p,%ld)\n", debugstr_w(pwzBaseUrl
), debugstr_w(pwzRelativeUrl
), dwCombineFlags
,
303 pwzResult
, cchResult
, pcchResult
, dwReserved
);
304 hres
= UrlCombineW(pwzBaseUrl
, pwzRelativeUrl
, pwzResult
, &size
, dwCombineFlags
);
305 if(pcchResult
) *pcchResult
= size
;
309 HRESULT WINAPI
CoInternetCompareUrl(LPCWSTR pwzUrl1
, LPCWSTR pwzUrl2
, DWORD dwCompareFlags
)
311 TRACE("(%s,%s,%08lx)\n", debugstr_w(pwzUrl1
), debugstr_w(pwzUrl2
), dwCompareFlags
);
312 return UrlCompareW(pwzUrl1
, pwzUrl2
, dwCompareFlags
)==0?S_OK
:S_FALSE
;
315 /**************************************************************************
316 * IsValidURL (URLMON.@)
318 * Determines if a specified string is a valid URL.
321 * pBC [I] ignored, must be NULL.
322 * szURL [I] string that represents the URL in question.
323 * dwReserved [I] reserved and must be zero.
328 * returns E_INVALIDARG if one or more of the args is invalid.
331 * test functionality against windows to see what a valid URL is.
333 HRESULT WINAPI
IsValidURL(LPBC pBC
, LPCWSTR szURL
, DWORD dwReserved
)
335 FIXME("(%p, %s, %ld): stub\n", pBC
, debugstr_w(szURL
), dwReserved
);
337 if (pBC
!= NULL
|| dwReserved
!= 0)
343 /**************************************************************************
344 * FaultInIEFeature (URLMON.@)
346 * Undocumented. Appears to be used by native shdocvw.dll.
348 HRESULT WINAPI
FaultInIEFeature( HWND hwnd
, uCLSSPEC
* pClassSpec
,
349 QUERYCONTEXT
*pQuery
, DWORD flags
)
351 FIXME("%p %p %p %08lx\n", hwnd
, pClassSpec
, pQuery
, flags
);
355 /**************************************************************************
356 * CoGetClassObjectFromURL (URLMON.@)
358 HRESULT WINAPI
CoGetClassObjectFromURL( REFCLSID rclsid
, LPCWSTR szCodeURL
, DWORD dwFileVersionMS
,
359 DWORD dwFileVersionLS
, LPCWSTR szContentType
,
360 LPBINDCTX pBindCtx
, DWORD dwClsContext
, LPVOID pvReserved
,
361 REFIID riid
, LPVOID
*ppv
)
363 FIXME("(%s %s %ld %ld %s %p %ld %p %s %p) Stub!\n", debugstr_guid(rclsid
), debugstr_w(szCodeURL
),
364 dwFileVersionMS
, dwFileVersionLS
, debugstr_w(szContentType
), pBindCtx
, dwClsContext
, pvReserved
,
365 debugstr_guid(riid
), ppv
);
366 return E_NOINTERFACE
;
369 /***********************************************************************
370 * ReleaseBindInfo (URLMON.@)
372 * Release the resources used by the specified BINDINFO structure.
375 * pbindinfo [I] BINDINFO to release.
380 void WINAPI
ReleaseBindInfo(BINDINFO
* pbindinfo
)
382 TRACE("(%p)\n", pbindinfo
);
387 CoTaskMemFree(pbindinfo
->szExtraInfo
);
390 IUnknown_Release(pbindinfo
->pUnk
);
393 /***********************************************************************
394 * FindMimeFromData (URLMON.@)
396 * Determines the Multipurpose Internet Mail Extensions (MIME) type from the data provided.
398 HRESULT WINAPI
FindMimeFromData(LPBC pBC
, LPCWSTR pwzUrl
, LPVOID pBuffer
,
399 DWORD cbSize
, LPCWSTR pwzMimeProposed
, DWORD dwMimeFlags
,
400 LPWSTR
* ppwzMimeOut
, DWORD dwReserved
)
402 TRACE("(%p,%s,%p,%ld,%s,0x%lx,%p,0x%lx)\n", pBC
, debugstr_w(pwzUrl
), pBuffer
, cbSize
,
403 debugstr_w(pwzMimeProposed
), dwMimeFlags
, ppwzMimeOut
, dwReserved
);
406 WARN("dwMimeFlags=%08lx\n", dwMimeFlags
);
408 WARN("dwReserved=%ld\n", dwReserved
);
410 /* pBC seams to not be used */
412 if(!ppwzMimeOut
|| (!pwzUrl
&& !pBuffer
))
415 if(pwzMimeProposed
&& (!pwzUrl
|| !pBuffer
|| (pBuffer
&& !cbSize
))) {
421 len
= strlenW(pwzMimeProposed
)+1;
422 *ppwzMimeOut
= CoTaskMemAlloc(len
*sizeof(WCHAR
));
423 memcpy(*ppwzMimeOut
, pwzMimeProposed
, len
*sizeof(WCHAR
));
428 UCHAR
*ptr
= pBuffer
;
432 static const WCHAR wszAppOctetStream
[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
433 'o','c','t','e','t','-','s','t','r','e','a','m','\0'};
434 static const WCHAR wszTextPlain
[] = {'t','e','x','t','/','p','l','a','i','n','\0'};
440 for(ptr
= pBuffer
; ptr
< (UCHAR
*)pBuffer
+cbSize
-1; ptr
++) {
441 if(*ptr
< 0x20 && *ptr
!= '\n' && *ptr
!= '\r' && *ptr
!= '\t') {
442 ret
= wszAppOctetStream
;
447 len
= strlenW(ret
)+1;
448 *ppwzMimeOut
= CoTaskMemAlloc(len
*sizeof(WCHAR
));
449 memcpy(*ppwzMimeOut
, ret
, len
*sizeof(WCHAR
));
459 static const WCHAR wszContentType
[] =
460 {'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
462 ptr
= strrchrW(pwzUrl
, '.');
466 res
= RegOpenKeyW(HKEY_CLASSES_ROOT
, ptr
, &hkey
);
467 if(res
!= ERROR_SUCCESS
)
471 res
= RegQueryValueExW(hkey
, wszContentType
, NULL
, NULL
, (LPBYTE
)mime
, &size
);
473 if(res
!= ERROR_SUCCESS
)
476 *ppwzMimeOut
= CoTaskMemAlloc(size
);
477 memcpy(*ppwzMimeOut
, mime
, size
);