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.…
==============================================================================
--- 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?re…
==============================================================================
--- 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?re…
==============================================================================
--- 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=…
==============================================================================
--- 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?…
==============================================================================
--- 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?re…
==============================================================================
--- 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.…
==============================================================================
--- 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.rb…
==============================================================================
--- 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.sp…
==============================================================================
--- 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_ma…
==============================================================================
--- 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_ma…
==============================================================================
--- 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 */