Commit 4985ca0e authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

urlmon: Abstract ProtocolStream object.

parent 6b854ff4
...@@ -50,15 +50,19 @@ typedef struct { ...@@ -50,15 +50,19 @@ typedef struct {
HRESULT hres; HRESULT hres;
} stgmed_buf_t; } stgmed_buf_t;
#define STGMEDUNK(x) ((IUnknown*) &(x)->lpUnknownVtbl) typedef struct _stgmed_obj_t stgmed_obj_t;
typedef struct { 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; #define STGMEDUNK(x) ((IUnknown*) &(x)->lpUnknownVtbl)
} ProtocolStream;
typedef enum { typedef enum {
BEFORE_DOWNLOAD, BEFORE_DOWNLOAD,
...@@ -83,7 +87,7 @@ struct Binding { ...@@ -83,7 +87,7 @@ struct Binding {
IServiceProvider *service_provider; IServiceProvider *service_provider;
stgmed_buf_t *stgmed_buf; stgmed_buf_t *stgmed_buf;
ProtocolStream *stream; stgmed_obj_t *stgmed_obj;
BINDINFO bindinfo; BINDINFO bindinfo;
DWORD bindf; DWORD bindf;
...@@ -104,8 +108,6 @@ struct Binding { ...@@ -104,8 +108,6 @@ struct Binding {
DWORD apartment_thread; DWORD apartment_thread;
HWND notif_hwnd; HWND notif_hwnd;
STGMEDIUM stgmed;
task_header_t *task_queue_head, *task_queue_tail; task_header_t *task_queue_head, *task_queue_tail;
CRITICAL_SECTION section; CRITICAL_SECTION section;
}; };
...@@ -527,6 +529,33 @@ static const IUnknownVtbl StgMedUnkVtbl = { ...@@ -527,6 +529,33 @@ static const IUnknownVtbl StgMedUnkVtbl = {
StgMedUnk_Release 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) #define STREAM_THIS(iface) DEFINE_THIS(ProtocolStream, Stream, iface)
static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface, static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface,
...@@ -724,30 +753,42 @@ static const IStreamVtbl ProtocolStreamVtbl = { ...@@ -724,30 +753,42 @@ static const IStreamVtbl ProtocolStreamVtbl = {
ProtocolStream_Clone 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; stgmed->tymed = TYMED_ISTREAM;
ret->ref = 1; stgmed->u.pstm = STREAM(stream);
ret->size = 0; stgmed->pUnkForRelease = STGMEDUNK(stream->buf);
ret->init = FALSE;
ret->hres = S_OK;
IInternetProtocol_AddRef(protocol); return S_OK;
ret->protocol = protocol; }
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)); ProtocolStream *ret = heap_alloc(sizeof(ProtocolStream));
ret->stgmed_obj.vtbl = &stgmed_stream_vtbl;
ret->lpStreamVtbl = &ProtocolStreamVtbl; ret->lpStreamVtbl = &ProtocolStreamVtbl;
ret->ref = 1; ret->ref = 1;
...@@ -756,9 +797,11 @@ static ProtocolStream *create_stream(stgmed_buf_t *buf) ...@@ -756,9 +797,11 @@ static ProtocolStream *create_stream(stgmed_buf_t *buf)
URLMON_LockModule(); 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) static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void **ppv)
{ {
Binding *This = BINDING_THIS(iface); Binding *This = BINDING_THIS(iface);
...@@ -821,8 +864,8 @@ static ULONG WINAPI Binding_Release(IBinding *iface) ...@@ -821,8 +864,8 @@ static ULONG WINAPI Binding_Release(IBinding *iface)
IServiceProvider_Release(This->service_provider); IServiceProvider_Release(This->service_provider);
if(This->stgmed_buf) if(This->stgmed_buf)
IUnknown_Release(STGMEDUNK(This->stgmed_buf)); IUnknown_Release(STGMEDUNK(This->stgmed_buf));
if(This->stream) if(This->stgmed_obj)
IStream_Release(STREAM(This->stream)); This->stgmed_obj->vtbl->release(This->stgmed_obj);
if(This->obj) if(This->obj)
IUnknown_Release(This->obj); IUnknown_Release(This->obj);
if(This->bctx) if(This->bctx)
...@@ -1106,6 +1149,8 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres ...@@ -1106,6 +1149,8 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
if(!(This->state & BINDING_OBJAVAIL)) if(!(This->state & BINDING_OBJAVAIL))
create_object(This); create_object(This);
}else { }else {
STGMEDIUM stgmed;
if(!(This->state & BINDING_LOCKED)) { if(!(This->state & BINDING_LOCKED)) {
HRESULT hres = IInternetProtocol_LockRequest(This->protocol, 0); HRESULT hres = IInternetProtocol_LockRequest(This->protocol, 0);
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
...@@ -1113,8 +1158,10 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres ...@@ -1113,8 +1158,10 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
} }
formatetc.cfFormat = This->clipboard_format; formatetc.cfFormat = This->clipboard_format;
This->stgmed_obj->vtbl->fill_stgmed(This->stgmed_obj, &stgmed);
IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress, IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress,
&formatetc, &This->stgmed); &formatetc, &stgmed);
if(This->download_state == END_DOWNLOAD) if(This->download_state == END_DOWNLOAD)
stop_binding(This, S_OK, NULL); stop_binding(This, S_OK, NULL);
...@@ -1493,16 +1540,12 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, ...@@ -1493,16 +1540,12 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url,
if(binding_ctx) { if(binding_ctx) {
ret->stgmed_buf = binding_ctx->stgmed_buf; ret->stgmed_buf = binding_ctx->stgmed_buf;
IUnknown_AddRef(STGMEDUNK(ret->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; ret->clipboard_format = binding_ctx->clipboard_format;
}else { }else {
ret->stgmed_buf = create_stgmed_buf(ret->protocol); 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_obj = create_stgmed_stream(ret->stgmed_buf);
ret->stgmed.pUnkForRelease = (IUnknown*)BINDING(ret); /* NOTE: Windows uses other IUnknown */
*binding = ret; *binding = ret;
return S_OK; return S_OK;
...@@ -1576,9 +1619,7 @@ HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv) ...@@ -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)) if((binding->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED))
IInternetProtocol_UnlockRequest(binding->protocol); IInternetProtocol_UnlockRequest(binding->protocol);
*ppv = binding->stgmed.u.pstm; *ppv = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj);
IStream_AddRef(binding->stgmed.u.pstm);
hres = S_OK; hres = S_OK;
}else { }else {
hres = MK_S_ASYNCHRONOUS; hres = MK_S_ASYNCHRONOUS;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment