Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
8a67308f
Commit
8a67308f
authored
Oct 05, 2023
by
Gabriel Ivăncescu
Committed by
Alexandre Julliard
Oct 06, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ieframe: Navigate to a basic error page on failed navigation.
Signed-off-by:
Gabriel Ivăncescu
<
gabrielopcode@gmail.com
>
parent
125c390f
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
197 additions
and
7 deletions
+197
-7
ieframe.h
dlls/ieframe/ieframe.h
+1
-0
navigate.c
dlls/ieframe/navigate.c
+45
-4
ie.c
dlls/ieframe/tests/ie.c
+151
-3
No files found.
dlls/ieframe/ieframe.h
View file @
8a67308f
...
...
@@ -277,6 +277,7 @@ HRESULT go_home(DocHost*);
HRESULT
go_back
(
DocHost
*
);
HRESULT
go_forward
(
DocHost
*
);
HRESULT
refresh_document
(
DocHost
*
,
const
VARIANT
*
);
HRESULT
get_window
(
DocHost
*
,
IHTMLWindow2
**
);
HRESULT
get_location_url
(
DocHost
*
,
BSTR
*
);
HRESULT
set_dochost_url
(
DocHost
*
,
const
WCHAR
*
);
void
handle_navigation_error
(
DocHost
*
,
HRESULT
,
BSTR
,
IHTMLWindow2
*
);
...
...
dlls/ieframe/navigate.c
View file @
8a67308f
...
...
@@ -306,12 +306,13 @@ static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface,
return
S_OK
;
}
void
handle_navigation_error
(
DocHost
*
doc_host
,
HRESULT
hres
,
BSTR
url
,
IHTMLWindow2
*
win2
)
void
handle_navigation_error
(
DocHost
*
doc_host
,
HRESULT
status_code
,
BSTR
url
,
IHTMLWindow2
*
win2
)
{
VARIANT
var_status_code
,
var_frame_name
,
var_url
;
DISPPARAMS
dispparams
;
VARIANTARG
params
[
5
];
VARIANT_BOOL
cancel
=
VARIANT_FALSE
;
HRESULT
hres
;
dispparams
.
cArgs
=
5
;
dispparams
.
cNamedArgs
=
0
;
...
...
@@ -324,7 +325,7 @@ void handle_navigation_error(DocHost* doc_host, HRESULT hres, BSTR url, IHTMLWin
V_VT
(
params
+
1
)
=
VT_VARIANT
|
VT_BYREF
;
V_VARIANTREF
(
params
+
1
)
=
&
var_status_code
;
V_VT
(
&
var_status_code
)
=
VT_I4
;
V_I4
(
&
var_status_code
)
=
hres
;
V_I4
(
&
var_status_code
)
=
status_code
;
V_VT
(
params
+
2
)
=
VT_VARIANT
|
VT_BYREF
;
V_VARIANTREF
(
params
+
2
)
=
&
var_frame_name
;
...
...
@@ -347,8 +348,48 @@ void handle_navigation_error(DocHost* doc_host, HRESULT hres, BSTR url, IHTMLWin
call_sink
(
doc_host
->
cps
.
wbe2
,
DISPID_NAVIGATEERROR
,
&
dispparams
);
SysFreeString
(
V_BSTR
(
&
var_frame_name
));
if
(
!
cancel
)
FIXME
(
"Navigate to error page
\n
"
);
if
(
!
cancel
)
{
IHTMLPrivateWindow
*
priv_window
;
IHTMLWindow2
*
tmp
;
if
(
win2
)
hres
=
IHTMLWindow2_QueryInterface
(
win2
,
&
IID_IHTMLPrivateWindow
,
(
void
**
)
&
priv_window
);
else
{
hres
=
get_window
(
doc_host
,
&
tmp
);
if
(
SUCCEEDED
(
hres
))
{
if
(
!
tmp
)
hres
=
E_UNEXPECTED
;
else
{
hres
=
IHTMLWindow2_QueryInterface
(
tmp
,
&
IID_IHTMLPrivateWindow
,
(
void
**
)
&
priv_window
);
IHTMLWindow2_Release
(
tmp
);
}
}
}
if
(
SUCCEEDED
(
hres
))
{
/* Error page navigation URL is a local resource (varies on native, also depending on error),
* with the fragment being the original URL of the page that failed to load. We add a query
* with the error code so the generic error page can display the actual error code there. */
WCHAR
buf
[
32
],
sysdirbuf
[
MAX_PATH
];
BSTR
nav_url
;
UINT
len
;
if
(
SUCCEEDED
(
status_code
))
len
=
swprintf
(
buf
,
ARRAY_SIZE
(
buf
),
L"ERROR.HTM?HTTP %u"
,
status_code
);
else
len
=
swprintf
(
buf
,
ARRAY_SIZE
(
buf
),
L"ERROR.HTM?0x%08x"
,
status_code
);
len
=
6
/* res:// */
+
GetSystemDirectoryW
(
sysdirbuf
,
ARRAY_SIZE
(
sysdirbuf
))
+
ARRAY_SIZE
(
L"
\\
shdoclc.dll/"
)
-
1
+
len
+
1
/* # */
+
wcslen
(
url
);
nav_url
=
SysAllocStringLen
(
NULL
,
len
);
if
(
nav_url
)
{
swprintf
(
nav_url
,
len
+
1
,
L"res://%s
\\
shdoclc.dll/%s#%s"
,
sysdirbuf
,
buf
,
url
);
IHTMLPrivateWindow_SuperNavigate
(
priv_window
,
nav_url
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
2
);
SysFreeString
(
nav_url
);
}
IHTMLPrivateWindow_Release
(
priv_window
);
}
}
}
static
HRESULT
WINAPI
BindStatusCallback_OnStopBinding
(
IBindStatusCallback
*
iface
,
...
...
dlls/ieframe/tests/ie.c
View file @
8a67308f
...
...
@@ -55,9 +55,72 @@
expect_ ## func = called_ ## func = FALSE; \
}while(0)
DEFINE_EXPECT
(
Invoke_BEFORENAVIGATE2
);
DEFINE_EXPECT
(
Invoke_NAVIGATECOMPLETE2
);
DEFINE_EXPECT
(
Invoke_NAVIGATEERROR
);
DEFINE_EXPECT
(
Invoke_DOCUMENTCOMPLETE
);
static
BOOL
navigate_complete
;
static
BOOL
navigate_complete
,
navigation_timed_out
;
static
const
WCHAR
*
navigate_url
;
static
BSTR
get_window_url
(
IDispatch
*
webbrowser
)
{
IHTMLPrivateWindow
*
priv_window
;
IHTMLLocation
*
location
;
IHTMLWindow2
*
window
;
IServiceProvider
*
sp
;
IHTMLDocument2
*
doc
;
HRESULT
hres
;
BSTR
url
;
hres
=
IDispatch_QueryInterface
(
webbrowser
,
&
IID_IServiceProvider
,
(
void
**
)
&
sp
);
ok
(
hres
==
S_OK
,
"QueryInterface(IServiceProvider) failed: %08lx
\n
"
,
hres
);
hres
=
IServiceProvider_QueryService
(
sp
,
&
SID_SHTMLWindow
,
&
IID_IHTMLWindow2
,
(
void
**
)
&
window
);
ok
(
hres
==
S_OK
,
"Could not get SHTMLWindow service: %08lx
\n
"
,
hres
);
ok
(
window
!=
NULL
,
"window = NULL
\n
"
);
IServiceProvider_Release
(
sp
);
hres
=
IHTMLWindow2_QueryInterface
(
window
,
&
IID_IHTMLPrivateWindow
,
(
void
**
)
&
priv_window
);
ok
(
hres
==
E_NOINTERFACE
,
"QueryInterface(IID_IHTMLPrivateWindow) returned: %08lx
\n
"
,
hres
);
hres
=
IHTMLWindow2_get_document
(
window
,
&
doc
);
ok
(
hres
==
S_OK
,
"get_document failed: %08lx
\n
"
,
hres
);
ok
(
doc
!=
NULL
,
"doc = NULL
\n
"
);
IHTMLWindow2_Release
(
window
);
hres
=
IHTMLDocument2_get_parentWindow
(
doc
,
&
window
);
ok
(
hres
==
S_OK
,
"get_parentWindow failed: %08lx
\n
"
,
hres
);
ok
(
window
!=
NULL
,
"window = NULL
\n
"
);
IHTMLDocument2_Release
(
doc
);
hres
=
IHTMLWindow2_get_location
(
window
,
&
location
);
ok
(
hres
==
S_OK
,
"get_location failed: %08lx
\n
"
,
hres
);
ok
(
location
!=
NULL
,
"location = NULL
\n
"
);
IHTMLWindow2_Release
(
window
);
hres
=
IHTMLLocation_get_href
(
location
,
&
url
);
ok
(
hres
==
S_OK
,
"get_href failed: %08lx
\n
"
,
hres
);
ok
(
url
!=
NULL
,
"url = NULL
\n
"
);
IHTMLLocation_Release
(
location
);
return
url
;
}
#define test_url(a) _test_url(__LINE__,a)
static
void
_test_url
(
unsigned
line
,
const
WCHAR
*
url
)
{
/* If error page, it actually returns the error page's resource URL, followed by #, followed by the original URL.
Since the error page's location varies on native, and depends on the error itself, just check for res:// here. */
if
(
called_Invoke_NAVIGATEERROR
)
{
ok_
(
__FILE__
,
line
)(
!
wcsncmp
(
url
,
L"res://"
,
ARRAY_SIZE
(
L"res://"
)
-
1
),
"url is not a local resource: %s
\n
"
,
wine_dbgstr_w
(
url
));
url
=
wcschr
(
url
,
'#'
);
ok_
(
__FILE__
,
line
)(
url
!=
NULL
,
"url has no fragment: %s
\n
"
,
wine_dbgstr_w
(
url
));
ok_
(
__FILE__
,
line
)(
!
wcscmp
(
url
+
1
,
navigate_url
),
"url after fragment = %s
\n
"
,
wine_dbgstr_w
(
url
+
1
));
}
else
{
ok_
(
__FILE__
,
line
)(
!
wcscmp
(
url
,
navigate_url
),
"url = %s
\n
"
,
wine_dbgstr_w
(
url
));
}
}
static
HRESULT
WINAPI
Dispatch_QueryInterface
(
IDispatch
*
iface
,
REFIID
riid
,
void
**
ppv
)
{
...
...
@@ -104,10 +167,64 @@ static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REF
LCID
lcid
,
WORD
wFlags
,
DISPPARAMS
*
pDispParams
,
VARIANT
*
pVarResult
,
EXCEPINFO
*
pExcepInfo
,
UINT
*
puArgErr
)
{
VARIANT
*
arg
;
BSTR
url
;
switch
(
dispIdMember
)
{
case
DISPID_BEFORENAVIGATE2
:
CHECK_EXPECT
(
Invoke_BEFORENAVIGATE2
);
arg
=
pDispParams
->
rgvarg
+
5
;
ok
(
V_VT
(
arg
)
==
(
VT_BYREF
|
VT_VARIANT
),
"VT = %d
\n
"
,
V_VT
(
arg
));
ok
(
V_VT
(
V_VARIANTREF
(
arg
))
==
VT_BSTR
,
"VT = %d
\n
"
,
V_VT
(
V_VARIANTREF
(
arg
)));
test_url
(
V_BSTR
(
V_VARIANTREF
(
arg
)));
return
S_OK
;
case
DISPID_NAVIGATECOMPLETE2
:
CHECK_EXPECT
(
Invoke_NAVIGATECOMPLETE2
);
arg
=
pDispParams
->
rgvarg
;
ok
(
V_VT
(
arg
)
==
(
VT_BYREF
|
VT_VARIANT
),
"VT = %d
\n
"
,
V_VT
(
arg
));
ok
(
V_VT
(
V_VARIANTREF
(
arg
))
==
VT_BSTR
,
"VT = %d
\n
"
,
V_VT
(
V_VARIANTREF
(
arg
)));
todo_wine_if
(
called_Invoke_NAVIGATEERROR
)
ok
(
!
wcscmp
(
V_BSTR
(
V_VARIANTREF
(
arg
)),
navigate_url
),
"url = %s
\n
"
,
wine_dbgstr_w
(
V_BSTR
(
V_VARIANTREF
(
arg
))));
arg
=
pDispParams
->
rgvarg
+
1
;
ok
(
V_VT
(
arg
)
==
VT_DISPATCH
,
"VT = %d
\n
"
,
V_VT
(
arg
));
ok
(
V_DISPATCH
(
arg
)
!=
NULL
,
"V_DISPATCH = NULL
\n
"
);
url
=
get_window_url
(
V_DISPATCH
(
arg
));
test_url
(
url
);
SysFreeString
(
url
);
return
S_OK
;
case
DISPID_NAVIGATEERROR
:
CHECK_EXPECT
(
Invoke_NAVIGATEERROR
);
ok
(
!
called_Invoke_NAVIGATECOMPLETE2
,
"NAVIGATECOMPLETE2 called before NAVIGATEERROR
\n
"
);
arg
=
pDispParams
->
rgvarg
;
ok
(
V_VT
(
arg
)
==
(
VT_BYREF
|
VT_BOOL
),
"VT = %d
\n
"
,
V_VT
(
arg
));
ok
(
*
V_BOOLREF
(
arg
)
==
VARIANT_FALSE
,
"cancel = %#x
\n
"
,
*
V_BOOLREF
(
arg
));
arg
=
pDispParams
->
rgvarg
+
3
;
ok
(
V_VT
(
arg
)
==
(
VT_BYREF
|
VT_VARIANT
),
"VT = %d
\n
"
,
V_VT
(
arg
));
ok
(
V_VT
(
V_VARIANTREF
(
arg
))
==
VT_BSTR
,
"VT = %d
\n
"
,
V_VT
(
V_VARIANTREF
(
arg
)));
ok
(
!
wcscmp
(
V_BSTR
(
V_VARIANTREF
(
arg
)),
navigate_url
),
"url = %s
\n
"
,
wine_dbgstr_w
(
V_BSTR
(
V_VARIANTREF
(
arg
))));
return
S_OK
;
case
DISPID_DOCUMENTCOMPLETE
:
CHECK_EXPECT
(
Invoke_DOCUMENTCOMPLETE
);
navigate_complete
=
TRUE
;
arg
=
pDispParams
->
rgvarg
;
ok
(
V_VT
(
arg
)
==
(
VT_BYREF
|
VT_VARIANT
),
"VT = %d
\n
"
,
V_VT
(
arg
));
ok
(
V_VT
(
V_VARIANTREF
(
arg
))
==
VT_BSTR
,
"VT = %d
\n
"
,
V_VT
(
V_VARIANTREF
(
arg
)));
todo_wine_if
(
called_Invoke_NAVIGATEERROR
)
ok
(
!
wcscmp
(
V_BSTR
(
V_VARIANTREF
(
arg
)),
navigate_url
),
"url = %s
\n
"
,
wine_dbgstr_w
(
V_BSTR
(
V_VARIANTREF
(
arg
))));
arg
=
pDispParams
->
rgvarg
+
1
;
ok
(
V_VT
(
arg
)
==
VT_DISPATCH
,
"VT = %d
\n
"
,
V_VT
(
arg
));
ok
(
V_DISPATCH
(
arg
)
!=
NULL
,
"V_DISPATCH = NULL
\n
"
);
url
=
get_window_url
(
V_DISPATCH
(
arg
));
test_url
(
url
);
SysFreeString
(
url
);
return
S_OK
;
}
...
...
@@ -141,6 +258,7 @@ static void advise_cp(IUnknown *unk, BOOL init)
hres
=
IConnectionPointContainer_FindConnectionPoint
(
container
,
&
DIID_DWebBrowserEvents2
,
&
point
);
IConnectionPointContainer_Release
(
container
);
if
(
!
navigation_timed_out
)
ok
(
hres
==
S_OK
,
"FindConnectionPoint failed: %08lx
\n
"
,
hres
);
if
(
FAILED
(
hres
))
return
;
...
...
@@ -211,13 +329,31 @@ static void test_window(IWebBrowser2 *wb)
ok
(
!
strcmp
(
buf
,
"IEFrame"
),
"Unexpected class name %s
\n
"
,
buf
);
}
static
void
test_navigate
(
IWebBrowser2
*
wb
,
const
WCHAR
*
url
)
static
void
CALLBACK
navigate_timeout
(
HWND
hwnd
,
UINT
msg
,
UINT_PTR
timer
,
DWORD
time
)
{
win_skip
(
"Navigation timed out, skipping tests...
\n
"
);
called_Invoke_BEFORENAVIGATE2
=
TRUE
;
called_Invoke_NAVIGATECOMPLETE2
=
TRUE
;
called_Invoke_DOCUMENTCOMPLETE
=
TRUE
;
if
(
expect_Invoke_NAVIGATEERROR
)
CHECK_EXPECT
(
Invoke_NAVIGATEERROR
);
navigation_timed_out
=
TRUE
;
navigate_complete
=
TRUE
;
}
static
void
test_navigate
(
IWebBrowser2
*
wb
,
const
WCHAR
*
url
,
DWORD
timeout
)
{
VARIANT
urlv
,
emptyv
;
UINT_PTR
timer
=
0
;
MSG
msg
;
HRESULT
hres
;
SET_EXPECT
(
Invoke_BEFORENAVIGATE2
);
SET_EXPECT
(
Invoke_NAVIGATECOMPLETE2
);
SET_EXPECT
(
Invoke_DOCUMENTCOMPLETE
);
navigation_timed_out
=
FALSE
;
navigate_complete
=
FALSE
;
navigate_url
=
url
;
V_VT
(
&
urlv
)
=
VT_BSTR
;
V_BSTR
(
&
urlv
)
=
SysAllocString
(
url
);
...
...
@@ -226,12 +362,20 @@ static void test_navigate(IWebBrowser2 *wb, const WCHAR *url)
ok
(
hres
==
S_OK
,
"Navigate2 failed: %08lx
\n
"
,
hres
);
SysFreeString
(
V_BSTR
(
&
urlv
));
if
(
timeout
)
timer
=
SetTimer
(
NULL
,
0
,
timeout
,
navigate_timeout
);
while
(
!
navigate_complete
&&
GetMessageW
(
&
msg
,
NULL
,
0
,
0
))
{
TranslateMessage
(
&
msg
);
DispatchMessageW
(
&
msg
);
}
if
(
timer
)
KillTimer
(
NULL
,
timer
);
CHECK_CALLED
(
Invoke_BEFORENAVIGATE2
);
CHECK_CALLED
(
Invoke_NAVIGATECOMPLETE2
);
CHECK_CALLED
(
Invoke_DOCUMENTCOMPLETE
);
}
static
void
test_busy
(
IWebBrowser2
*
wb
)
...
...
@@ -272,7 +416,11 @@ static void test_InternetExplorer(void)
test_visible
(
wb
);
test_html_window
(
wb
);
test_window
(
wb
);
test_navigate
(
wb
,
L"http://test.winehq.org/tests/hello.html"
);
test_navigate
(
wb
,
L"http://test.winehq.org/tests/hello.html"
,
0
);
SET_EXPECT
(
Invoke_NAVIGATEERROR
);
test_navigate
(
wb
,
L"http://0.0.0.0:1234/#frag?query=foo&wine=bar"
,
6000
);
CHECK_CALLED
(
Invoke_NAVIGATEERROR
);
advise_cp
(
unk
,
FALSE
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment