urlmon: Don't allow direct sink callbacks when reporting data.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46213
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52286
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-01-06 19:30:37 +01:00 committed by Alexandre Julliard
parent 059848c5cd
commit 7c037c82c8
2 changed files with 70 additions and 30 deletions

View File

@ -915,34 +915,20 @@ static HRESULT WINAPI ProtocolSinkHandler_ReportProgress(IInternetProtocolSink *
return S_OK;
}
static HRESULT WINAPI ProtocolSinkHandler_ReportData(IInternetProtocolSink *iface,
DWORD bscf, ULONG progress, ULONG progress_max)
static HRESULT report_data(BindProtocol *This)
{
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
TRACE("(%p)->(%x %u %u)\n", This, bscf, progress, progress_max);
This->bscf = bscf;
This->progress = progress;
This->progress_max = progress_max;
if(!This->protocol_sink)
return S_OK;
DWORD bscf = This->bscf;
HRESULT hres;
if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) {
BYTE buf[BUFFER_SIZE];
DWORD read = 0;
LPWSTR mime;
HRESULT hres;
do {
read = 0;
if(is_apartment_thread(This))
This->continue_call++;
hres = IInternetProtocol_Read(This->protocol, buf,
sizeof(buf)-This->buf_size, &read);
if(is_apartment_thread(This))
This->continue_call--;
if(FAILED(hres) && hres != E_PENDING)
return hres;
@ -995,7 +981,34 @@ static HRESULT WINAPI ProtocolSinkHandler_ReportData(IInternetProtocolSink *ifac
if(!This->protocol_sink)
return S_OK;
return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max);
return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, This->progress, This->progress_max);
}
static HRESULT WINAPI ProtocolSinkHandler_ReportData(IInternetProtocolSink *iface,
DWORD bscf, ULONG progress, ULONG progress_max)
{
BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface);
HRESULT hres;
TRACE("(%p)->(%x %u %u)\n", This, bscf, progress, progress_max);
This->bscf = bscf;
This->progress = progress;
This->progress_max = progress_max;
if(!This->protocol_sink)
return S_OK;
if(is_apartment_thread(This))
This->continue_call++;
hres = report_data(This);
if(is_apartment_thread(This)) {
This->continue_call--;
process_tasks(This);
}
return hres;
}
static HRESULT handle_redirect(BindProtocol *This, const WCHAR *url)

View File

@ -161,7 +161,7 @@ static DWORD prot_read, filter_state, http_post_test, thread_id;
static BOOL security_problem, test_async_req, impl_protex;
static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort;
static BOOL empty_file, no_mime, bind_from_cache, file_with_hash, reuse_protocol_thread;
static BOOL no_aggregation;
static BOOL no_aggregation, result_from_lock;
enum {
STATE_CONNECTING,
@ -1168,6 +1168,16 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR
}
}
if(result_from_lock) {
SET_EXPECT(LockRequest);
hres = IInternetProtocol_LockRequest(binding_protocol, 0);
ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
CHECK_CALLED(LockRequest);
/* ReportResult is called before ReportData returns */
SET_EXPECT(ReportResult);
}
rec_depth--;
return S_OK;
}
@ -1911,6 +1921,12 @@ static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo
else
CHECK_CALLED(ReportData);
if(result_from_lock) {
/* set in ProtocolSink_ReportData */
CHECK_CALLED(ReportResult);
return;
}
if(tested_protocol == ITS_TEST) {
SET_EXPECT(ReportData);
hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
@ -2202,6 +2218,11 @@ static HRESULT WINAPI ProtocolEmul_LockRequest(IInternetProtocolEx *iface, DWORD
{
CHECK_EXPECT(LockRequest);
ok(dwOptions == 0, "dwOptions=%x\n", dwOptions);
if(result_from_lock) {
HRESULT hres;
hres = IInternetProtocolSink_ReportResult(binding_sink, S_OK, ERROR_SUCCESS, NULL);
ok(hres == S_OK, "ReportResult failed: %08x, expected E_FAIL\n", hres);
}
return S_OK;
}
@ -2688,6 +2709,7 @@ static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
#define TEST_NOMIME 0x2000
#define TEST_FROMCACHE 0x4000
#define TEST_DISABLEAUTOREDIRECT 0x8000
#define TEST_RESULTFROMLOCK 0x10000
static void register_filter(BOOL do_register)
{
@ -2744,6 +2766,7 @@ static void init_test(int prot, DWORD flags)
impl_protex = (flags & TEST_IMPLPROTEX) != 0;
empty_file = (flags & TEST_EMPTY) != 0;
bind_from_cache = (flags & TEST_FROMCACHE) != 0;
result_from_lock = (flags & TEST_RESULTFROMLOCK) != 0;
file_with_hash = FALSE;
security_problem = FALSE;
reuse_protocol_thread = FALSE;
@ -4131,16 +4154,18 @@ static void test_binding(int prot, DWORD grf_pi, DWORD test_flags)
CHECK_CALLED(ReportData); /* Set in ReportResult */
ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" );
}else {
if(mimefilter_test)
SET_EXPECT(MimeFilter_LockRequest);
else
SET_EXPECT(LockRequest);
hres = IInternetProtocol_LockRequest(protocol, 0);
ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
if(mimefilter_test)
CHECK_CALLED(MimeFilter_LockRequest);
else
CHECK_CALLED(LockRequest);
if(!result_from_lock) {
if(mimefilter_test)
SET_EXPECT(MimeFilter_LockRequest);
else
SET_EXPECT(LockRequest);
hres = IInternetProtocol_LockRequest(protocol, 0);
ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
if(mimefilter_test)
CHECK_CALLED(MimeFilter_LockRequest);
else
CHECK_CALLED(LockRequest);
}
if(mimefilter_test)
SET_EXPECT(MimeFilter_UnlockRequest);
@ -4284,7 +4309,7 @@ START_TEST(protocol)
test_CreateBinding();
no_aggregation = FALSE;
bindf &= ~BINDF_FROMURLMON;
bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_NOWRITECACHE | BINDF_PULLDATA;
trace("Testing file binding (mime verification, emulate prot)...\n");
test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT);
trace("Testing http binding (mime verification, emulate prot)...\n");
@ -4307,6 +4332,8 @@ START_TEST(protocol)
test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ);
trace("Testing http binding (mime verification, emulate prot, abort)...\n");
test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_ABORT);
trace("Testing its binding (mime verification, emulate prot, apartment thread)...\n");
test_binding(ITS_TEST, PI_MIMEVERIFICATION | PI_APARTMENTTHREADED, TEST_EMULATEPROT | TEST_RESULTFROMLOCK);
if(pCreateUri) {
trace("Testing file binding (use IUri, mime verification, emulate prot)...\n");
test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_USEIURI);