diff --git a/programs/winebrowser/Makefile.in b/programs/winebrowser/Makefile.in index 0dee0702cec..a2e27937714 100644 --- a/programs/winebrowser/Makefile.in +++ b/programs/winebrowser/Makefile.in @@ -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 diff --git a/programs/winebrowser/main.c b/programs/winebrowser/main.c index 8635ad2bc06..9e94fd5cb22 100644 --- a/programs/winebrowser/main.c +++ b/programs/winebrowser/main.c @@ -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; }