2 * Copyright 2005-2006 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "urlmon_main.h"
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(urlmon
);
36 typedef struct name_space
{
40 struct name_space
*next
;
43 static name_space
*name_space_list
= NULL
;
45 static IClassFactory
*find_name_space(LPCWSTR protocol
)
49 for(iter
= name_space_list
; iter
; iter
= iter
->next
) {
50 if(!strcmpW(iter
->protocol
, protocol
))
57 static HRESULT
get_protocol_iface(LPCWSTR schema
, DWORD schema_len
, IUnknown
**ret
)
61 DWORD res
, type
, size
;
66 static const WCHAR wszProtocolsKey
[] =
67 {'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'};
68 static const WCHAR wszCLSID
[] = {'C','L','S','I','D',0};
70 wszKey
= HeapAlloc(GetProcessHeap(), 0, sizeof(wszProtocolsKey
)+(schema_len
+1)*sizeof(WCHAR
));
71 memcpy(wszKey
, wszProtocolsKey
, sizeof(wszProtocolsKey
));
72 memcpy(wszKey
+ sizeof(wszProtocolsKey
)/sizeof(WCHAR
), schema
, (schema_len
+1)*sizeof(WCHAR
));
74 res
= RegOpenKeyW(HKEY_CLASSES_ROOT
, wszKey
, &hkey
);
75 HeapFree(GetProcessHeap(), 0, wszKey
);
76 if(res
!= ERROR_SUCCESS
) {
77 TRACE("Could not open protocol handler key\n");
81 size
= sizeof(str_clsid
);
82 res
= RegQueryValueExW(hkey
, wszCLSID
, NULL
, &type
, (LPBYTE
)str_clsid
, &size
);
84 if(res
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
85 WARN("Could not get protocol CLSID res=%ld\n", res
);
89 hres
= CLSIDFromString(str_clsid
, &clsid
);
91 WARN("CLSIDFromString failed: %08lx\n", hres
);
95 return CoGetClassObject(&clsid
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, (void**)ret
);
98 IInternetProtocolInfo
*get_protocol_info(LPCWSTR url
)
100 IInternetProtocolInfo
*ret
= NULL
;
107 hres
= CoInternetParseUrl(url
, PARSE_SCHEMA
, 0, schema
, sizeof(schema
)/sizeof(schema
[0]),
109 if(FAILED(hres
) || !schema_len
)
112 cf
= find_name_space(schema
);
114 hres
= IClassFactory_QueryInterface(cf
, &IID_IInternetProtocolInfo
, (void**)&ret
);
118 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IInternetProtocolInfo
, (void**)&ret
);
123 hres
= get_protocol_iface(schema
, schema_len
, &unk
);
127 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocolInfo
, (void**)&ret
);
128 IUnknown_Release(unk
);
133 HRESULT
get_protocol_handler(LPCWSTR url
, IClassFactory
**ret
)
141 hres
= CoInternetParseUrl(url
, PARSE_SCHEMA
, 0, schema
, sizeof(schema
)/sizeof(schema
[0]),
143 if(FAILED(hres
) || !schema_len
)
144 return schema_len
? hres
: E_FAIL
;
146 cf
= find_name_space(schema
);
152 hres
= get_protocol_iface(schema
, schema_len
, &unk
);
156 hres
= IUnknown_QueryInterface(unk
, &IID_IClassFactory
, (void**)ret
);
157 IUnknown_Release(unk
);
161 static HRESULT WINAPI
InternetSession_QueryInterface(IInternetSession
*iface
,
162 REFIID riid
, void **ppv
)
164 TRACE("(%s %p)\n", debugstr_guid(riid
), ppv
);
166 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IInternetSession
, riid
)) {
168 IInternetSession_AddRef(iface
);
173 return E_NOINTERFACE
;
176 static ULONG WINAPI
InternetSession_AddRef(IInternetSession
*iface
)
183 static ULONG WINAPI
InternetSession_Release(IInternetSession
*iface
)
186 URLMON_UnlockModule();
190 static HRESULT WINAPI
InternetSession_RegisterNameSpace(IInternetSession
*iface
,
191 IClassFactory
*pCF
, REFCLSID rclsid
, LPCWSTR pwzProtocol
, ULONG cPatterns
,
192 const LPCWSTR
*ppwzPatterns
, DWORD dwReserved
)
194 name_space
*new_name_space
;
197 TRACE("(%p %s %s %ld %p %ld)\n", pCF
, debugstr_guid(rclsid
), debugstr_w(pwzProtocol
),
198 cPatterns
, ppwzPatterns
, dwReserved
);
200 if(cPatterns
|| ppwzPatterns
)
201 FIXME("patterns not supported\n");
203 WARN("dwReserved = %ld\n", dwReserved
);
205 if(!pCF
|| !pwzProtocol
)
208 new_name_space
= HeapAlloc(GetProcessHeap(), 0, sizeof(name_space
));
210 size
= (strlenW(pwzProtocol
)+1)*sizeof(WCHAR
);
211 new_name_space
->protocol
= HeapAlloc(GetProcessHeap(), 0, size
);
212 memcpy(new_name_space
->protocol
, pwzProtocol
, size
);
214 IClassFactory_AddRef(pCF
);
215 new_name_space
->cf
= pCF
;
217 new_name_space
->next
= name_space_list
;
218 name_space_list
= new_name_space
;
222 static HRESULT WINAPI
InternetSession_UnregisterNameSpace(IInternetSession
*iface
,
223 IClassFactory
*pCF
, LPCWSTR pszProtocol
)
225 name_space
*iter
, *last
= NULL
;
227 TRACE("(%p %s)\n", pCF
, debugstr_w(pszProtocol
));
229 if(!pCF
|| !pszProtocol
)
232 for(iter
= name_space_list
; iter
; iter
= iter
->next
) {
233 if(iter
->cf
== pCF
&& !strcmpW(iter
->protocol
, pszProtocol
))
242 last
->next
= iter
->next
;
244 name_space_list
= iter
->next
;
246 IClassFactory_Release(iter
->cf
);
247 HeapFree(GetProcessHeap(), 0, iter
->protocol
);
248 HeapFree(GetProcessHeap(), 0, iter
);
253 static HRESULT WINAPI
InternetSession_RegisterMimeFilter(IInternetSession
*iface
,
254 IClassFactory
*pCF
, REFCLSID rclsid
, LPCWSTR pwzType
)
256 FIXME("(%p %s %s)\n", pCF
, debugstr_guid(rclsid
), debugstr_w(pwzType
));
260 static HRESULT WINAPI
InternetSession_UnregisterMimeFilter(IInternetSession
*iface
,
261 IClassFactory
*pCF
, LPCWSTR pwzType
)
263 FIXME("(%p %s)\n", pCF
, debugstr_w(pwzType
));
267 static HRESULT WINAPI
InternetSession_CreateBinding(IInternetSession
*iface
,
268 LPBC pBC
, LPCWSTR szUrl
, IUnknown
*pUnkOuter
, IUnknown
**ppUnk
,
269 IInternetProtocol
**ppOInetProt
, DWORD dwOption
)
271 FIXME("(%p %s %p %p %p %08lx)\n", pBC
, debugstr_w(szUrl
), pUnkOuter
, ppUnk
,
272 ppOInetProt
, dwOption
);
276 static HRESULT WINAPI
InternetSession_SetSessionOption(IInternetSession
*iface
,
277 DWORD dwOption
, LPVOID pBuffer
, DWORD dwBufferLength
, DWORD dwReserved
)
279 FIXME("(%08lx %p %ld %ld)\n", dwOption
, pBuffer
, dwBufferLength
, dwReserved
);
283 static const IInternetSessionVtbl InternetSessionVtbl
= {
284 InternetSession_QueryInterface
,
285 InternetSession_AddRef
,
286 InternetSession_Release
,
287 InternetSession_RegisterNameSpace
,
288 InternetSession_UnregisterNameSpace
,
289 InternetSession_RegisterMimeFilter
,
290 InternetSession_UnregisterMimeFilter
,
291 InternetSession_CreateBinding
,
292 InternetSession_SetSessionOption
295 static IInternetSession InternetSession
= { &InternetSessionVtbl
};
297 /***********************************************************************
298 * CoInternetGetSession (URLMON.@)
300 * Create a new internet session and return an IInternetSession interface
304 * dwSessionMode [I] Mode for the internet session
305 * ppIInternetSession [O] Destination for creates IInternetSession object
306 * dwReserved [I] Reserved, must be 0.
309 * Success: S_OK. ppIInternetSession contains the IInternetSession interface.
310 * Failure: E_INVALIDARG, if any argument is invalid, or
311 * E_OUTOFMEMORY if memory allocation fails.
313 HRESULT WINAPI
CoInternetGetSession(DWORD dwSessionMode
, IInternetSession
**ppIInternetSession
,
316 TRACE("(%ld %p %ld)\n", dwSessionMode
, ppIInternetSession
, dwReserved
);
319 ERR("dwSessionMode=%ld\n", dwSessionMode
);
321 ERR("dwReserved=%ld\n", dwReserved
);
323 *ppIInternetSession
= &InternetSession
;
327 /**************************************************************************
328 * UrlMkGetSessionOption (URLMON.@)
330 static BOOL
get_url_encoding(HKEY root
, DWORD
*encoding
)
332 DWORD size
= sizeof(DWORD
), res
, type
;
335 static const WCHAR wszKeyName
[] =
336 {'S','O','F','T','W','A','R','E',
337 '\\','M','i','c','r','o','s','o','f','t',
338 '\\','W','i','n','d','o','w','s',
339 '\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',
340 '\\','I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0};
341 static const WCHAR wszUrlEncoding
[] = {'U','r','l','E','n','c','o','d','i','n','g',0};
343 res
= RegOpenKeyW(root
, wszKeyName
, &hkey
);
344 if(res
!= ERROR_SUCCESS
)
347 res
= RegQueryValueExW(hkey
, wszUrlEncoding
, NULL
, &type
, (LPBYTE
)encoding
, &size
);
350 return res
== ERROR_SUCCESS
;
353 HRESULT WINAPI
UrlMkGetSessionOption(DWORD dwOption
, LPVOID pBuffer
, DWORD dwBufferLength
,
354 DWORD
* pdwBufferLength
, DWORD dwReserved
)
356 TRACE("(%lx, %p, %ld, %p)\n", dwOption
, pBuffer
, dwBufferLength
, pdwBufferLength
);
359 WARN("dwReserved = %ld\n", dwReserved
);
362 case URLMON_OPTION_URL_ENCODING
: {
365 if(!pBuffer
|| dwBufferLength
< sizeof(DWORD
) || !pdwBufferLength
)
368 if(!get_url_encoding(HKEY_CURRENT_USER
, &encoding
))
369 get_url_encoding(HKEY_LOCAL_MACHINE
, &encoding
);
371 *pdwBufferLength
= sizeof(DWORD
);
372 *(DWORD
*)pBuffer
= encoding
? URL_ENCODING_DISABLE_UTF8
: URL_ENCODING_ENABLE_UTF8
;
376 FIXME("unsupported option %lx\n", dwOption
);