winebrowser: Use IUri API for URL-related logic.
This commit is contained in:
parent
32955de353
commit
dd7c38d044
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue