winebrowser: Use IUri API for URL-related logic.

This commit is contained in:
Jacek Caban 2011-12-08 16:36:33 +01:00 committed by Alexandre Julliard
parent 32955de353
commit dd7c38d044
2 changed files with 87 additions and 98 deletions

View File

@ -1,7 +1,7 @@
EXTRADEFS = -DWINE_NO_UNICODE_MACROS
MODULE = winebrowser.exe
APPMODE = -mwindows -municode
IMPORTS = shlwapi user32 advapi32
IMPORTS = urlmon oleaut32 user32 advapi32
C_SRCS = \
main.c

View File

@ -36,6 +36,7 @@
*/
#define WIN32_LEAN_AND_MEAN
#define COBJMACROS
#include "config.h"
#include "wine/port.h"
@ -66,15 +67,6 @@ static char *strdup_unixcp( const WCHAR *str )
return ret;
}
static WCHAR *strdupW( const WCHAR *src )
{
WCHAR *dst;
if (!src) return NULL;
if ((dst = HeapAlloc( GetProcessHeap(), 0, (strlenW( src ) + 1) * sizeof(WCHAR) )))
strcpyW( dst, src );
return dst;
}
/* try to launch a unix app from a comma separated string of app names */
static int launch_app( WCHAR *candidates, const WCHAR *argv1 )
{
@ -316,6 +308,58 @@ done:
return ret;
}
static IUri *convert_file_uri(IUri *uri)
{
wine_get_unix_file_name_t wine_get_unix_file_name_ptr;
IUriBuilder *uri_builder;
struct stat dummy;
WCHAR *new_path;
char *unixpath;
BSTR filename;
IUri *new_uri;
HRESULT hres;
/* check if the argument is a local file */
wine_get_unix_file_name_ptr = (wine_get_unix_file_name_t)
GetProcAddress( GetModuleHandleA( "KERNEL32" ), "wine_get_unix_file_name" );
if(!wine_get_unix_file_name_ptr)
return NULL;
hres = IUri_GetPath(uri, &filename);
if(FAILED(hres))
return NULL;
unixpath = wine_get_unix_file_name_ptr(filename);
SysFreeString(filename);
if(unixpath && stat(unixpath, &dummy) >= 0) {
int len;
len = MultiByteToWideChar(CP_UNIXCP, 0, unixpath, -1, NULL, 0);
new_path = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
if(new_path)
MultiByteToWideChar(CP_UNIXCP, 0, unixpath, -1, new_path, len);
HeapFree(GetProcessHeap(), 0, unixpath);
}else {
WINE_WARN("File %s does not exist\n", wine_dbgstr_a(unixpath));
HeapFree(GetProcessHeap(), 0, unixpath);
new_path = NULL;
}
hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
if(SUCCEEDED(hres) && new_path)
hres = IUriBuilder_SetPath(uri_builder, new_path);
HeapFree(GetProcessHeap(), 0, new_path);
if(FAILED(hres))
return NULL;
hres = IUriBuilder_CreateUri(uri_builder, 0, 0, 0, &new_uri);
IUriBuilder_Release(uri_builder);
if(FAILED(hres))
return NULL;
return new_uri;
}
/*****************************************************************************
* Main entry point. This is a console application so we have a wmain() not a
* winmain().
@ -323,11 +367,12 @@ done:
int wmain(int argc, WCHAR *argv[])
{
static const WCHAR nohomeW[] = {'-','n','o','h','o','m','e',0};
static const WCHAR mailtoW[] = {'m','a','i','l','t','o',':',0};
static const WCHAR fileW[] = {'f','i','l','e',':',0};
WCHAR *p, *filenameW = NULL, *fileurlW = NULL, *url = argv[1];
wine_get_unix_file_name_t wine_get_unix_file_name_ptr;
WCHAR *url = argv[1];
BSTR display_uri;
DWORD scheme;
IUri *uri;
HRESULT hres;
int ret = 1;
/* DDE used only if -nohome is specified; avoids delay in printing usage info
@ -335,103 +380,47 @@ int wmain(int argc, WCHAR *argv[])
if (url && !strcmpiW( url, nohomeW ))
url = argc > 2 ? argv[2] : get_url_from_dde();
if (!url)
{
if (!url) {
WINE_ERR( "Usage: winebrowser URL\n" );
goto done;
return -1;
}
/* handle an RFC1738 file URL */
if (!strncmpiW( url, fileW, 5 ))
{
DWORD len = strlenW( url ) + 1;
hres = CreateUri(url, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME|Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
if(FAILED(hres)) {
WINE_ERR("Failed to parse URL\n");
ret = open_http_url(url);
HeapFree(GetProcessHeap(), 0, ddeString);
return ret;
}
if (UrlUnescapeW( url, NULL, &len, URL_UNESCAPE_INPLACE ) != S_OK)
{
WINE_ERR( "unescaping URL failed: %s\n", wine_dbgstr_w(url) );
goto done;
}
HeapFree(GetProcessHeap(), 0, ddeString);
IUri_GetScheme(uri, &scheme);
/* look for a Windows path after 'file:' */
p = url + 5;
while (*p)
{
if (isalphaW( p[0] ) && (p[1] == ':' || p[1] == '|')) break;
p++;
}
if (!*p)
{
WINE_ERR( "no valid Windows path in: %s\n", wine_dbgstr_w(url) );
goto done;
}
if(scheme == URL_SCHEME_FILE) {
IUri *file_uri;
if (p[1] == '|') p[1] = ':';
url = p;
while (*p)
{
if (*p == '/') *p = '\\';
p++;
file_uri = convert_file_uri(uri);
if(file_uri) {
IUri_Release(uri);
uri = file_uri;
}else {
WINE_ERR("Failed to convert file URL to unix path\n");
}
}
/* check if the argument is a local file */
wine_get_unix_file_name_ptr = (wine_get_unix_file_name_t)
GetProcAddress( GetModuleHandleA( "KERNEL32" ), "wine_get_unix_file_name" );
hres = IUri_GetDisplayUri(uri, &display_uri);
IUri_Release(uri);
if(FAILED(hres))
return -1;
if (wine_get_unix_file_name_ptr == NULL)
{
WINE_ERR( "cannot get the address of 'wine_get_unix_file_name'\n" );
}
else
{
char *unixpath;
WCHAR c = 0;
WINE_TRACE("opening %s\n", wine_dbgstr_w(display_uri));
if (!(filenameW = strdupW( url ))) goto done;
if ((p = strchrW( filenameW, '?' )) || (p = strchrW( filenameW, '#' )))
{
c = *p;
*p = 0;
}
if ((unixpath = wine_get_unix_file_name_ptr( filenameW )))
{
struct stat dummy;
if (stat( unixpath, &dummy ) >= 0)
{
static const WCHAR schemeW[] = {'f','i','l','e',':','/','/',0};
int len, len_scheme;
len = len_scheme = strlenW( schemeW );
len += MultiByteToWideChar( CP_UNIXCP, 0, unixpath, -1, NULL, 0 );
if (p)
{
*p = c;
len += strlenW( p );
}
if (!(fileurlW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) goto done;
strcpyW( fileurlW, schemeW );
MultiByteToWideChar( CP_UNIXCP, 0, unixpath, -1, fileurlW + len_scheme, len - len_scheme );
if (p) strcatW( fileurlW, p );
ret = open_http_url( fileurlW );
goto done;
}
}
}
if (!strncmpiW( url, mailtoW, 7 ))
ret = open_mailto_url( url );
if(scheme == URL_SCHEME_MAILTO)
ret = open_mailto_url(display_uri);
else
/* let the browser decide how to handle the given url */
ret = open_http_url( url );
ret = open_http_url(display_uri);
done:
HeapFree(GetProcessHeap(), 0, ddeString);
HeapFree( GetProcessHeap(), 0, filenameW );
HeapFree( GetProcessHeap(), 0, fileurlW );
SysFreeString(display_uri);
return ret;
}