wine/dlls/urlmon/internet.c

408 lines
12 KiB
C

/*
* Copyright 2005 Jacek Caban
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "urlmon_main.h"
#include "winreg.h"
#include "shlwapi.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
{
WCHAR *ptr;
DWORD len = 0;
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
if(flags)
ERR("wrong flags\n");
ptr = strchrW(url, ':');
if(ptr)
len = ptr-url;
if(rsize)
*rsize = len;
if(len >= size)
return E_POINTER;
if(len)
memcpy(result, url, len*sizeof(WCHAR));
result[len] = 0;
return S_OK;
}
static HRESULT parse_canonicalize_url(LPCWSTR url, DWORD flags, LPWSTR result,
DWORD size, DWORD *rsize)
{
IInternetProtocolInfo *protocol_info;
DWORD prsize = size;
HRESULT hres;
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
protocol_info = get_protocol_info(url);
if(protocol_info) {
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_CANONICALIZE,
flags, result, size, rsize, 0);
IInternetProtocolInfo_Release(protocol_info);
if(SUCCEEDED(hres))
return hres;
}
hres = UrlCanonicalizeW(url, result, &prsize, flags);
if(rsize)
*rsize = prsize;
return hres;
}
static HRESULT parse_security_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
{
IInternetProtocolInfo *protocol_info;
HRESULT hres;
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
protocol_info = get_protocol_info(url);
if(protocol_info) {
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_URL,
flags, result, size, rsize, 0);
IInternetProtocolInfo_Release(protocol_info);
return hres;
}
return E_FAIL;
}
static HRESULT parse_encode(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
{
IInternetProtocolInfo *protocol_info;
DWORD prsize;
HRESULT hres;
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
protocol_info = get_protocol_info(url);
if(protocol_info) {
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ENCODE,
flags, result, size, rsize, 0);
IInternetProtocolInfo_Release(protocol_info);
if(SUCCEEDED(hres))
return hres;
}
prsize = size;
hres = UrlUnescapeW((LPWSTR)url, result, &prsize, flags);
if(rsize)
*rsize = prsize;
return hres;
}
static HRESULT parse_path_from_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize)
{
IInternetProtocolInfo *protocol_info;
DWORD prsize;
HRESULT hres;
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
protocol_info = get_protocol_info(url);
if(protocol_info) {
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_PATH_FROM_URL,
flags, result, size, rsize, 0);
IInternetProtocolInfo_Release(protocol_info);
if(SUCCEEDED(hres))
return hres;
}
prsize = size;
hres = PathCreateFromUrlW(url, result, &prsize, 0);
if(rsize)
*rsize = prsize;
return hres;
}
static HRESULT parse_security_domain(LPCWSTR url, DWORD flags, LPWSTR result,
DWORD size, DWORD *rsize)
{
IInternetProtocolInfo *protocol_info;
HRESULT hres;
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
protocol_info = get_protocol_info(url);
if(protocol_info) {
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_SECURITY_DOMAIN,
flags, result, size, rsize, 0);
IInternetProtocolInfo_Release(protocol_info);
if(SUCCEEDED(hres))
return hres;
}
return E_FAIL;
}
static HRESULT parse_domain(LPCWSTR url, DWORD flags, LPWSTR result,
DWORD size, DWORD *rsize)
{
IInternetProtocolInfo *protocol_info;
HRESULT hres;
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
protocol_info = get_protocol_info(url);
if(protocol_info) {
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_DOMAIN,
flags, result, size, rsize, 0);
IInternetProtocolInfo_Release(protocol_info);
if(SUCCEEDED(hres))
return hres;
}
hres = UrlGetPartW(url, result, &size, URL_PART_HOSTNAME, flags);
if(rsize)
*rsize = size;
if(hres == E_POINTER)
return S_FALSE;
if(FAILED(hres))
return E_FAIL;
return S_OK;
}
static HRESULT parse_rootdocument(LPCWSTR url, DWORD flags, LPWSTR result,
DWORD size, DWORD *rsize)
{
IInternetProtocolInfo *protocol_info;
PARSEDURLW url_info;
HRESULT hres;
TRACE("(%s %08x %p %d %p)\n", debugstr_w(url), flags, result, size, rsize);
protocol_info = get_protocol_info(url);
if(protocol_info) {
hres = IInternetProtocolInfo_ParseUrl(protocol_info, url, PARSE_ROOTDOCUMENT,
flags, result, size, rsize, 0);
IInternetProtocolInfo_Release(protocol_info);
if(SUCCEEDED(hres))
return hres;
}
url_info.cbSize = sizeof(url_info);
if(FAILED(ParseURLW(url, &url_info)))
return E_FAIL;
switch(url_info.nScheme) {
case URL_SCHEME_FTP:
case URL_SCHEME_HTTP:
case URL_SCHEME_HTTPS:
if(url_info.cchSuffix<3 || *(url_info.pszSuffix)!='/'
|| *(url_info.pszSuffix+1)!='/')
return E_FAIL;
if(size < url_info.cchProtocol+3) {
size = 0;
hres = UrlGetPartW(url, result, &size, URL_PART_HOSTNAME, flags);
if(rsize)
*rsize = size+url_info.cchProtocol+3;
if(hres == E_POINTER)
return S_FALSE;
return hres;
}
size -= url_info.cchProtocol+3;
hres = UrlGetPartW(url, result+url_info.cchProtocol+3,
&size, URL_PART_HOSTNAME, flags);
if(hres == E_POINTER)
return S_FALSE;
if(FAILED(hres))
return E_FAIL;
if(rsize)
*rsize = size+url_info.cchProtocol+3;
memcpy(result, url, (url_info.cchProtocol+3)*sizeof(WCHAR));
return hres;
default:
return E_FAIL;
}
}
/**************************************************************************
* CoInternetParseUrl (URLMON.@)
*/
HRESULT WINAPI CoInternetParseUrl(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD dwFlags,
LPWSTR pszResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
{
if(dwReserved)
WARN("dwReserved = %d\n", dwReserved);
switch(ParseAction) {
case PARSE_CANONICALIZE:
return parse_canonicalize_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
case PARSE_SECURITY_URL:
return parse_security_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
case PARSE_ENCODE:
return parse_encode(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
case PARSE_PATH_FROM_URL:
return parse_path_from_url(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
case PARSE_SCHEMA:
return parse_schema(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
case PARSE_SECURITY_DOMAIN:
return parse_security_domain(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
case PARSE_DOMAIN:
return parse_domain(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
case PARSE_ROOTDOCUMENT:
return parse_rootdocument(pwzUrl, dwFlags, pszResult, cchResult, pcchResult);
default:
FIXME("not supported action %d\n", ParseAction);
}
return E_NOTIMPL;
}
/**************************************************************************
* CoInternetCombineUrl (URLMON.@)
*/
HRESULT WINAPI CoInternetCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult,
DWORD dwReserved)
{
IInternetProtocolInfo *protocol_info;
DWORD size = cchResult;
HRESULT hres;
TRACE("(%s,%s,0x%08x,%p,%d,%p,%d)\n", debugstr_w(pwzBaseUrl),
debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult, pcchResult,
dwReserved);
protocol_info = get_protocol_info(pwzBaseUrl);
if(protocol_info) {
hres = IInternetProtocolInfo_CombineUrl(protocol_info, pwzBaseUrl, pwzRelativeUrl,
dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
IInternetProtocolInfo_Release(protocol_info);
if(SUCCEEDED(hres))
return hres;
}
hres = UrlCombineW(pwzBaseUrl, pwzRelativeUrl, pwzResult, &size, dwCombineFlags);
if(pcchResult)
*pcchResult = size;
return hres;
}
/**************************************************************************
* CoInternetCompareUrl (URLMON.@)
*/
HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags)
{
IInternetProtocolInfo *protocol_info;
HRESULT hres;
TRACE("(%s,%s,%08x)\n", debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
protocol_info = get_protocol_info(pwzUrl1);
if(protocol_info) {
hres = IInternetProtocolInfo_CompareUrl(protocol_info, pwzUrl1, pwzUrl2, dwCompareFlags);
IInternetProtocolInfo_Release(protocol_info);
if(SUCCEEDED(hres))
return hres;
}
return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags) ? S_FALSE : S_OK;
}
/***********************************************************************
* CoInternetQueryInfo (URLMON.@)
*
* Retrieves information relevant to a specified URL
*
*/
HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption,
DWORD dwQueryFlags, LPVOID pvBuffer, DWORD cbBuffer, DWORD *pcbBuffer,
DWORD dwReserved)
{
IInternetProtocolInfo *protocol_info;
HRESULT hres;
TRACE("(%s, %x, %x, %p, %x, %p, %x): stub\n", debugstr_w(pwzUrl),
QueryOption, dwQueryFlags, pvBuffer, cbBuffer, pcbBuffer, dwReserved);
protocol_info = get_protocol_info(pwzUrl);
if(protocol_info) {
hres = IInternetProtocolInfo_QueryInfo(protocol_info, pwzUrl, QueryOption, dwQueryFlags,
pvBuffer, cbBuffer, pcbBuffer, dwReserved);
IInternetProtocolInfo_Release(protocol_info);
return SUCCEEDED(hres) ? hres : E_FAIL;
}
switch(QueryOption) {
case QUERY_USES_NETWORK:
if(!pvBuffer || cbBuffer < sizeof(DWORD))
return E_FAIL;
*(DWORD*)pvBuffer = 0;
if(pcbBuffer)
*pcbBuffer = sizeof(DWORD);
break;
default:
FIXME("Not supported option %d\n", QueryOption);
return E_NOTIMPL;
}
return S_OK;
}
/***********************************************************************
* CoInternetSetFeatureEnabled (URLMON.@)
*/
HRESULT WINAPI CoInternetSetFeatureEnabled(INTERNETFEATURELIST feature, DWORD flags, BOOL enable)
{
FIXME("%d, 0x%08x, %x, stub\n", feature, flags, enable);
return E_NOTIMPL;
}