Author: winesync Date: Fri Apr 4 09:41:46 2008 New Revision: 32859
URL: http://svn.reactos.org/svn/reactos?rev=32859&view=rev Log: Autosyncing with Wine HEAD
Added: trunk/reactos/dll/win32/urlmon/download.c (with props) Modified: trunk/reactos/dll/win32/urlmon/binding.c trunk/reactos/dll/win32/urlmon/file.c trunk/reactos/dll/win32/urlmon/http.c trunk/reactos/dll/win32/urlmon/mk.c trunk/reactos/dll/win32/urlmon/regsvr.c trunk/reactos/dll/win32/urlmon/sec_mgr.c trunk/reactos/dll/win32/urlmon/session.c trunk/reactos/dll/win32/urlmon/umon.c trunk/reactos/dll/win32/urlmon/umstream.c trunk/reactos/dll/win32/urlmon/urlmon.rbuild trunk/reactos/dll/win32/urlmon/urlmon.spec trunk/reactos/dll/win32/urlmon/urlmon_main.c trunk/reactos/dll/win32/urlmon/urlmon_main.h
Modified: trunk/reactos/dll/win32/urlmon/binding.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/binding.c?... ============================================================================== --- trunk/reactos/dll/win32/urlmon/binding.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/binding.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -38,17 +38,33 @@ } task_header_t;
typedef struct { - const IStreamVtbl *lpStreamVtbl; + const IUnknownVtbl *lpUnknownVtbl;
LONG ref;
IInternetProtocol *protocol;
BYTE buf[1024*8]; - DWORD buf_size; - BOOL init_buf; + DWORD size; + BOOL init; HRESULT hres; -} ProtocolStream; + + LPWSTR cache_file; +} stgmed_buf_t; + +typedef struct _stgmed_obj_t stgmed_obj_t; + +typedef struct { + void (*release)(stgmed_obj_t*); + HRESULT (*fill_stgmed)(stgmed_obj_t*,STGMEDIUM*); + void *(*get_result)(stgmed_obj_t*); +} stgmed_obj_vtbl; + +struct _stgmed_obj_t { + const stgmed_obj_vtbl *vtbl; +}; + +#define STGMEDUNK(x) ((IUnknown*) &(x)->lpUnknownVtbl)
typedef enum { BEFORE_DOWNLOAD, @@ -71,7 +87,9 @@ IBindStatusCallback *callback; IInternetProtocol *protocol; IServiceProvider *service_provider; - ProtocolStream *stream; + + stgmed_buf_t *stgmed_buf; + stgmed_obj_t *stgmed_obj;
BINDINFO bindinfo; DWORD bindf; @@ -92,8 +110,6 @@ DWORD apartment_thread; HWND notif_hwnd;
- STGMEDIUM stgmed; - task_header_t *task_queue_head, *task_queue_tail; CRITICAL_SECTION section; }; @@ -143,18 +159,18 @@ return ret; }
-static void fill_stream_buffer(ProtocolStream *This) +static void fill_stgmed_buffer(stgmed_buf_t *buf) { DWORD read = 0;
- if(sizeof(This->buf) == This->buf_size) + if(sizeof(buf->buf) == buf->size) return;
- This->hres = IInternetProtocol_Read(This->protocol, This->buf+This->buf_size, - sizeof(This->buf)-This->buf_size, &read); - This->buf_size += read; + buf->hres = IInternetProtocol_Read(buf->protocol, buf->buf+buf->size, + sizeof(buf->buf)-buf->size, &read); + buf->size += read; if(read > 0) - This->init_buf = TRUE; + buf->init = TRUE; }
static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -281,9 +297,9 @@ if(verify) { LPWSTR mime = NULL;
- fill_stream_buffer(binding->stream); - FindMimeFromData(NULL, binding->url, binding->stream->buf, - min(binding->stream->buf_size, 255), binding->mime, 0, &mime, 0); + fill_stgmed_buffer(binding->stgmed_buf); + FindMimeFromData(NULL, binding->url, binding->stgmed_buf->buf, + min(binding->stgmed_buf->size, 255), binding->mime, 0, &mime, 0);
heap_free(binding->mime); binding->mime = heap_strdupW(mime); @@ -404,31 +420,17 @@ FIXME("Load failed: %08x\n", hres); }
-static void create_object(Binding *binding) +static HRESULT create_mime_object(Binding *binding, const CLSID *clsid, LPCWSTR clsid_str) { IPersistMoniker *persist; - LPWSTR clsid_str; - CLSID clsid; HRESULT hres;
- if(!binding->mime) { - FIXME("MIME unavailable\n"); - return; - } - - if(!(clsid_str = get_mime_clsid(binding->mime, &clsid))) { - FIXME("Could not find object for MIME %s\n", debugstr_w(binding->mime)); - return; - } - - IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_CLASSIDAVAILABLE, clsid_str); - - IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_BEGINSYNCOPERATION, NULL); - - hres = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &binding->iid, (void**)&binding->obj); - if(FAILED(hres)) - FIXME("CoCreateInstance failed: %08x\n", hres); + if(FAILED(hres)) { + WARN("CoCreateInstance failed: %08x\n", hres); + return INET_E_CANNOT_INSTANTIATE_OBJECT; + }
binding->state |= BINDING_OBJAVAIL;
@@ -451,14 +453,123 @@ /* FIXME: Try query IPersistFile */ }
+ IBindStatusCallback_OnObjectAvailable(binding->callback, &binding->iid, binding->obj); + + return S_OK; +} + +static void create_object(Binding *binding) +{ + LPWSTR clsid_str; + CLSID clsid; + HRESULT hres; + + if(!binding->mime) { + FIXME("MIME not available\n"); + return; + } + + if(!(clsid_str = get_mime_clsid(binding->mime, &clsid))) { + FIXME("Could not find object for MIME %s\n", debugstr_w(binding->mime)); + return; + } + + IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_CLASSIDAVAILABLE, clsid_str); + IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_BEGINSYNCOPERATION, NULL); + + hres = create_mime_object(binding, &clsid, clsid_str); heap_free(clsid_str);
- IBindStatusCallback_OnObjectAvailable(binding->callback, &binding->iid, binding->obj); - IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_ENDSYNCOPERATION, NULL);
- stop_binding(binding, S_OK, NULL); -} + stop_binding(binding, hres, NULL); + if(FAILED(hres)) + IInternetProtocol_Terminate(binding->protocol, 0); +} + +#define STGMEDUNK_THIS(iface) DEFINE_THIS(stgmed_buf_t, Unknown, iface) + +static HRESULT WINAPI StgMedUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + stgmed_buf_t *This = STGMEDUNK_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(riid, &IID_IUnknown)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + + *ppv = STGMEDUNK(This); + IUnknown_AddRef(STGMEDUNK(This)); + return S_OK; + } + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI StgMedUnk_AddRef(IUnknown *iface) +{ + stgmed_buf_t *This = STGMEDUNK_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI StgMedUnk_Release(IUnknown *iface) +{ + stgmed_buf_t *This = STGMEDUNK_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + IInternetProtocol_Release(This->protocol); + heap_free(This->cache_file); + heap_free(This); + + URLMON_UnlockModule(); + } + + return ref; +} + +#undef STGMEDUNK_THIS + +static const IUnknownVtbl StgMedUnkVtbl = { + StgMedUnk_QueryInterface, + StgMedUnk_AddRef, + 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; + ret->cache_file = NULL; + + 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)
@@ -507,7 +618,7 @@ TRACE("(%p) ref=%d\n", This, ref);
if(!ref) { - IInternetProtocol_Release(This->protocol); + IUnknown_Release(STGMEDUNK(This->buf)); heap_free(This);
URLMON_UnlockModule(); @@ -517,24 +628,25 @@ }
static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv, - ULONG cb, ULONG *pcbRead) + ULONG cb, ULONG *pcbRead) { ProtocolStream *This = STREAM_THIS(iface); DWORD read = 0, pread = 0; + HRESULT hres;
TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbRead);
- if(This->buf_size) { + if(This->buf->size) { read = cb;
- if(read > This->buf_size) - read = This->buf_size; - - memcpy(pv, This->buf, read); - - if(read < This->buf_size) - memmove(This->buf, This->buf+read, This->buf_size-read); - This->buf_size -= read; + if(read > This->buf->size) + read = This->buf->size; + + memcpy(pv, This->buf->buf, read); + + if(read < This->buf->size) + memmove(This->buf->buf, This->buf->buf+read, This->buf->size-read); + This->buf->size -= read; }
if(read == cb) { @@ -543,14 +655,14 @@ return S_OK; }
- This->hres = IInternetProtocol_Read(This->protocol, (PBYTE)pv+read, cb-read, &pread); + hres = This->buf->hres = IInternetProtocol_Read(This->buf->protocol, (PBYTE)pv+read, cb-read, &pread); if (pcbRead) *pcbRead = read + pread;
- if(This->hres == E_PENDING) + if(hres == E_PENDING) return E_PENDING; - else if(FAILED(This->hres)) - FIXME("Read failed: %08x\n", This->hres); + else if(FAILED(hres)) + FIXME("Read failed: %08x\n", hres);
return read || pread ? S_OK : S_FALSE; } @@ -656,25 +768,117 @@ ProtocolStream_Clone };
-#define BINDING_THIS(iface) DEFINE_THIS(Binding, Binding, iface) - -static ProtocolStream *create_stream(IInternetProtocol *protocol) +static void stgmed_stream_release(stgmed_obj_t *obj) +{ + ProtocolStream *stream = (ProtocolStream*)obj; + IStream_Release(STREAM(stream)); +} + +static HRESULT stgmed_stream_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) +{ + ProtocolStream *stream = (ProtocolStream*)obj; + + stgmed->tymed = TYMED_ISTREAM; + stgmed->u.pstm = STREAM(stream); + stgmed->pUnkForRelease = STGMEDUNK(stream->buf); + + return S_OK; +} + +static void *stgmed_stream_get_result(stgmed_obj_t *obj) +{ + ProtocolStream *stream = (ProtocolStream*)obj; + + IStream_AddRef(STREAM(stream)); + return STREAM(stream); +} + +static const stgmed_obj_vtbl stgmed_stream_vtbl = { + stgmed_stream_release, + stgmed_stream_fill_stgmed, + stgmed_stream_get_result +}; + +typedef struct { + stgmed_obj_t stgmed_obj; + stgmed_buf_t *buf; +} stgmed_file_obj_t; + +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; - ret->buf_size = 0; - ret->init_buf = FALSE; - ret->hres = S_OK; - - IInternetProtocol_AddRef(protocol); - ret->protocol = protocol; + + IUnknown_AddRef(STGMEDUNK(buf)); + ret->buf = buf;
URLMON_LockModule();
- return ret; -} + return &ret->stgmed_obj; +} + +static void stgmed_file_release(stgmed_obj_t *obj) +{ + stgmed_file_obj_t *file_obj = (stgmed_file_obj_t*)obj; + + IUnknown_Release(STGMEDUNK(file_obj->buf)); + heap_free(file_obj); +} + +static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed) +{ + stgmed_file_obj_t *file_obj = (stgmed_file_obj_t*)obj; + + if(!file_obj->buf->cache_file) { + WARN("cache_file not set\n"); + return INET_E_DATA_NOT_AVAILABLE; + } + + fill_stgmed_buffer(file_obj->buf); + if(file_obj->buf->size == sizeof(file_obj->buf->buf)) { + BYTE buf[1024]; + DWORD read; + HRESULT hres; + + do { + hres = IInternetProtocol_Read(file_obj->buf->protocol, buf, sizeof(buf), &read); + }while(hres == S_OK); + } + + stgmed->tymed = TYMED_FILE; + stgmed->u.lpszFileName = file_obj->buf->cache_file; + stgmed->pUnkForRelease = STGMEDUNK(file_obj->buf); + + return S_OK; +} + +static void *stgmed_file_get_result(stgmed_obj_t *obj) +{ + return NULL; +} + +static const stgmed_obj_vtbl stgmed_file_vtbl = { + stgmed_file_release, + stgmed_file_fill_stgmed, + stgmed_file_get_result +}; + +static stgmed_obj_t *create_stgmed_file(stgmed_buf_t *buf) +{ + stgmed_file_obj_t *ret = heap_alloc(sizeof(*ret)); + + ret->stgmed_obj.vtbl = &stgmed_file_vtbl; + + IUnknown_AddRef(STGMEDUNK(buf)); + ret->buf = buf; + + return &ret->stgmed_obj; +} + +#define BINDING_THIS(iface) DEFINE_THIS(Binding, Binding, iface)
static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void **ppv) { @@ -736,8 +940,10 @@ IInternetProtocol_Release(This->protocol); if(This->service_provider) IServiceProvider_Release(This->service_provider); - if(This->stream) - IStream_Release(STREAM(This->stream)); + if(This->stgmed_buf) + IUnknown_Release(STGMEDUNK(This->stgmed_buf)); + if(This->stgmed_obj) + This->stgmed_obj->vtbl->release(This->stgmed_obj); if(This->obj) IUnknown_Release(This->obj); if(This->bctx) @@ -877,7 +1083,7 @@ TRACE("(%p)->(%p)\n", This, pProtocolData);
task = heap_alloc(sizeof(switch_task_t)); - memcpy(&task->data, pProtocolData, sizeof(PROTOCOLDATA)); + task->data = *pProtocolData;
push_task(This, &task->header, switch_proc);
@@ -957,7 +1163,7 @@ on_progress(This, 0, 0, BINDSTATUS_CONNECTING, szStatusText); break; case BINDSTATUS_BEGINDOWNLOADDATA: - fill_stream_buffer(This->stream); + fill_stgmed_buffer(This->stgmed_buf); break; case BINDSTATUS_MIMETYPEAVAILABLE: set_binding_mime(This, szStatusText); @@ -971,6 +1177,8 @@ mime_available(This, szStatusText, FALSE); break; case BINDSTATUS_CACHEFILENAMEAVAILABLE: + heap_free(This->stgmed_buf->cache_file); + This->stgmed_buf->cache_file = heap_strdupW(szStatusText); break; case BINDSTATUS_DIRECTBIND: This->report_mime = FALSE; @@ -1000,15 +1208,19 @@ mime_available(This, NULL, TRUE);
if(This->download_state == BEFORE_DOWNLOAD) { - fill_stream_buffer(This->stream); + fill_stgmed_buffer(This->stgmed_buf);
This->download_state = DOWNLOADING; sent_begindownloaddata = TRUE; IBindStatusCallback_OnProgress(This->callback, progress, progress_max, BINDSTATUS_BEGINDOWNLOADDATA, This->url); - } - - if(This->stream->hres == S_FALSE || (bscf & BSCF_LASTDATANOTIFICATION)) { + + if(This->stgmed_buf->cache_file) + IBindStatusCallback_OnProgress(This->callback, progress, progress_max, + BINDSTATUS_CACHEFILENAMEAVAILABLE, This->stgmed_buf->cache_file); + } + + if(This->stgmed_buf->hres == S_FALSE || (bscf & BSCF_LASTDATANOTIFICATION)) { This->download_state = END_DOWNLOAD; IBindStatusCallback_OnProgress(This->callback, progress, progress_max, BINDSTATUS_ENDDOWNLOADDATA, This->url); @@ -1021,15 +1233,26 @@ if(!(This->state & BINDING_OBJAVAIL)) create_object(This); }else { + STGMEDIUM stgmed; + HRESULT hres; + if(!(This->state & BINDING_LOCKED)) { HRESULT hres = IInternetProtocol_LockRequest(This->protocol, 0); if(SUCCEEDED(hres)) This->state |= BINDING_LOCKED; }
+ hres = This->stgmed_obj->vtbl->fill_stgmed(This->stgmed_obj, &stgmed); + if(FAILED(hres)) { + stop_binding(This, hres, NULL); + return; + } + + formatetc.tymed = stgmed.tymed; formatetc.cfFormat = This->clipboard_format; + IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress, - &formatetc, &This->stgmed); + &formatetc, &stgmed);
if(This->download_state == END_DOWNLOAD) stop_binding(This, S_OK, NULL); @@ -1159,7 +1382,7 @@
*grfBINDF = This->bindf;
- memcpy(pbindinfo, &This->bindinfo, sizeof(BINDINFO)); + *pbindinfo = This->bindinfo;
if(pbindinfo->szExtraInfo || pbindinfo->szCustomVerb) FIXME("copy strings\n"); @@ -1283,7 +1506,7 @@ IUnknown_Release(unk); }
- return SUCCEEDED(hres) ? S_OK : MK_E_SYNTAX; + return SUCCEEDED(hres) ? S_OK : INET_E_DATA_NOT_AVAILABLE; }
static BOOL is_urlmon_protocol(LPCWSTR url) @@ -1326,11 +1549,6 @@ Binding *ret; HRESULT hres;
- if(!to_obj && !IsEqualGUID(&IID_IStream, riid)) { - FIXME("Unsupported riid %s\n", debugstr_guid(riid)); - return E_NOTIMPL; - } - URLMON_LockModule();
ret = heap_alloc_zero(sizeof(Binding)); @@ -1406,15 +1624,25 @@ ret->url = heap_strdupW(url);
if(binding_ctx) { - ret->stream = binding_ctx->stream; - IStream_AddRef(STREAM(ret->stream)); + ret->stgmed_buf = binding_ctx->stgmed_buf; + IUnknown_AddRef(STGMEDUNK(ret->stgmed_buf)); ret->clipboard_format = binding_ctx->clipboard_format; }else { - ret->stream = create_stream(ret->protocol); - } - ret->stgmed.tymed = TYMED_ISTREAM; - ret->stgmed.u.pstm = STREAM(ret->stream); - ret->stgmed.pUnkForRelease = (IUnknown*)BINDING(ret); /* NOTE: Windows uses other IUnknown */ + ret->stgmed_buf = create_stgmed_buf(ret->protocol); + } + + if(to_obj) { + ret->stgmed_obj = NULL; + }else if(IsEqualGUID(&IID_IStream, riid)) { + ret->stgmed_obj = create_stgmed_stream(ret->stgmed_buf); + }else if(IsEqualGUID(&IID_IUnknown, riid)) { + ret->bindf |= BINDF_NEEDFILE; + ret->stgmed_obj = create_stgmed_file(ret->stgmed_buf); + }else { + FIXME("Unsupported riid %s\n", debugstr_guid(riid)); + IBinding_Release(BINDING(ret)); + return E_NOTIMPL; + }
*binding = ret; return S_OK; @@ -1434,7 +1662,7 @@ hres = IBindStatusCallback_OnStartBinding(binding->callback, 0, BINDING(binding)); if(FAILED(hres)) { WARN("OnStartBinding failed: %08x\n", hres); - stop_binding(binding, 0x800c0008, NULL); + stop_binding(binding, INET_E_DOWNLOAD_FAILURE, NULL); IBinding_Release(BINDING(binding)); return hres; } @@ -1448,7 +1676,7 @@
TRACE("start ret %08x\n", hres);
- if(FAILED(hres)) { + if(FAILED(hres) && hres != E_PENDING) { stop_binding(binding, hres, NULL); IBinding_Release(BINDING(binding));
@@ -1484,23 +1712,16 @@ if(FAILED(hres)) return hres;
- if(binding->hres != S_OK) { - hres = SUCCEEDED(binding->hres) ? S_OK : binding->hres; - }else if(binding->stream->init_buf) { + if(binding->hres == S_OK && binding->stgmed_buf->init) { if((binding->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED)) IInternetProtocol_UnlockRequest(binding->protocol);
- IStream_AddRef(STREAM(binding->stream)); - *ppv = binding->stream; - - hres = S_OK; - }else { - hres = MK_S_ASYNCHRONOUS; + *ppv = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj); }
IBinding_Release(BINDING(binding));
- return hres; + return *ppv ? S_OK : MK_S_ASYNCHRONOUS; }
HRESULT bind_to_object(IMoniker *mon, LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
Added: trunk/reactos/dll/win32/urlmon/download.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/download.c... ============================================================================== --- trunk/reactos/dll/win32/urlmon/download.c (added) +++ trunk/reactos/dll/win32/urlmon/download.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -1,0 +1,406 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "urlmon_main.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(urlmon); + +typedef struct { + const IBindStatusCallbackVtbl *lpBindStatusCallbackVtbl; + const IServiceProviderVtbl *lpServiceProviderVtbl; + + LONG ref; + + IBindStatusCallback *callback; + LPWSTR file_name; + LPWSTR cache_file; +} DownloadBSC; + +#define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl) +#define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl) + +#define STATUSCLB_THIS(iface) DEFINE_THIS(DownloadBSC, BindStatusCallback, iface) + +static HRESULT WINAPI DownloadBSC_QueryInterface(IBindStatusCallback *iface, + REFIID riid, void **ppv) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv); + *ppv = STATUSCLB(This); + }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) { + TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv); + *ppv = STATUSCLB(This); + }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { + TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv); + *ppv = SERVPROV(This); + } + + if(*ppv) { + IBindStatusCallback_AddRef((IUnknown*)*ppv); + return S_OK; + } + + TRACE("Unsupported riid = %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI DownloadBSC_AddRef(IBindStatusCallback *iface) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref = %d\n", This, ref); + + return ref; +} + +static ULONG WINAPI DownloadBSC_Release(IBindStatusCallback *iface) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref = %d\n", This, ref); + + if(!ref) { + if(This->callback) + IBindStatusCallback_Release(This->callback); + heap_free(This->file_name); + heap_free(This->cache_file); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI DownloadBSC_OnStartBinding(IBindStatusCallback *iface, + DWORD dwReserved, IBinding *pbind) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind); + + if(This->callback) + IBindStatusCallback_OnStartBinding(This->callback, dwReserved, pbind); + + return S_OK; +} + +static HRESULT WINAPI DownloadBSC_GetPriority(IBindStatusCallback *iface, LONG *pnPriority) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + FIXME("(%p)->(%p)\n", This, pnPriority); + return E_NOTIMPL; +} + +static HRESULT WINAPI DownloadBSC_OnLowResource(IBindStatusCallback *iface, DWORD reserved) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + FIXME("(%p)->(%d)\n", This, reserved); + return E_NOTIMPL; +} + +static void on_progress(DownloadBSC *This, ULONG progress, ULONG progress_max, ULONG status_code, LPCWSTR status_text) +{ + HRESULT hres; + + if(!This->callback) + return; + + hres = IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text); + if(FAILED(hres)) + FIXME("OnProgress failed: %08x\n", hres); +} + +static HRESULT WINAPI DownloadBSC_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, + ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + + TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, + debugstr_w(szStatusText)); + + switch(ulStatusCode) { + case BINDSTATUS_BEGINDOWNLOADDATA: + case BINDSTATUS_DOWNLOADINGDATA: + case BINDSTATUS_ENDDOWNLOADDATA: + case BINDSTATUS_SENDINGREQUEST: + case BINDSTATUS_MIMETYPEAVAILABLE: + on_progress(This, ulProgress, ulProgressMax, ulStatusCode, szStatusText); + break; + + case BINDSTATUS_CACHEFILENAMEAVAILABLE: + on_progress(This, ulProgress, ulProgressMax, ulStatusCode, szStatusText); + This->cache_file = heap_strdupW(szStatusText); + break; + + case BINDSTATUS_FINDINGRESOURCE: + case BINDSTATUS_CONNECTING: + break; + + default: + FIXME("Unsupported status %u\n", ulStatusCode); + } + + return S_OK; +} + +static HRESULT WINAPI DownloadBSC_OnStopBinding(IBindStatusCallback *iface, + HRESULT hresult, LPCWSTR szError) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError)); + + if(This->cache_file) { + BOOL b; + + b = CopyFileW(This->cache_file, This->file_name, FALSE); + if(!b) + FIXME("CopyFile failed: %u\n", GetLastError()); + }else { + FIXME("No cache file\n"); + } + + if(This->callback) + IBindStatusCallback_OnStopBinding(This->callback, hresult, szError); + + return S_OK; +} + +static HRESULT WINAPI DownloadBSC_GetBindInfo(IBindStatusCallback *iface, + DWORD *grfBINDF, BINDINFO *pbindinfo) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + DWORD bindf = 0; + + TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo); + + if(This->callback) { + BINDINFO bindinfo; + HRESULT hres; + + memset(&bindinfo, 0, sizeof(bindinfo)); + bindinfo.cbSize = sizeof(bindinfo); + + hres = IBindStatusCallback_GetBindInfo(This->callback, &bindf, &bindinfo); + if(SUCCEEDED(hres)) + ReleaseBindInfo(&bindinfo); + } + + *grfBINDF = BINDF_PULLDATA | BINDF_NEEDFILE | (bindf & BINDF_ENFORCERESTRICTED); + return S_OK; +} + +static HRESULT WINAPI DownloadBSC_OnDataAvailable(IBindStatusCallback *iface, + DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed); + + return S_OK; +} + +static HRESULT WINAPI DownloadBSC_OnObjectAvailable(IBindStatusCallback *iface, + REFIID riid, IUnknown *punk) +{ + DownloadBSC *This = STATUSCLB_THIS(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk); + return E_NOTIMPL; +} + +#undef STATUSCLB_THIS + +static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = { + DownloadBSC_QueryInterface, + DownloadBSC_AddRef, + DownloadBSC_Release, + DownloadBSC_OnStartBinding, + DownloadBSC_GetPriority, + DownloadBSC_OnLowResource, + DownloadBSC_OnProgress, + DownloadBSC_OnStopBinding, + DownloadBSC_GetBindInfo, + DownloadBSC_OnDataAvailable, + DownloadBSC_OnObjectAvailable +}; + +#define SERVPROV_THIS(iface) DEFINE_THIS(DownloadBSC, ServiceProvider, iface) + +static HRESULT WINAPI DwlServiceProvider_QueryInterface(IServiceProvider *iface, + REFIID riid, void **ppv) +{ + DownloadBSC *This = SERVPROV_THIS(iface); + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); +} + +static ULONG WINAPI DwlServiceProvider_AddRef(IServiceProvider *iface) +{ + DownloadBSC *This = SERVPROV_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI DwlServiceProvider_Release(IServiceProvider *iface) +{ + DownloadBSC *This = SERVPROV_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI DwlServiceProvider_QueryService(IServiceProvider *iface, + REFGUID guidService, REFIID riid, void **ppv) +{ + DownloadBSC *This = SERVPROV_THIS(iface); + IServiceProvider *serv_prov; + HRESULT hres; + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); + + if(!This->callback) + return E_NOINTERFACE; + + hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv); + if(SUCCEEDED(hres)) + return S_OK; + + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IServiceProvider, (void**)&serv_prov); + if(SUCCEEDED(hres)) { + hres = IServiceProvider_QueryService(serv_prov, guidService, riid, ppv); + IServiceProvider_Release(serv_prov); + return hres; + } + + return E_NOINTERFACE; +} + +#undef SERVPROV_THIS + +static const IServiceProviderVtbl ServiceProviderVtbl = { + DwlServiceProvider_QueryInterface, + DwlServiceProvider_AddRef, + DwlServiceProvider_Release, + DwlServiceProvider_QueryService +}; + +static IBindStatusCallback *DownloadBSC_Create(IBindStatusCallback *callback, LPCWSTR file_name) +{ + DownloadBSC *ret = heap_alloc(sizeof(*ret)); + + ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl; + ret->lpServiceProviderVtbl = &ServiceProviderVtbl; + ret->ref = 1; + ret->file_name = heap_strdupW(file_name); + ret->cache_file = NULL; + + if(callback) + IBindStatusCallback_AddRef(callback); + ret->callback = callback; + + return STATUSCLB(ret); +} + +/*********************************************************************** + * URLDownloadToFileW (URLMON.@) + * + * Downloads URL szURL to file szFileName and call lpfnCB callback to + * report progress. + * + * PARAMS + * pCaller [I] controlling IUnknown interface. + * szURL [I] URL of the file to download + * szFileName [I] file name to store the content of the URL + * dwReserved [I] reserved - set to 0 + * lpfnCB [I] callback for progress report + * + * RETURNS + * S_OK on success + */ +HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, LPCWSTR szURL, LPCWSTR szFileName, + DWORD dwReserved, LPBINDSTATUSCALLBACK lpfnCB) +{ + IBindStatusCallback *callback; + IUnknown *unk; + IMoniker *mon; + IBindCtx *bindctx; + HRESULT hres; + + TRACE("(%p %s %s %d %p)\n", pCaller, debugstr_w(szURL), debugstr_w(szFileName), dwReserved, lpfnCB); + + if(pCaller) + FIXME("pCaller not supported\n"); + + callback = DownloadBSC_Create(lpfnCB, szFileName); + hres = CreateAsyncBindCtx(0, callback, NULL, &bindctx); + IBindStatusCallback_Release(callback); + if(FAILED(hres)) + return hres; + + hres = CreateURLMoniker(NULL, szURL, &mon); + if(FAILED(hres)) { + IBindCtx_Release(bindctx); + return hres; + } + + hres = IMoniker_BindToStorage(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk); + IMoniker_Release(mon); + IBindCtx_Release(bindctx); + + if(unk) + IUnknown_Release(unk); + + return hres == MK_S_ASYNCHRONOUS ? S_OK : hres; +} + +/*********************************************************************** + * URLDownloadToFileA (URLMON.@) + * + * Downloads URL szURL to rile szFileName and call lpfnCB callback to + * report progress. + * + * PARAMS + * pCaller [I] controlling IUnknown interface. + * szURL [I] URL of the file to download + * szFileName [I] file name to store the content of the URL + * dwReserved [I] reserved - set to 0 + * lpfnCB [I] callback for progress report + * + * RETURNS + * S_OK on success + */ +HRESULT WINAPI URLDownloadToFileA(LPUNKNOWN pCaller, LPCSTR szURL, LPCSTR szFileName, DWORD dwReserved, + LPBINDSTATUSCALLBACK lpfnCB) +{ + LPWSTR urlW, file_nameW; + HRESULT hres; + + TRACE("(%p %s %s %d %p)\n", pCaller, debugstr_a(szURL), debugstr_a(szFileName), dwReserved, lpfnCB); + + urlW = heap_strdupAtoW(szURL); + file_nameW = heap_strdupAtoW(szFileName); + + hres = URLDownloadToFileW(pCaller, urlW, file_nameW, dwReserved, lpfnCB); + + heap_free(urlW); + heap_free(file_nameW); + + return hres; +}
Propchange: trunk/reactos/dll/win32/urlmon/download.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/win32/urlmon/file.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/file.c?rev... ============================================================================== --- trunk/reactos/dll/win32/urlmon/file.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/file.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -229,10 +229,14 @@
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
+ if (pcbRead) + *pcbRead = 0; + if(!This->file) return INET_E_DATA_NOT_AVAILABLE;
- ReadFile(This->file, pv, cb, &read, NULL); + if (!ReadFile(This->file, pv, cb, &read, NULL)) + return INET_E_DOWNLOAD_FAILURE;
if(pcbRead) *pcbRead = read;
Modified: trunk/reactos/dll/win32/urlmon/http.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/http.c?rev... ============================================================================== --- trunk/reactos/dll/win32/urlmon/http.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/http.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -380,7 +380,7 @@ if (!(user_agent = CoTaskMemAlloc((len)*sizeof(WCHAR)))) WARN("Out of memory\n"); else - MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len); } heap_free(user_agenta); } @@ -419,6 +419,8 @@
if (This->grfBINDF & BINDF_NOWRITECACHE) request_flags |= INTERNET_FLAG_NO_CACHE_WRITE; + if (This->grfBINDF & BINDF_NEEDFILE) + request_flags |= INTERNET_FLAG_NEED_FILE; This->request = HttpOpenRequestW(This->connect, This->bind_info.dwBindVerb < BINDVERB_CUSTOM ? wszBindVerb[This->bind_info.dwBindVerb] : This->bind_info.szCustomVerb, @@ -655,6 +657,21 @@ { This->content_length = atoiW(content_length); } + + if(This->grfBINDF & BINDF_NEEDFILE) { + WCHAR cache_file[MAX_PATH]; + DWORD buflen = sizeof(cache_file); + + if(InternetQueryOptionW(This->request, INTERNET_OPTION_DATAFILE_NAME, + cache_file, &buflen)) + { + IInternetProtocolSink_ReportProgress(This->protocol_sink, + BINDSTATUS_CACHEFILENAMEAVAILABLE, + cache_file); + }else { + FIXME("Could not get cache file\n"); + } + }
This->flags |= FLAG_FIRST_CONTINUE_COMPLETE; }
Modified: trunk/reactos/dll/win32/urlmon/mk.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/mk.c?rev=3... ============================================================================== --- trunk/reactos/dll/win32/urlmon/mk.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/mk.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -124,7 +124,6 @@
ReleaseBindInfo(&bindinfo);
- IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL); IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, NULL);
hres = FindMimeFromData(NULL, szUrl, NULL, 0, NULL, 0, &mime, 0);
Modified: trunk/reactos/dll/win32/urlmon/regsvr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/regsvr.c?r... ============================================================================== --- trunk/reactos/dll/win32/urlmon/regsvr.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/regsvr.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -522,7 +522,7 @@ { HRESULT hres; HMODULE hAdvpack; - typeof(RegInstallA) *pRegInstall; + HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable); STRTABLEA strtable; STRENTRYA pse[7]; static CLSID const *clsids[34]; @@ -550,7 +550,7 @@ strtable.pse = pse;
hAdvpack = LoadLibraryW(wszAdvpack); - pRegInstall = (typeof(RegInstallA)*)GetProcAddress(hAdvpack, "RegInstall"); + pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
hres = pRegInstall(URLMON_hInstance, doregister ? "RegisterDll" : "UnregisterDll", &strtable);
Modified: trunk/reactos/dll/win32/urlmon/sec_mgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/sec_mgr.c?... ============================================================================== --- trunk/reactos/dll/win32/urlmon/sec_mgr.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/sec_mgr.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -23,65 +23,27 @@
#include "urlmon_main.h" #include "winreg.h" +#include "wininet.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-/*********************************************************************** - * InternetSecurityManager implementation - * - */ -typedef struct { - const IInternetSecurityManagerVtbl* lpInternetSecurityManagerVtbl; - - LONG ref; - - IInternetSecurityMgrSite *mgrsite; - IInternetSecurityManager *custom_manager; -} SecManagerImpl; - -#define SECMGR_THIS(iface) DEFINE_THIS(SecManagerImpl, InternetSecurityManager, iface) - -static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone) -{ - WCHAR schema[64]; - DWORD res, size=0; +static const WCHAR fileW[] = {'f','i','l','e',0}; + +static HRESULT get_zone_from_reg(LPCWSTR schema, DWORD *zone) +{ + DWORD res, size; HKEY hkey; - HRESULT hres;
static const WCHAR wszZoneMapProtocolKey[] = {'S','o','f','t','w','a','r','e','\', - 'M','i','c','r','o','s','o','f','t','\', - 'W','i','n','d','o','w','s','\', - 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\', - 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\', - 'Z','o','n','e','M','a','p','\', - 'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0}; - static const WCHAR wszFile[] = {'f','i','l','e',0}; - - *zone = -1; - - hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(WCHAR), &size, 0); - if(FAILED(hres)) - return hres; - if(!*schema) - return 0x80041001; - - /* file protocol is a special case */ - if(!strcmpW(schema, wszFile)) { - WCHAR path[MAX_PATH]; - - hres = CoInternetParseUrl(url, PARSE_PATH_FROM_URL, 0, path, - sizeof(path)/sizeof(WCHAR), &size, 0); - - if(SUCCEEDED(hres) && strchrW(path, '\')) { - *zone = 0; - return S_OK; - } - } - - WARN("domains are not yet implemented\n"); + 'M','i','c','r','o','s','o','f','t','\', + 'W','i','n','d','o','w','s','\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\', + 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\', + 'Z','o','n','e','M','a','p','\', + 'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0};
res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapProtocolKey, &hkey); if(res != ERROR_SUCCESS) { @@ -110,6 +72,171 @@ *zone = 3; return S_OK; } + +static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone, LPWSTR *ret_url) +{ + LPWSTR secur_url; + WCHAR schema[64]; + DWORD size=0; + HRESULT hres; + + secur_url = heap_alloc(INTERNET_MAX_URL_LENGTH*sizeof(WCHAR)); + *zone = -1; + + hres = CoInternetParseUrl(url, PARSE_SECURITY_URL, 0, secur_url, INTERNET_MAX_URL_LENGTH, &size, 0); + if(hres != S_OK) + strcpyW(secur_url, url); + + hres = CoInternetParseUrl(secur_url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(WCHAR), &size, 0); + if(FAILED(hres) || !*schema) { + heap_free(secur_url); + return E_INVALIDARG; + } + + /* file protocol is a special case */ + if(!strcmpW(schema, fileW)) { + WCHAR path[MAX_PATH], root[20]; + WCHAR *ptr; + + hres = CoInternetParseUrl(secur_url, PARSE_PATH_FROM_URL, 0, path, + sizeof(path)/sizeof(WCHAR), &size, 0); + + if(SUCCEEDED(hres) && (ptr = strchrW(path, '\')) && ptr-path < sizeof(root)/sizeof(WCHAR)) { + UINT type; + + memcpy(root, path, (ptr-path)*sizeof(WCHAR)); + root[ptr-path] = 0; + + type = GetDriveTypeW(root); + + switch(type) { + case DRIVE_UNKNOWN: + case DRIVE_NO_ROOT_DIR: + break; + case DRIVE_REMOVABLE: + case DRIVE_FIXED: + case DRIVE_CDROM: + case DRIVE_RAMDISK: + *zone = 0; + hres = S_OK; + break; + case DRIVE_REMOTE: + *zone = 3; + hres = S_OK; + break; + default: + FIXME("unsupported drive type %d\n", type); + } + } + } + + if(*zone == -1) { + WARN("domains are not yet implemented\n"); + hres = get_zone_from_reg(schema, zone); + } + + if(FAILED(hres) || !ret_url) + heap_free(secur_url); + else + *ret_url = secur_url; + + return hres; +} + +static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey) +{ + static const WCHAR wszZonesKey[] = + {'S','o','f','t','w','a','r','e','\', + 'M','i','c','r','o','s','o','f','t','\', + 'W','i','n','d','o','w','s','\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\', + 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\', + 'Z','o','n','e','s','\',0}; + static const WCHAR wszFormat[] = {'%','s','%','l','d',0}; + + WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+8]; + DWORD res; + + wsprintfW(key_name, wszFormat, wszZonesKey, zone); + + res = RegOpenKeyW(parent_key, key_name, hkey); + + if(res != ERROR_SUCCESS) { + WARN("RegOpenKey failed\n"); + return E_INVALIDARG; + } + + return S_OK; +} + +static HRESULT get_action_policy(DWORD zone, DWORD action, BYTE *policy, DWORD size, URLZONEREG zone_reg) +{ + HKEY parent_key; + HKEY hkey; + LONG res; + HRESULT hres; + + switch(action) { + case URLACTION_SCRIPT_OVERRIDE_SAFETY: + *(DWORD*)policy = URLPOLICY_DISALLOW; + return S_OK; + } + + switch(zone_reg) { + case URLZONEREG_DEFAULT: + case URLZONEREG_HKCU: + parent_key = HKEY_CURRENT_USER; + break; + case URLZONEREG_HKLM: + parent_key = HKEY_LOCAL_MACHINE; + break; + default: + WARN("Unknown URLZONEREG: %d\n", zone_reg); + return E_FAIL; + }; + + hres = open_zone_key(parent_key, zone, &hkey); + if(SUCCEEDED(hres)) { + WCHAR action_str[16]; + DWORD len = size; + + static const WCHAR formatW[] = {'%','X',0}; + + wsprintfW(action_str, formatW, action); + + res = RegQueryValueExW(hkey, action_str, NULL, NULL, policy, &len); + if(res == ERROR_MORE_DATA) { + hres = E_INVALIDARG; + }else if(res == ERROR_FILE_NOT_FOUND) { + hres = E_FAIL; + }else if(res != ERROR_SUCCESS) { + ERR("RegQueryValue failed: %d\n", res); + hres = E_UNEXPECTED; + } + + RegCloseKey(hkey); + } + + if(FAILED(hres) && zone_reg == URLZONEREG_DEFAULT) + return get_action_policy(zone, action, policy, size, URLZONEREG_HKLM); + + return hres; +} + +/*********************************************************************** + * InternetSecurityManager implementation + * + */ +typedef struct { + const IInternetSecurityManagerVtbl* lpInternetSecurityManagerVtbl; + + LONG ref; + + IInternetSecurityMgrSite *mgrsite; + IInternetSecurityManager *custom_manager; +} SecManagerImpl; + +#define SECMGR_THIS(iface) DEFINE_THIS(SecManagerImpl, InternetSecurityManager, iface)
static HRESULT WINAPI SecManagerImpl_QueryInterface(IInternetSecurityManager* iface,REFIID riid,void** ppvObject) { @@ -230,8 +357,6 @@ DWORD dwFlags) { SecManagerImpl *This = SECMGR_THIS(iface); - LPWSTR url; - DWORD size; HRESULT hres;
TRACE("(%p)->(%s %p %08x)\n", iface, debugstr_w(pwszUrl), pdwZone, dwFlags); @@ -251,26 +376,15 @@ if(dwFlags) FIXME("not supported flags: %08x\n", dwFlags);
- size = (strlenW(pwszUrl)+16) * sizeof(WCHAR); - url = heap_alloc(size); - - hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, url, size/sizeof(WCHAR), &size, 0); - if(FAILED(hres)) - memcpy(url, pwszUrl, size); - - hres = map_url_to_zone(url, pdwZone); - - heap_free(url); - - return hres; + return map_url_to_zone(pwszUrl, pdwZone, NULL); }
static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface, LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) { SecManagerImpl *This = SECMGR_THIS(iface); - LPWSTR buf, ptr, ptr2; - DWORD size, zone, len; + LPWSTR url, ptr, ptr2; + DWORD zone, len; HRESULT hres;
static const WCHAR wszFile[] = {'f','i','l','e',':'}; @@ -291,26 +405,17 @@ if(dwReserved) FIXME("dwReserved is not supported\n");
- len = strlenW(pwszUrl)+1; - buf = heap_alloc((len+16)*sizeof(WCHAR)); - - hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, buf, len, &size, 0); + hres = map_url_to_zone(pwszUrl, &zone, &url); if(FAILED(hres)) - memcpy(buf, pwszUrl, len*sizeof(WCHAR)); - - hres = map_url_to_zone(buf, &zone); - if(FAILED(hres)) { - heap_free(buf); return hres == 0x80041001 ? E_INVALIDARG : hres; - }
/* file protocol is a special case */ - if(strlenW(pwszUrl) >= sizeof(wszFile)/sizeof(WCHAR) - && !memcmp(buf, wszFile, sizeof(wszFile))) { + if(strlenW(url) >= sizeof(wszFile)/sizeof(WCHAR) + && !memcmp(url, wszFile, sizeof(wszFile)) && strchrW(url, '\')) {
static const BYTE secidFile[] = {'f','i','l','e',':'};
- heap_free(buf); + heap_free(url);
if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone)) return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); @@ -322,7 +427,7 @@ return S_OK; }
- ptr = strchrW(buf, ':'); + ptr = strchrW(url, ':'); ptr2 = ++ptr; while(*ptr2 == '/') ptr2++; @@ -333,15 +438,15 @@ if(ptr) *ptr = 0;
- len = WideCharToMultiByte(CP_ACP, 0, buf, -1, NULL, 0, NULL, NULL)-1; + len = WideCharToMultiByte(CP_ACP, 0, url, -1, NULL, 0, NULL, NULL)-1;
if(len+sizeof(DWORD) > *pcbSecurityId) { - heap_free(buf); + heap_free(url); return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); }
- WideCharToMultiByte(CP_ACP, 0, buf, -1, (LPSTR)pbSecurityId, -1, NULL, NULL); - heap_free(buf); + WideCharToMultiByte(CP_ACP, 0, url, -1, (LPSTR)pbSecurityId, len, NULL, NULL); + heap_free(url);
*(DWORD*)(pbSecurityId+len) = zone;
@@ -358,6 +463,7 @@ DWORD dwFlags, DWORD dwReserved) { SecManagerImpl *This = SECMGR_THIS(iface); + DWORD zone, policy; HRESULT hres;
TRACE("(%p)->(%s %08x %p %08x %p %08x %08x %08x)\n", iface, debugstr_w(pwszUrl), dwAction, @@ -370,8 +476,36 @@ return hres; }
- FIXME("Default action is not implemented\n"); - return E_NOTIMPL; + if(pContext || cbContext || dwFlags || dwReserved) + FIXME("Unsupported arguments\n"); + + if(!pwszUrl) + return E_INVALIDARG; + + hres = map_url_to_zone(pwszUrl, &zone, NULL); + if(FAILED(hres)) + return hres; + + hres = get_action_policy(zone, dwAction, (BYTE*)&policy, sizeof(policy), URLZONEREG_DEFAULT); + if(FAILED(hres)) + return hres; + + TRACE("policy %x\n", policy); + + switch(GetUrlPolicyPermissions(policy)) { + case URLPOLICY_ALLOW: + case URLPOLICY_CHANNEL_SOFTDIST_PRECACHE: + return S_OK; + case URLPOLICY_DISALLOW: + return S_FALSE; + case URLPOLICY_QUERY: + FIXME("URLPOLICY_QUERY not implemented\n"); + return E_FAIL; + default: + FIXME("Not implemented policy %x\n", policy); + } + + return E_FAIL; }
@@ -481,46 +615,6 @@ LONG ref; } ZoneMgrImpl;
-static HRESULT open_zone_key(DWORD zone, HKEY *hkey, URLZONEREG zone_reg) -{ - static const WCHAR wszZonesKey[] = - {'S','o','f','t','w','a','r','e','\', - 'M','i','c','r','o','s','o','f','t','\', - 'W','i','n','d','o','w','s','\', - 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\', - 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\', - 'Z','o','n','e','s','\',0}; - static const WCHAR wszFormat[] = {'%','s','%','l','d',0}; - - WCHAR key_name[sizeof(wszZonesKey)/sizeof(WCHAR)+8]; - HKEY parent_key; - DWORD res; - - switch(zone_reg) { - case URLZONEREG_DEFAULT: /* FIXME: TEST */ - case URLZONEREG_HKCU: - parent_key = HKEY_CURRENT_USER; - break; - case URLZONEREG_HKLM: - parent_key = HKEY_LOCAL_MACHINE; - break; - default: - WARN("Unknown URLZONEREG: %d\n", zone_reg); - return E_FAIL; - }; - - wsprintfW(key_name, wszFormat, wszZonesKey, zone); - - res = RegOpenKeyW(parent_key, key_name, hkey); - - if(res != ERROR_SUCCESS) { - WARN("RegOpenKey failed\n"); - return E_INVALIDARG; - } - - return S_OK; -} - /******************************************************************** * IInternetZoneManager_QueryInterface */ @@ -634,39 +728,13 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneActionPolicy(IInternetZoneManager* iface, DWORD dwZone, DWORD dwAction, BYTE* pPolicy, DWORD cbPolicy, URLZONEREG urlZoneReg) { - WCHAR action[16]; - HKEY hkey; - LONG res; - DWORD size = cbPolicy; - HRESULT hres; - - static const WCHAR wszFormat[] = {'%','l','X',0}; - TRACE("(%p)->(%d %08x %p %d %d)\n", iface, dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg);
if(!pPolicy) return E_INVALIDARG;
- hres = open_zone_key(dwZone, &hkey, urlZoneReg); - if(FAILED(hres)) - return hres; - - wsprintfW(action, wszFormat, dwAction); - - res = RegQueryValueExW(hkey, action, NULL, NULL, pPolicy, &size); - if(res == ERROR_MORE_DATA) { - hres = E_INVALIDARG; - }else if(res == ERROR_FILE_NOT_FOUND) { - hres = E_FAIL; - }else if(res != ERROR_SUCCESS) { - ERR("RegQueryValue failed: %d\n", res); - hres = E_UNEXPECTED; - } - - RegCloseKey(hkey); - - return hres; + return get_action_policy(dwZone, dwAction, pPolicy, cbPolicy, urlZoneReg); }
/********************************************************************
Modified: trunk/reactos/dll/win32/urlmon/session.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/session.c?... ============================================================================== --- trunk/reactos/dll/win32/urlmon/session.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/session.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -27,6 +27,7 @@ LPWSTR protocol; IClassFactory *cf; CLSID clsid; + BOOL urlmon;
struct name_space *next; } name_space; @@ -41,6 +42,15 @@
static name_space *name_space_list = NULL; static mime_filter *mime_filter_list = NULL; + +static CRITICAL_SECTION session_cs; +static CRITICAL_SECTION_DEBUG session_cs_dbg = +{ + 0, 0, &session_cs, + { &session_cs_dbg.ProcessLocksList, &session_cs_dbg.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": session") } +}; +static CRITICAL_SECTION session_cs = { &session_cs_dbg, -1, 0, 0, 0, 0 };
static name_space *find_name_space(LPCWSTR protocol) { @@ -95,7 +105,87 @@ if(pclsid) *pclsid = clsid;
+ if(!ret) + return S_OK; + return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)ret); +} + +static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL urlmon_protocol) +{ + name_space *new_name_space; + + new_name_space = heap_alloc(sizeof(name_space)); + + if(!urlmon_protocol) + IClassFactory_AddRef(cf); + new_name_space->cf = cf; + new_name_space->clsid = *clsid; + new_name_space->urlmon = urlmon_protocol; + new_name_space->protocol = heap_strdupW(protocol); + + EnterCriticalSection(&session_cs); + + new_name_space->next = name_space_list; + name_space_list = new_name_space; + + LeaveCriticalSection(&session_cs); + + return S_OK; +} + +static HRESULT unregister_namespace(IClassFactory *cf, LPCWSTR protocol) +{ + name_space *iter, *last = NULL; + + EnterCriticalSection(&session_cs); + + for(iter = name_space_list; iter; iter = iter->next) { + if(iter->cf == cf && !strcmpW(iter->protocol, protocol)) + break; + last = iter; + } + + if(iter) { + if(last) + last->next = iter->next; + else + name_space_list = iter->next; + } + + LeaveCriticalSection(&session_cs); + + if(iter) { + if(!iter->urlmon) + IClassFactory_Release(iter->cf); + heap_free(iter->protocol); + heap_free(iter); + } + + return S_OK; +} + + +void register_urlmon_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL do_register) +{ + if(do_register) + register_namespace(cf, clsid, protocol, TRUE); + else + unregister_namespace(cf, protocol); +} + +BOOL is_registered_protocol(LPCWSTR url) +{ + DWORD schema_len; + WCHAR schema[64]; + HRESULT hres; + + hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), + &schema_len, 0); + if(FAILED(hres)) + return FALSE; + + return get_protocol_cf(schema, schema_len, NULL, NULL) == S_OK; }
IInternetProtocolInfo *get_protocol_info(LPCWSTR url) @@ -112,16 +202,19 @@ if(FAILED(hres) || !schema_len) return NULL;
+ EnterCriticalSection(&session_cs); + ns = find_name_space(schema); - if(ns) { + if(ns && !ns->urlmon) { hres = IClassFactory_QueryInterface(ns->cf, &IID_IInternetProtocolInfo, (void**)&ret); - if(SUCCEEDED(hres)) - return ret; - - hres = IClassFactory_CreateInstance(ns->cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret); - if(SUCCEEDED(hres)) - return ret; - } + if(FAILED(hres)) + hres = IClassFactory_CreateInstance(ns->cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret); + } + + LeaveCriticalSection(&session_cs); + + if(ns && SUCCEEDED(hres)) + return ret;
hres = get_protocol_cf(schema, schema_len, NULL, &cf); if(FAILED(hres)) @@ -142,10 +235,14 @@ DWORD schema_len; HRESULT hres;
+ *ret = NULL; + hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), &schema_len, 0); if(FAILED(hres) || !schema_len) return schema_len ? hres : E_FAIL; + + EnterCriticalSection(&session_cs);
ns = find_name_space(schema); if(ns) { @@ -153,8 +250,12 @@ IClassFactory_AddRef(*ret); if(clsid) *clsid = ns->clsid; + } + + LeaveCriticalSection(&session_cs); + + if(*ret) return S_OK; - }
return get_protocol_cf(schema, schema_len, clsid, ret); } @@ -192,8 +293,6 @@ IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pwzProtocol, ULONG cPatterns, const LPCWSTR *ppwzPatterns, DWORD dwReserved) { - name_space *new_name_space; - TRACE("(%p %s %s %d %p %d)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzProtocol), cPatterns, ppwzPatterns, dwReserved);
@@ -205,47 +304,18 @@ if(!pCF || !pwzProtocol) return E_INVALIDARG;
- new_name_space = heap_alloc(sizeof(name_space)); - - IClassFactory_AddRef(pCF); - new_name_space->cf = pCF; - new_name_space->clsid = *rclsid; - new_name_space->protocol = heap_strdupW(pwzProtocol); - - new_name_space->next = name_space_list; - name_space_list = new_name_space; - return S_OK; + return register_namespace(pCF, rclsid, pwzProtocol, FALSE); }
static HRESULT WINAPI InternetSession_UnregisterNameSpace(IInternetSession *iface, IClassFactory *pCF, LPCWSTR pszProtocol) { - name_space *iter, *last = NULL; - TRACE("(%p %s)\n", pCF, debugstr_w(pszProtocol));
if(!pCF || !pszProtocol) return E_INVALIDARG;
- for(iter = name_space_list; iter; iter = iter->next) { - if(iter->cf == pCF && !strcmpW(iter->protocol, pszProtocol)) - break; - last = iter; - } - - if(!iter) - return S_OK; - - if(last) - last->next = iter->next; - else - name_space_list = iter->next; - - IClassFactory_Release(iter->cf); - heap_free(iter->protocol); - heap_free(iter); - - return S_OK; + return unregister_namespace(pCF, pszProtocol); }
static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface, @@ -262,9 +332,13 @@ filter->clsid = *rclsid; filter->mime = heap_strdupW(pwzType);
+ EnterCriticalSection(&session_cs); + filter->next = mime_filter_list; mime_filter_list = filter;
+ LeaveCriticalSection(&session_cs); + return S_OK; }
@@ -274,6 +348,8 @@ mime_filter *iter, *prev = NULL;
TRACE("(%p %s)\n", pCF, debugstr_w(pwzType)); + + EnterCriticalSection(&session_cs);
for(iter = mime_filter_list; iter; iter = iter->next) { if(iter->cf == pCF && !strcmpW(iter->mime, pwzType)) @@ -281,17 +357,20 @@ prev = iter; }
- if(!iter) - return S_OK; - - if(prev) - prev->next = iter->next; - else - mime_filter_list = iter->next; - - IClassFactory_Release(iter->cf); - heap_free(iter->mime); - heap_free(iter); + if(iter) { + if(prev) + prev->next = iter->next; + else + mime_filter_list = iter->next; + } + + LeaveCriticalSection(&session_cs); + + if(iter) { + IClassFactory_Release(iter->cf); + heap_free(iter->mime); + heap_free(iter); + }
return S_OK; }
Modified: trunk/reactos/dll/win32/urlmon/umon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/umon.c?rev... ============================================================================== --- trunk/reactos/dll/win32/urlmon/umon.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/umon.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -493,10 +493,7 @@ /****************************************************************************** * URLMoniker_BindToStorage ******************************************************************************/ -static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, - IBindCtx* pbc, - REFIID riid, - VOID** ppvObject) +static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, IBindCtx* pbc, VOID** ppvObject) { HRESULT hres; BINDINFO bi; @@ -505,12 +502,7 @@ Binding *bind; int len;
- WARN("(%s %p %s %p)\n", debugstr_w(URLName), pbc, debugstr_guid(riid), ppvObject); - - if(!IsEqualIID(&IID_IStream, riid)) { - FIXME("unsupported iid\n"); - return E_NOTIMPL; - } + WARN("(%s %p %p)\n", debugstr_w(URLName), pbc, ppvObject);
bind = heap_alloc_zero(sizeof(Binding)); bind->lpVtbl = &BindingVtbl; @@ -741,10 +733,11 @@ return E_FAIL; }
- if(url.nScheme== INTERNET_SCHEME_HTTPS - || url.nScheme== INTERNET_SCHEME_FTP - || url.nScheme == INTERNET_SCHEME_GOPHER) - return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, riid, ppvObject); + if(IsEqualGUID(&IID_IStream, riid) && + ( url.nScheme == INTERNET_SCHEME_HTTPS + || url.nScheme == INTERNET_SCHEME_FTP + || url.nScheme == INTERNET_SCHEME_GOPHER)) + return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, ppvObject);
TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject);
@@ -1186,218 +1179,25 @@ }
/*********************************************************************** - * URLDownloadToFileA (URLMON.@) - * - * Downloads URL szURL to rile szFileName and call lpfnCB callback to - * report progress. - * - * PARAMS - * pCaller [I] controlling IUnknown interface. - * szURL [I] URL of the file to download - * szFileName [I] file name to store the content of the URL - * dwReserved [I] reserved - set to 0 - * lpfnCB [I] callback for progress report - * - * RETURNS - * S_OK on success - * E_OUTOFMEMORY when going out of memory + * MkParseDisplayNameEx (URLMON.@) */ -HRESULT WINAPI URLDownloadToFileA(LPUNKNOWN pCaller, - LPCSTR szURL, - LPCSTR szFileName, - DWORD dwReserved, - LPBINDSTATUSCALLBACK lpfnCB) -{ - UNICODE_STRING szURL_w, szFileName_w; - - if ((szURL == NULL) || (szFileName == NULL)) { - FIXME("(%p,%s,%s,%08x,%p) cannot accept NULL strings !\n", pCaller, debugstr_a(szURL), debugstr_a(szFileName), dwReserved, lpfnCB); - return E_INVALIDARG; /* The error code is not specified in this case... */ - } - - if (RtlCreateUnicodeStringFromAsciiz(&szURL_w, szURL)) { - if (RtlCreateUnicodeStringFromAsciiz(&szFileName_w, szFileName)) { - HRESULT ret = URLDownloadToFileW(pCaller, szURL_w.Buffer, szFileName_w.Buffer, dwReserved, lpfnCB); - - RtlFreeUnicodeString(&szURL_w); - RtlFreeUnicodeString(&szFileName_w); - - return ret; - } else { - RtlFreeUnicodeString(&szURL_w); - } - } - - FIXME("(%p,%s,%s,%08x,%p) could not allocate W strings !\n", pCaller, szURL, szFileName, dwReserved, lpfnCB); - return E_OUTOFMEMORY; -} - -/*********************************************************************** - * URLDownloadToFileW (URLMON.@) - * - * Downloads URL szURL to rile szFileName and call lpfnCB callback to - * report progress. - * - * PARAMS - * pCaller [I] controlling IUnknown interface. - * szURL [I] URL of the file to download - * szFileName [I] file name to store the content of the URL - * dwReserved [I] reserved - set to 0 - * lpfnCB [I] callback for progress report - * - * RETURNS - * S_OK on success - * E_OUTOFMEMORY when going out of memory - */ -HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, - LPCWSTR szURL, - LPCWSTR szFileName, - DWORD dwReserved, - LPBINDSTATUSCALLBACK lpfnCB) -{ - HINTERNET hinternet, hcon, hreq; - BOOL r; - CHAR buffer[0x1000]; - DWORD sz, total, written; - DWORD total_size = 0xFFFFFFFF, arg_size = sizeof(total_size); - URL_COMPONENTSW url; - WCHAR host[0x80], path[0x100]; - HANDLE hfile; - static const WCHAR wszAppName[]={'u','r','l','m','o','n','.','d','l','l',0}; - - /* Note: all error codes would need to be checked agains real Windows behaviour... */ - TRACE("(%p,%s,%s,%08x,%p) stub!\n", pCaller, debugstr_w(szURL), debugstr_w(szFileName), dwReserved, lpfnCB); - - if ((szURL == NULL) || (szFileName == NULL)) { - FIXME(" cannot accept NULL strings !\n"); - return E_INVALIDARG; - } - - /* Would be better to use the application name here rather than 'urlmon' :-/ */ - hinternet = InternetOpenW(wszAppName, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); - if (hinternet == NULL) { - return E_OUTOFMEMORY; - } - - memset(&url, 0, sizeof(url)); - url.dwStructSize = sizeof(url); - url.lpszHostName = host; - url.dwHostNameLength = sizeof(host); - url.lpszUrlPath = path; - url.dwUrlPathLength = sizeof(path); - - if (!InternetCrackUrlW(szURL, 0, 0, &url)) { - InternetCloseHandle(hinternet); - return E_OUTOFMEMORY; - } - - if (lpfnCB) { - if (IBindStatusCallback_OnProgress(lpfnCB, 0, 0, BINDSTATUS_CONNECTING, url.lpszHostName) == E_ABORT) { - InternetCloseHandle(hinternet); - return S_OK; - } - } - - hcon = InternetConnectW(hinternet, url.lpszHostName, url.nPort, - url.lpszUserName, url.lpszPassword, - INTERNET_SERVICE_HTTP, 0, 0); - if (!hcon) { - InternetCloseHandle(hinternet); - return E_OUTOFMEMORY; - } - - hreq = HttpOpenRequestW(hcon, NULL, url.lpszUrlPath, NULL, NULL, NULL, 0, 0); - if (!hreq) { - InternetCloseHandle(hinternet); - InternetCloseHandle(hcon); - return E_OUTOFMEMORY; - } - - if (!HttpSendRequestW(hreq, NULL, 0, NULL, 0)) { - InternetCloseHandle(hinternet); - InternetCloseHandle(hcon); - InternetCloseHandle(hreq); - return E_OUTOFMEMORY; - } - - if (HttpQueryInfoW(hreq, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, - &total_size, &arg_size, NULL)) { - TRACE(" total size : %d\n", total_size); - } - - hfile = CreateFileW(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL ); - if (hfile == INVALID_HANDLE_VALUE) { - return E_ACCESSDENIED; - } - - if (lpfnCB) { - if (IBindStatusCallback_OnProgress(lpfnCB, 0, total_size != 0xFFFFFFFF ? total_size : 0, - BINDSTATUS_BEGINDOWNLOADDATA, szURL) == E_ABORT) { - InternetCloseHandle(hreq); - InternetCloseHandle(hcon); - InternetCloseHandle(hinternet); - CloseHandle(hfile); - return S_OK; - } - } - - total = 0; - while (1) { - r = InternetReadFile(hreq, buffer, sizeof(buffer), &sz); - if (!r) { - InternetCloseHandle(hreq); - InternetCloseHandle(hcon); - InternetCloseHandle(hinternet); - - CloseHandle(hfile); - return E_OUTOFMEMORY; - } - if (!sz) - break; - - total += sz; - - if (lpfnCB) { - if (IBindStatusCallback_OnProgress(lpfnCB, total, total_size != 0xFFFFFFFF ? total_size : 0, - BINDSTATUS_DOWNLOADINGDATA, szURL) == E_ABORT) { - InternetCloseHandle(hreq); - InternetCloseHandle(hcon); - InternetCloseHandle(hinternet); - CloseHandle(hfile); - return S_OK; - } - } - - if (!WriteFile(hfile, buffer, sz, &written, NULL)) { - InternetCloseHandle(hreq); - InternetCloseHandle(hcon); - InternetCloseHandle(hinternet); - - CloseHandle(hfile); - return E_OUTOFMEMORY; - } - } - - if (lpfnCB) { - if (IBindStatusCallback_OnProgress(lpfnCB, total, total_size != 0xFFFFFFFF ? total_size : 0, - BINDSTATUS_ENDDOWNLOADDATA, szURL) == E_ABORT) { - InternetCloseHandle(hreq); - InternetCloseHandle(hcon); - InternetCloseHandle(hinternet); - CloseHandle(hfile); - return S_OK; - } - } - - InternetCloseHandle(hreq); - InternetCloseHandle(hcon); - InternetCloseHandle(hinternet); - - CloseHandle(hfile); - - return S_OK; -} +HRESULT WINAPI MkParseDisplayNameEx(IBindCtx *pbc, LPCWSTR szDisplayName, ULONG *pchEaten, LPMONIKER *ppmk) +{ + TRACE("(%p %s %p %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk); + + if(is_registered_protocol(szDisplayName)) { + HRESULT hres; + + hres = CreateURLMoniker(NULL, szDisplayName, ppmk); + if(SUCCEEDED(hres)) { + *pchEaten = strlenW(szDisplayName); + return hres; + } + } + + return MkParseDisplayName(pbc, szDisplayName, pchEaten, ppmk); +} +
/*********************************************************************** * URLDownloadToCacheFileA (URLMON.@)
Modified: trunk/reactos/dll/win32/urlmon/umstream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/umstream.c... ============================================================================== --- trunk/reactos/dll/win32/urlmon/umstream.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/umstream.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -221,7 +221,7 @@ if ( !pcbRead) pcbRead = &dwBytesRead;
- if ( ! ReadFile( This->handle, pv, cb, (LPDWORD)pcbRead, NULL ) ) + if ( ! ReadFile( This->handle, pv, cb, pcbRead, NULL ) ) return S_FALSE;
if (!*pcbRead)
Modified: trunk/reactos/dll/win32/urlmon/urlmon.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon.rbu... ============================================================================== --- trunk/reactos/dll/win32/urlmon/urlmon.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/urlmon.rbuild [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -9,18 +9,10 @@ <define name="__WINESRC__" /> <define name="WINVER">0x600</define> <define name="_WIN32_WINNT">0x600</define> - <library>wine</library> - <library>ole32</library> - <library>shlwapi</library> - <library>wininet</library> - <library>user32</library> - <library>advapi32</library> - <library>kernel32</library> - <library>ntdll</library> - <library>uuid</library> <file>bindctx.c</file> <file>binding.c</file> <file>bindprot.c</file> + <file>download.c</file> <file>file.c</file> <file>format.c</file> <file>ftp.c</file> @@ -35,5 +27,14 @@ <file>urlmon_main.c</file> <file>rsrc.rc</file> <file>urlmon.spec</file> + <library>wine</library> + <library>ole32</library> + <library>shlwapi</library> + <library>wininet</library> + <library>user32</library> + <library>advapi32</library> + <library>kernel32</library> + <library>uuid</library> + <library>ntdll</library> </module> </group>
Modified: trunk/reactos/dll/win32/urlmon/urlmon.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon.spe... ============================================================================== --- trunk/reactos/dll/win32/urlmon/urlmon.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/urlmon.spec [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -21,7 +21,7 @@ @ stdcall CoInternetQueryInfo(ptr long long ptr long ptr long) @ stub CompareSecurityIds @ stub CopyBindInfo -@ stub CopyStgMedium +@ stdcall CopyStgMedium(ptr ptr) @ stdcall CreateAsyncBindCtx(long ptr ptr ptr) @ stdcall CreateAsyncBindCtxEx(ptr long ptr ptr ptr long) @ stdcall CreateFormatEnumerator(long ptr ptr) @@ -53,7 +53,7 @@ @ stub IsLoggingEnabledA @ stub IsLoggingEnabledW @ stdcall IsValidURL(ptr wstr long) -@ stdcall MkParseDisplayNameEx(ptr ptr ptr ptr) ole32.MkParseDisplayName +@ stdcall MkParseDisplayNameEx(ptr wstr ptr ptr) @ stdcall ObtainUserAgentString(long str ptr) @ stub PrivateCoInstall @ stdcall RegisterBindStatusCallback(ptr ptr ptr long)
Modified: trunk/reactos/dll/win32/urlmon/urlmon_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon_mai... ============================================================================== --- trunk/reactos/dll/win32/urlmon/urlmon_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/urlmon_main.c [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -210,31 +210,14 @@
static void init_session(BOOL init) { - IInternetSession *session; int i;
- CoInternetGetSession(0, &session, 0); - for(i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) { - if(object_creation[i].protocol) { - if(init) - { - IInternetSession_RegisterNameSpace(session, object_creation[i].cf, - object_creation[i].clsid, object_creation[i].protocol, 0, NULL, 0); - /* make sure that the AddRef on the class factory doesn't keep us loaded */ - URLMON_UnlockModule(); - } - else - { - /* make sure that the Release on the class factory doesn't unload us */ - URLMON_LockModule(); - IInternetSession_UnregisterNameSpace(session, object_creation[i].cf, - object_creation[i].protocol); - } - } - } - - IInternetSession_Release(session); + + if(object_creation[i].protocol) + register_urlmon_namespace(object_creation[i].cf, object_creation[i].clsid, + object_creation[i].protocol, init); + } }
/******************************************************************************* @@ -398,12 +381,51 @@ if(offsetof(BINDINFO, szExtraInfo) < size) CoTaskMemFree(pbindinfo->szCustomVerb);
- if(pbindinfo->pUnk && offsetof(BINDINFO, pUnk) < size) IUnknown_Release(pbindinfo->pUnk);
memset(pbindinfo, 0, size); pbindinfo->cbSize = size; +} + +/*********************************************************************** + * CopyStgMedium (URLMON.@) + */ +HRESULT WINAPI CopyStgMedium(const STGMEDIUM *src, STGMEDIUM *dst) +{ + TRACE("(%p %p)\n", src, dst); + + if(!src || !dst) + return E_POINTER; + + *dst = *src; + + switch(dst->tymed) { + case TYMED_NULL: + break; + case TYMED_FILE: + if(src->u.lpszFileName && !src->pUnkForRelease) { + DWORD size = (strlenW(src->u.lpszFileName)+1)*sizeof(WCHAR); + dst->u.lpszFileName = CoTaskMemAlloc(size); + memcpy(dst->u.lpszFileName, src->u.lpszFileName, size); + } + break; + case TYMED_ISTREAM: + if(dst->u.pstm) + IStream_AddRef(dst->u.pstm); + break; + case TYMED_ISTORAGE: + if(dst->u.pstg) + IStorage_AddRef(dst->u.pstg); + break; + default: + FIXME("Unimplemented tymed %d\n", src->tymed); + } + + if(dst->pUnkForRelease) + IUnknown_AddRef(dst->pUnkForRelease); + + return S_OK; }
static BOOL text_richtext_filter(const BYTE *b, DWORD size) @@ -430,6 +452,12 @@ return FALSE; }
+static BOOL audio_basic_filter(const BYTE *b, DWORD size) +{ + return size > 4 + && b[0] == '.' && b[1] == 's' && b[2] == 'n' && b[3] == 'd'; +} + static BOOL audio_wav_filter(const BYTE *b, DWORD size) { return size > 12 @@ -574,6 +602,7 @@
static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0}; static const WCHAR wszTextRichtext[] = {'t','e','x','t','/','r','i','c','h','t','e','x','t',0}; + static const WCHAR wszAudioBasic[] = {'a','u','d','i','o','/','b','a','s','i','c',0}; static const WCHAR wszAudioWav[] = {'a','u','d','i','o','/','w','a','v',0}; static const WCHAR wszImageGif[] = {'i','m','a','g','e','/','g','i','f',0}; static const WCHAR wszImagePjpeg[] = {'i','m','a','g','e','/','p','j','p','e','g',0}; @@ -604,16 +633,25 @@ } mime_filters[] = { {wszTextHtml, text_html_filter}, {wszTextRichtext, text_richtext_filter}, + /* {wszAudioXAiff, audio_xaiff_filter}, */ + {wszAudioBasic, audio_basic_filter}, {wszAudioWav, audio_wav_filter}, {wszImageGif, image_gif_filter}, {wszImagePjpeg, image_pjpeg_filter}, {wszImageTiff, image_tiff_filter}, {wszImageXPng, image_xpng_filter}, + /* {wszImageXBitmap, image_xbitmap_filter}, */ {wszImageBmp, image_bmp_filter}, + /* {wszImageXJg, image_xjg_filter}, */ + /* {wszImageXEmf, image_xemf_filter}, */ + /* {wszImageXWmf, image_xwmf_filter}, */ {wszVideoAvi, video_avi_filter}, {wszVideoMpeg, video_mpeg_filter}, {wszAppPostscript, application_postscript_filter}, + /* {wszAppBase64, application_base64_filter}, */ + /* {wszAppMacbinhex40, application_macbinhex40_filter}, */ {wszAppPdf, application_pdf_filter}, + /* {wszAppXCompressed, application_xcompressed_filter}, */ {wszAppXZip, application_xzip_filter}, {wszAppXGzip, application_xgzip_filter}, {wszAppJava, application_java_filter},
Modified: trunk/reactos/dll/win32/urlmon/urlmon_main.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon_mai... ============================================================================== --- trunk/reactos/dll/win32/urlmon/urlmon_main.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/urlmon_main.h [iso-8859-1] Fri Apr 4 09:41:46 2008 @@ -67,6 +67,8 @@
IInternetProtocolInfo *get_protocol_info(LPCWSTR url); HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret); +BOOL is_registered_protocol(LPCWSTR); +void register_urlmon_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL);
HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv); HRESULT bind_to_object(IMoniker *mon, LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv); @@ -109,4 +111,17 @@ return ret; }
+static inline LPWSTR heap_strdupAtoW(const char *str) +{ + LPWSTR ret = NULL; + + if(str) { + DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = heap_alloc(len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + } + + return ret; +} + #endif /* __WINE_URLMON_MAIN_H */