Module: wine Branch: master Commit: 5fac827fd7b177a23639e986efae0e96f44aa2b7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5fac827fd7b177a23639e986ef...
Author: Thomas Mullaly tmullaly@codeweavers.com Date: Sun May 1 00:30:17 2011 -0400
urlmon: Honor E_ABORT for URLDownloadToFile status callbacks.
---
dlls/urlmon/download.c | 28 +++++++++- dlls/urlmon/tests/url.c | 128 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 147 insertions(+), 9 deletions(-)
diff --git a/dlls/urlmon/download.c b/dlls/urlmon/download.c index 9759e71..c20c87c 100644 --- a/dlls/urlmon/download.c +++ b/dlls/urlmon/download.c @@ -28,6 +28,7 @@ typedef struct { LONG ref;
IBindStatusCallback *callback; + IBinding *binding; LPWSTR file_name; LPWSTR cache_file; } DownloadBSC; @@ -89,6 +90,8 @@ static ULONG WINAPI DownloadBSC_Release(IBindStatusCallback *iface) if(!ref) { if(This->callback) IBindStatusCallback_Release(This->callback); + if(This->binding) + IBinding_Release(This->binding); heap_free(This->file_name); heap_free(This->cache_file); heap_free(This); @@ -101,13 +104,19 @@ static HRESULT WINAPI DownloadBSC_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved, IBinding *pbind) { DownloadBSC *This = impl_from_IBindStatusCallback(iface); + HRESULT hres = S_OK;
TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
- if(This->callback) - IBindStatusCallback_OnStartBinding(This->callback, dwReserved, pbind); + if(This->callback) { + 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) @@ -132,6 +141,13 @@ static HRESULT on_progress(DownloadBSC *This, ULONG progress, ULONG progress_max return S_OK;
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; }
@@ -191,6 +207,11 @@ static HRESULT WINAPI DownloadBSC_OnStopBinding(IBindStatusCallback *iface, if(This->callback) IBindStatusCallback_OnStopBinding(This->callback, hresult, szError);
+ if(This->binding) { + IBinding_Release(This->binding); + This->binding = NULL; + } + return S_OK; }
@@ -311,6 +332,7 @@ static HRESULT DownloadBSC_Create(IBindStatusCallback *callback, LPCWSTR file_na ret->ref = 1; ret->file_name = heap_strdupW(file_name); ret->cache_file = NULL; + ret->binding = NULL;
if(callback) IBindStatusCallback_AddRef(callback); diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c index 0b57312..eb4d316 100644 --- a/dlls/urlmon/tests/url.c +++ b/dlls/urlmon/tests/url.c @@ -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)) SetEvent(complete_event);
- if(abort_progress) + if(abort_progress) { + if(filedwl_api) + binding_hres = E_ABORT; return E_ABORT; + }
break; 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)) return S_OK;
- if(filedwl_api) - ok(SUCCEEDED(hresult), "binding failed: %08x\n", hresult); - else if(invalid_cn_accepted) - ok(hresult == binding_hres, "binding failed: %08x, expected %08x\n", hresult, binding_hres); - else + if(filedwl_api) { + if(!abort_progress && !abort_start) + ok(SUCCEEDED(hresult), "binding failed: %08x\n", hresult); + else if(abort_start && abort_hres == E_NOTIMPL) + 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(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()); }
+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) { CHAR file_urlA[INTERNET_MAX_URL_LENGTH]; @@ -3728,6 +3841,9 @@ START_TEST(url) trace("test URLDownloadToFile for http protocol...\n"); test_URLDownloadToFile(HTTP_TEST, FALSE);
+ trace("test URLDownloadToFile abort...\n"); + test_URLDownloadToFile_abort(); + trace("test emulated http abort...\n"); test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_ABORT, TYMED_ISTREAM);