Module: wine Branch: master Commit: 4985ca0e1c57ddd7c42a80fd3b3e2215fa89ed4b URL: http://source.winehq.org/git/wine.git/?a=commit;h=4985ca0e1c57ddd7c42a80fd3b...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Jan 31 18:15:53 2008 +0100
urlmon: Abstract ProtocolStream object.
---
dlls/urlmon/binding.c | 109 +++++++++++++++++++++++++++++++++--------------- 1 files changed, 75 insertions(+), 34 deletions(-)
diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index 48f537b..b574c96 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -50,15 +50,19 @@ typedef struct { HRESULT hres; } stgmed_buf_t;
-#define STGMEDUNK(x) ((IUnknown*) &(x)->lpUnknownVtbl) +typedef struct _stgmed_obj_t stgmed_obj_t;
typedef struct { - const IStreamVtbl *lpStreamVtbl; + void (*release)(stgmed_obj_t*); + HRESULT (*fill_stgmed)(stgmed_obj_t*,STGMEDIUM*); + void *(*get_result)(stgmed_obj_t*); +} stgmed_obj_vtbl;
- LONG ref; +struct _stgmed_obj_t { + const stgmed_obj_vtbl *vtbl; +};
- stgmed_buf_t *buf; -} ProtocolStream; +#define STGMEDUNK(x) ((IUnknown*) &(x)->lpUnknownVtbl)
typedef enum { BEFORE_DOWNLOAD, @@ -83,7 +87,7 @@ struct Binding { IServiceProvider *service_provider;
stgmed_buf_t *stgmed_buf; - ProtocolStream *stream; + stgmed_obj_t *stgmed_obj;
BINDINFO bindinfo; DWORD bindf; @@ -104,8 +108,6 @@ struct Binding { DWORD apartment_thread; HWND notif_hwnd;
- STGMEDIUM stgmed; - task_header_t *task_queue_head, *task_queue_tail; CRITICAL_SECTION section; }; @@ -527,6 +529,33 @@ static const IUnknownVtbl StgMedUnkVtbl = { StgMedUnk_Release };
+static stgmed_buf_t *create_stgmed_buf(IInternetProtocol *protocol) +{ + stgmed_buf_t *ret = heap_alloc(sizeof(*ret)); + + ret->lpUnknownVtbl = &StgMedUnkVtbl; + ret->ref = 1; + ret->size = 0; + ret->init = FALSE; + ret->hres = S_OK; + + IInternetProtocol_AddRef(protocol); + ret->protocol = protocol; + + URLMON_LockModule(); + + return ret; +} + +typedef struct { + stgmed_obj_t stgmed_obj; + const IStreamVtbl *lpStreamVtbl; + + LONG ref; + + stgmed_buf_t *buf; +} ProtocolStream; + #define STREAM_THIS(iface) DEFINE_THIS(ProtocolStream, Stream, iface)
static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface, @@ -724,30 +753,42 @@ static const IStreamVtbl ProtocolStreamVtbl = { ProtocolStream_Clone };
-#define BINDING_THIS(iface) DEFINE_THIS(Binding, Binding, iface) +static void stgmed_stream_release(stgmed_obj_t *obj) +{ + ProtocolStream *stream = (ProtocolStream*)obj; + IStream_Release(STREAM(stream)); +}
-static stgmed_buf_t *create_stgmed_buf(IInternetProtocol *protocol) +static HRESULT stgmed_stream_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) { - stgmed_buf_t *ret = heap_alloc(sizeof(*ret)); + ProtocolStream *stream = (ProtocolStream*)obj;
- ret->lpUnknownVtbl = &StgMedUnkVtbl; - ret->ref = 1; - ret->size = 0; - ret->init = FALSE; - ret->hres = S_OK; + stgmed->tymed = TYMED_ISTREAM; + stgmed->u.pstm = STREAM(stream); + stgmed->pUnkForRelease = STGMEDUNK(stream->buf);
- IInternetProtocol_AddRef(protocol); - ret->protocol = protocol; + return S_OK; +}
- URLMON_LockModule(); +static void *stgmed_stream_get_result(stgmed_obj_t *obj) +{ + ProtocolStream *stream = (ProtocolStream*)obj;
- return ret; + IStream_AddRef(STREAM(stream)); + return STREAM(stream); }
-static ProtocolStream *create_stream(stgmed_buf_t *buf) +static const stgmed_obj_vtbl stgmed_stream_vtbl = { + stgmed_stream_release, + stgmed_stream_fill_stgmed, + stgmed_stream_get_result +}; + +static stgmed_obj_t *create_stgmed_stream(stgmed_buf_t *buf) { ProtocolStream *ret = heap_alloc(sizeof(ProtocolStream));
+ ret->stgmed_obj.vtbl = &stgmed_stream_vtbl; ret->lpStreamVtbl = &ProtocolStreamVtbl; ret->ref = 1;
@@ -756,9 +797,11 @@ static ProtocolStream *create_stream(stgmed_buf_t *buf)
URLMON_LockModule();
- return ret; + return &ret->stgmed_obj; }
+#define BINDING_THIS(iface) DEFINE_THIS(Binding, Binding, iface) + static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void **ppv) { Binding *This = BINDING_THIS(iface); @@ -821,8 +864,8 @@ static ULONG WINAPI Binding_Release(IBinding *iface) IServiceProvider_Release(This->service_provider); if(This->stgmed_buf) IUnknown_Release(STGMEDUNK(This->stgmed_buf)); - if(This->stream) - IStream_Release(STREAM(This->stream)); + if(This->stgmed_obj) + This->stgmed_obj->vtbl->release(This->stgmed_obj); if(This->obj) IUnknown_Release(This->obj); if(This->bctx) @@ -1106,6 +1149,8 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres if(!(This->state & BINDING_OBJAVAIL)) create_object(This); }else { + STGMEDIUM stgmed; + if(!(This->state & BINDING_LOCKED)) { HRESULT hres = IInternetProtocol_LockRequest(This->protocol, 0); if(SUCCEEDED(hres)) @@ -1113,8 +1158,10 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres }
formatetc.cfFormat = This->clipboard_format; + This->stgmed_obj->vtbl->fill_stgmed(This->stgmed_obj, &stgmed); + IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress, - &formatetc, &This->stgmed); + &formatetc, &stgmed);
if(This->download_state == END_DOWNLOAD) stop_binding(This, S_OK, NULL); @@ -1493,16 +1540,12 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, if(binding_ctx) { ret->stgmed_buf = binding_ctx->stgmed_buf; IUnknown_AddRef(STGMEDUNK(ret->stgmed_buf)); - ret->stream = binding_ctx->stream; - IStream_AddRef(STREAM(binding_ctx->stream)); ret->clipboard_format = binding_ctx->clipboard_format; }else { ret->stgmed_buf = create_stgmed_buf(ret->protocol); - ret->stream = create_stream(ret->stgmed_buf); } - ret->stgmed.tymed = TYMED_ISTREAM; - ret->stgmed.u.pstm = STREAM((ProtocolStream*)ret->stream); - ret->stgmed.pUnkForRelease = (IUnknown*)BINDING(ret); /* NOTE: Windows uses other IUnknown */ + + ret->stgmed_obj = create_stgmed_stream(ret->stgmed_buf);
*binding = ret; return S_OK; @@ -1576,9 +1619,7 @@ HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv) if((binding->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED)) IInternetProtocol_UnlockRequest(binding->protocol);
- *ppv = binding->stgmed.u.pstm; - IStream_AddRef(binding->stgmed.u.pstm); - + *ppv = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj); hres = S_OK; }else { hres = MK_S_ASYNCHRONOUS;