urlmon: Honor E_ABORT for URLDownloadToFile status callbacks.

This commit is contained in:
Thomas Mullaly 2011-05-01 00:30:17 -04:00 committed by Alexandre Julliard
parent e7ea2d3bb5
commit 5fac827fd7
2 changed files with 147 additions and 9 deletions

View File

@ -28,6 +28,7 @@ typedef struct {
LONG ref; LONG ref;
IBindStatusCallback *callback; IBindStatusCallback *callback;
IBinding *binding;
LPWSTR file_name; LPWSTR file_name;
LPWSTR cache_file; LPWSTR cache_file;
} DownloadBSC; } DownloadBSC;
@ -89,6 +90,8 @@ static ULONG WINAPI DownloadBSC_Release(IBindStatusCallback *iface)
if(!ref) { if(!ref) {
if(This->callback) if(This->callback)
IBindStatusCallback_Release(This->callback); IBindStatusCallback_Release(This->callback);
if(This->binding)
IBinding_Release(This->binding);
heap_free(This->file_name); heap_free(This->file_name);
heap_free(This->cache_file); heap_free(This->cache_file);
heap_free(This); heap_free(This);
@ -101,13 +104,19 @@ static HRESULT WINAPI DownloadBSC_OnStartBinding(IBindStatusCallback *iface,
DWORD dwReserved, IBinding *pbind) DWORD dwReserved, IBinding *pbind)
{ {
DownloadBSC *This = impl_from_IBindStatusCallback(iface); DownloadBSC *This = impl_from_IBindStatusCallback(iface);
HRESULT hres = S_OK;
TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind); TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
if(This->callback) if(This->callback) {
IBindStatusCallback_OnStartBinding(This->callback, dwReserved, pbind); hres = IBindStatusCallback_OnStartBinding(This->callback, dwReserved, pbind);
return S_OK; IBinding_AddRef(pbind);
This->binding = pbind;
}
/* Windows seems to ignore E_NOTIMPL if it's returned from the client. */
return hres == E_NOTIMPL ? S_OK : hres;
} }
static HRESULT WINAPI DownloadBSC_GetPriority(IBindStatusCallback *iface, LONG *pnPriority) static HRESULT WINAPI DownloadBSC_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
@ -132,6 +141,13 @@ static HRESULT on_progress(DownloadBSC *This, ULONG progress, ULONG progress_max
return S_OK; return S_OK;
hres = IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text); hres = IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text);
if(hres == E_ABORT) {
if(This->binding)
IBinding_Abort(This->binding);
else
FIXME("No binding, not sure what to do!\n");
}
return hres; return hres;
} }
@ -191,6 +207,11 @@ static HRESULT WINAPI DownloadBSC_OnStopBinding(IBindStatusCallback *iface,
if(This->callback) if(This->callback)
IBindStatusCallback_OnStopBinding(This->callback, hresult, szError); IBindStatusCallback_OnStopBinding(This->callback, hresult, szError);
if(This->binding) {
IBinding_Release(This->binding);
This->binding = NULL;
}
return S_OK; return S_OK;
} }
@ -311,6 +332,7 @@ static HRESULT DownloadBSC_Create(IBindStatusCallback *callback, LPCWSTR file_na
ret->ref = 1; ret->ref = 1;
ret->file_name = heap_strdupW(file_name); ret->file_name = heap_strdupW(file_name);
ret->cache_file = NULL; ret->cache_file = NULL;
ret->binding = NULL;
if(callback) if(callback)
IBindStatusCallback_AddRef(callback); IBindStatusCallback_AddRef(callback);

View File

@ -1631,8 +1631,11 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallbackEx *iface, ULONG u
if(emulate_protocol && (test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST)) if(emulate_protocol && (test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST))
SetEvent(complete_event); SetEvent(complete_event);
if(abort_progress) if(abort_progress) {
if(filedwl_api)
binding_hres = E_ABORT;
return E_ABORT; return E_ABORT;
}
break; break;
case BINDSTATUS_MIMETYPEAVAILABLE: case BINDSTATUS_MIMETYPEAVAILABLE:
@ -1789,11 +1792,14 @@ static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallbackEx *iface, HRES
if (hresult == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED)) if (hresult == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
return S_OK; return S_OK;
if(filedwl_api) if(filedwl_api) {
ok(SUCCEEDED(hresult), "binding failed: %08x\n", hresult); if(!abort_progress && !abort_start)
else if(invalid_cn_accepted) ok(SUCCEEDED(hresult), "binding failed: %08x\n", hresult);
ok(hresult == binding_hres, "binding failed: %08x, expected %08x\n", hresult, binding_hres); else if(abort_start && abort_hres == E_NOTIMPL)
else todo_wine ok(hresult == S_FALSE, "binding failed: %08x, expected S_FALSE\n", hresult);
else
ok(hresult == E_ABORT, "binding failed: %08x, expected E_ABORT\n", hresult);
} else
ok(hresult == binding_hres, "binding failed: %08x, expected %08x\n", hresult, binding_hres); ok(hresult == binding_hres, "binding failed: %08x, expected %08x\n", hresult, binding_hres);
ok(szError == NULL, "szError should be NULL\n"); ok(szError == NULL, "szError should be NULL\n");
@ -3328,6 +3334,113 @@ static void test_URLDownloadToFile(DWORD prot, BOOL emul)
ok(res, "DeleteFile failed: %u\n", GetLastError()); ok(res, "DeleteFile failed: %u\n", GetLastError());
} }
static void test_URLDownloadToFile_abort(void)
{
HRESULT hres;
init_bind_test(HTTP_TEST, BINDTEST_FILEDWLAPI|BINDTEST_ABORT_PROGRESS, TYMED_FILE);
SET_EXPECT(GetBindInfo);
SET_EXPECT(QueryInterface_IInternetProtocol);
SET_EXPECT(QueryInterface_IServiceProvider);
SET_EXPECT(QueryService_IInternetProtocol);
SET_EXPECT(OnStartBinding);
SET_EXPECT(QueryInterface_IHttpNegotiate);
SET_EXPECT(QueryInterface_IHttpNegotiate2);
SET_EXPECT(BeginningTransaction);
SET_EXPECT(GetRootSecurityId);
SET_EXPECT(QueryInterface_IWindowForBindingUI);
SET_EXPECT(OnProgress_CONNECTING);
SET_EXPECT(OnProgress_SENDINGREQUEST);
SET_EXPECT(OnStopBinding);
hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc);
ok(hres == E_ABORT, "URLDownloadToFile failed: %08x, expected E_ABORT\n", hres);
CHECK_CALLED(GetBindInfo);
CHECK_CALLED(QueryInterface_IInternetProtocol);
CHECK_CALLED(QueryInterface_IServiceProvider);
CHECK_CALLED(QueryService_IInternetProtocol);
CHECK_CALLED(OnStartBinding);
CHECK_CALLED(QueryInterface_IHttpNegotiate);
CHECK_CALLED(QueryInterface_IHttpNegotiate2);
CHECK_CALLED(BeginningTransaction);
CHECK_CALLED(GetRootSecurityId);
CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
CHECK_CALLED(OnProgress_SENDINGREQUEST);
CLEAR_CALLED(OnProgress_CONNECTING);
CHECK_CALLED(OnStopBinding);
init_bind_test(HTTP_TEST, BINDTEST_FILEDWLAPI|BINDTEST_ABORT_START, TYMED_FILE);
SET_EXPECT(GetBindInfo);
SET_EXPECT(QueryInterface_IInternetProtocol);
SET_EXPECT(QueryInterface_IServiceProvider);
SET_EXPECT(QueryService_IInternetProtocol);
SET_EXPECT(OnStartBinding);
SET_EXPECT(OnStopBinding);
abort_hres = E_ABORT;
hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc);
ok(hres == E_ABORT, "URLDownloadToFile failed: %08x, expected E_ABORT\n", hres);
CHECK_CALLED(GetBindInfo);
todo_wine CHECK_CALLED(QueryInterface_IInternetProtocol);
todo_wine CHECK_CALLED(QueryInterface_IServiceProvider);
todo_wine CHECK_CALLED(QueryService_IInternetProtocol);
CHECK_CALLED(OnStartBinding);
CHECK_CALLED(OnStopBinding);
init_bind_test(HTTP_TEST, BINDTEST_FILEDWLAPI|BINDTEST_ABORT_START, TYMED_FILE);
SET_EXPECT(GetBindInfo);
SET_EXPECT(QueryInterface_IInternetProtocol);
SET_EXPECT(QueryInterface_IServiceProvider);
SET_EXPECT(QueryService_IInternetProtocol);
SET_EXPECT(OnStartBinding);
SET_EXPECT(QueryInterface_IHttpNegotiate);
SET_EXPECT(QueryInterface_IHttpNegotiate2);
SET_EXPECT(BeginningTransaction);
SET_EXPECT(GetRootSecurityId);
SET_EXPECT(QueryInterface_IWindowForBindingUI);
SET_EXPECT(OnResponse);
SET_EXPECT(OnProgress_CONNECTING);
SET_EXPECT(OnProgress_SENDINGREQUEST);
SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
SET_EXPECT(OnProgress_DOWNLOADINGDATA);
SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
SET_EXPECT(OnStopBinding);
/* URLDownloadToFile doesn't abort if E_NOTIMPL is returned from the
* IBindStatusCallback's OnStartBinding function.
*/
abort_hres = E_NOTIMPL;
hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc);
ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres);
CHECK_CALLED(GetBindInfo);
CHECK_CALLED(QueryInterface_IInternetProtocol);
CHECK_CALLED(QueryInterface_IServiceProvider);
CHECK_CALLED(QueryService_IInternetProtocol);
CHECK_CALLED(OnStartBinding);
CHECK_CALLED(QueryInterface_IHttpNegotiate);
CHECK_CALLED(QueryInterface_IHttpNegotiate2);
CHECK_CALLED(BeginningTransaction);
CHECK_CALLED(GetRootSecurityId);
CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
CHECK_CALLED(OnResponse);
CLEAR_CALLED(OnProgress_CONNECTING);
CHECK_CALLED(OnProgress_SENDINGREQUEST);
CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
CHECK_CALLED(OnStopBinding);
DeleteFileA(dwl_htmlA);
}
static void set_file_url(char *path) static void set_file_url(char *path)
{ {
CHAR file_urlA[INTERNET_MAX_URL_LENGTH]; CHAR file_urlA[INTERNET_MAX_URL_LENGTH];
@ -3728,6 +3841,9 @@ START_TEST(url)
trace("test URLDownloadToFile for http protocol...\n"); trace("test URLDownloadToFile for http protocol...\n");
test_URLDownloadToFile(HTTP_TEST, FALSE); test_URLDownloadToFile(HTTP_TEST, FALSE);
trace("test URLDownloadToFile abort...\n");
test_URLDownloadToFile_abort();
trace("test emulated http abort...\n"); trace("test emulated http abort...\n");
test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_ABORT, TYMED_ISTREAM); test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_ABORT, TYMED_ISTREAM);