Thomas Mullaly : urlmon: Honor E_ABORT for URLDownloadToFile status callbacks.
Alexandre Julliard
julliard at winehq.org
Thu May 12 13:57:47 CDT 2011
Module: wine
Branch: master
Commit: 5fac827fd7b177a23639e986efae0e96f44aa2b7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5fac827fd7b177a23639e986efae0e96f44aa2b7
Author: Thomas Mullaly <tmullaly at 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);
More information about the wine-cvs
mailing list