Autosyncing with Wine HEAD

svn path=/trunk/; revision=31796
This commit is contained in:
The Wine Synchronizer 2008-01-14 16:39:00 +00:00
parent 183e6521c1
commit 7c79f1411f
17 changed files with 840 additions and 484 deletions

View file

@ -16,23 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -132,7 +119,7 @@ static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
if(This->authenticate)
IAuthenticate_Release(This->authenticate);
IBindStatusCallback_Release(This->callback);
urlmon_free(This);
heap_free(This);
}
return ref;
@ -455,7 +442,7 @@ static const IAuthenticateVtbl BSCAuthenticateVtbl = {
static IBindStatusCallback *create_bsc(IBindStatusCallback *bsc)
{
BindStatusCallback *ret = urlmon_alloc_zero(sizeof(BindStatusCallback));
BindStatusCallback *ret = heap_alloc_zero(sizeof(BindStatusCallback));
ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl;
ret->lpServiceProviderVtbl = &BSCServiceProviderVtbl;
@ -640,7 +627,7 @@ static ULONG WINAPI AsyncBindCtx_Release(IBindCtx *iface)
if(!ref) {
IBindCtx_Release(This->bindctx);
urlmon_free(This);
heap_free(This);
}
return ref;
@ -718,13 +705,13 @@ static HRESULT WINAPI AsyncBindCtx_GetObjectParam(IBindCtx* iface, LPOLESTR pszk
return IBindCtx_GetObjectParam(This->bindctx, pszkey, punk);
}
static HRESULT WINAPI AsyncBindCtx_RevokeObjectParam(IBindCtx *iface, LPOLESTR ppenum)
static HRESULT WINAPI AsyncBindCtx_RevokeObjectParam(IBindCtx *iface, LPOLESTR pszkey)
{
AsyncBindCtx *This = BINDCTX_THIS(iface);
TRACE("(%p)->(%p)\n", This, ppenum);
TRACE("(%p)->(%s)\n", This, debugstr_w(pszkey));
return IBindCtx_RevokeObjectParam(This->bindctx, ppenum);
return IBindCtx_RevokeObjectParam(This->bindctx, pszkey);
}
static HRESULT WINAPI AsyncBindCtx_EnumObjectParam(IBindCtx *iface, IEnumString **pszkey)
@ -833,11 +820,16 @@ HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options,
if(reserved)
WARN("reserved=%d\n", reserved);
hres = CreateBindCtx(0, &bindctx);
if(FAILED(hres))
return hres;
if(ibind) {
IBindCtx_AddRef(ibind);
bindctx = ibind;
}else {
hres = CreateBindCtx(0, &bindctx);
if(FAILED(hres))
return hres;
}
ret = urlmon_alloc(sizeof(AsyncBindCtx));
ret = heap_alloc(sizeof(AsyncBindCtx));
ret->lpBindCtxVtbl = &AsyncBindCtxVtbl;
ret->ref = 1;

View file

@ -16,24 +16,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "winreg.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
static WCHAR cbinding_contextW[] = {'C','B','i','n','d','i','n','g',' ','C','o','n','t','e','x','t',0};
static WCHAR bscb_holderW[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
typedef struct Binding Binding;
struct _task_header_t;
@ -64,6 +56,10 @@ typedef enum {
END_DOWNLOAD
} download_state_t;
#define BINDING_LOCKED 0x0001
#define BINDING_STOPPED 0x0002
#define BINDING_OBJAVAIL 0x0004
struct Binding {
const IBindingVtbl *lpBindingVtbl;
const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl;
@ -79,12 +75,19 @@ struct Binding {
BINDINFO bindinfo;
DWORD bindf;
BOOL to_object;
LPWSTR mime;
UINT clipboard_format;
LPWSTR url;
IID iid;
BOOL report_mime;
DWORD continue_call;
BOOL request_locked;
DWORD state;
HRESULT hres;
download_state_t download_state;
IUnknown *obj;
IMoniker *mon;
IBindCtx *bctx;
DWORD apartment_thread;
HWND notif_hwnd;
@ -251,6 +254,212 @@ static void dump_BINDINFO(BINDINFO *bi)
);
}
static void set_binding_mime(Binding *binding, LPCWSTR mime)
{
EnterCriticalSection(&binding->section);
if(binding->report_mime) {
heap_free(binding->mime);
binding->mime = heap_strdupW(mime);
}
LeaveCriticalSection(&binding->section);
}
static void handle_mime_available(Binding *binding, BOOL verify)
{
BOOL report_mime;
EnterCriticalSection(&binding->section);
report_mime = binding->report_mime;
binding->report_mime = FALSE;
LeaveCriticalSection(&binding->section);
if(!report_mime)
return;
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);
heap_free(binding->mime);
binding->mime = heap_strdupW(mime);
CoTaskMemFree(mime);
}
IBindStatusCallback_OnProgress(binding->callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, binding->mime);
binding->clipboard_format = RegisterClipboardFormatW(binding->mime);
}
typedef struct {
task_header_t header;
BOOL verify;
} mime_available_task_t;
static void mime_available_proc(Binding *binding, task_header_t *t)
{
mime_available_task_t *task = (mime_available_task_t*)t;
handle_mime_available(binding, task->verify);
heap_free(task);
}
static void mime_available(Binding *This, LPCWSTR mime, BOOL verify)
{
if(mime)
set_binding_mime(This, mime);
if(GetCurrentThreadId() == This->apartment_thread) {
handle_mime_available(This, verify);
}else {
mime_available_task_t *task = heap_alloc(sizeof(task_header_t));
task->verify = verify;
push_task(This, &task->header, mime_available_proc);
}
}
static void stop_binding(Binding *binding, HRESULT hres, LPCWSTR str)
{
if(binding->state & BINDING_LOCKED) {
IInternetProtocol_UnlockRequest(binding->protocol);
binding->state &= ~BINDING_LOCKED;
}
if(!(binding->state & BINDING_STOPPED)) {
binding->state |= BINDING_STOPPED;
IBindStatusCallback_OnStopBinding(binding->callback, hres, str);
binding->hres = hres;
}
}
static LPWSTR get_mime_clsid(LPCWSTR mime, CLSID *clsid)
{
LPWSTR key_name, ret;
DWORD res, type, size;
HKEY hkey;
int len;
HRESULT hres;
static const WCHAR mime_keyW[] =
{'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\',
'C','o','n','t','e','n','t',' ','T','y','p','e','\\'};
static const WCHAR clsidW[] = {'C','L','S','I','D',0};
len = strlenW(mime)+1;
key_name = heap_alloc(sizeof(mime_keyW) + len*sizeof(WCHAR));
memcpy(key_name, mime_keyW, sizeof(mime_keyW));
strcpyW(key_name + sizeof(mime_keyW)/sizeof(WCHAR), mime);
res = RegOpenKeyW(HKEY_CLASSES_ROOT, key_name, &hkey);
heap_free(key_name);
if(res != ERROR_SUCCESS) {
WARN("Could not open MIME key: %x\n", res);
return NULL;
}
size = 50*sizeof(WCHAR);
ret = heap_alloc(size);
res = RegQueryValueExW(hkey, clsidW, NULL, &type, (LPBYTE)ret, &size);
RegCloseKey(hkey);
if(res != ERROR_SUCCESS) {
WARN("Could not get CLSID: %08x\n", res);
heap_free(ret);
return NULL;
}
hres = CLSIDFromString(ret, clsid);
if(FAILED(hres)) {
WARN("Could not parse CLSID: %08x\n", hres);
heap_free(ret);
return NULL;
}
return ret;
}
static void load_doc_mon(Binding *binding, IPersistMoniker *persist)
{
IBindCtx *bctx;
HRESULT hres;
hres = CreateAsyncBindCtxEx(binding->bctx, 0, NULL, NULL, &bctx, 0);
if(FAILED(hres)) {
WARN("CreateAsyncBindCtxEx failed: %08x\n", hres);
return;
}
IBindCtx_RevokeObjectParam(bctx, bscb_holderW);
IBindCtx_RegisterObjectParam(bctx, cbinding_contextW, (IUnknown*)BINDING(binding));
hres = IPersistMoniker_Load(persist, binding->download_state == END_DOWNLOAD, binding->mon, bctx, 0x12);
IBindCtx_RevokeObjectParam(bctx, cbinding_contextW);
IBindCtx_Release(bctx);
if(FAILED(hres))
FIXME("Load failed: %08x\n", hres);
}
static void create_object(Binding *binding)
{
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,
&binding->iid, (void**)&binding->obj);
if(FAILED(hres))
FIXME("CoCreateInstance failed: %08x\n", hres);
binding->state |= BINDING_OBJAVAIL;
hres = IUnknown_QueryInterface(binding->obj, &IID_IPersistMoniker, (void**)&persist);
if(SUCCEEDED(hres)) {
IMonikerProp *prop;
hres = IPersistMoniker_QueryInterface(persist, &IID_IMonikerProp, (void**)&prop);
if(SUCCEEDED(hres)) {
IMonikerProp_PutProperty(prop, MIMETYPEPROP, binding->mime);
IMonikerProp_PutProperty(prop, CLASSIDPROP, clsid_str);
IMonikerProp_Release(prop);
}
load_doc_mon(binding, persist);
IPersistMoniker_Release(persist);
}else {
FIXME("Could not get IPersistMoniker: %08x\n", hres);
/* FIXME: Try query IPersistFile */
}
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);
}
#define STREAM_THIS(iface) DEFINE_THIS(ProtocolStream, Stream, iface)
static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface,
@ -299,7 +508,7 @@ static ULONG WINAPI ProtocolStream_Release(IStream *iface)
if(!ref) {
IInternetProtocol_Release(This->protocol);
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -451,7 +660,7 @@ static const IStreamVtbl ProtocolStreamVtbl = {
static ProtocolStream *create_stream(IInternetProtocol *protocol)
{
ProtocolStream *ret = urlmon_alloc(sizeof(ProtocolStream));
ProtocolStream *ret = heap_alloc(sizeof(ProtocolStream));
ret->lpStreamVtbl = &ProtocolStreamVtbl;
ret->ref = 1;
@ -519,6 +728,8 @@ static ULONG WINAPI Binding_Release(IBinding *iface)
if(!ref) {
if (This->notif_hwnd)
DestroyWindow( This->notif_hwnd );
if(This->mon)
IMoniker_Release(This->mon);
if(This->callback)
IBindStatusCallback_Release(This->callback);
if(This->protocol)
@ -527,14 +738,18 @@ static ULONG WINAPI Binding_Release(IBinding *iface)
IServiceProvider_Release(This->service_provider);
if(This->stream)
IStream_Release(STREAM(This->stream));
if(This->obj)
IUnknown_Release(This->obj);
if(This->bctx)
IBindCtx_Release(This->bctx);
ReleaseBindInfo(&This->bindinfo);
This->section.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->section);
urlmon_free(This->mime);
urlmon_free(This->url);
heap_free(This->mime);
heap_free(This->url);
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -585,6 +800,25 @@ static HRESULT WINAPI Binding_GetBindResult(IBinding *iface, CLSID *pclsidProtoc
return E_NOTIMPL;
}
static Binding *get_bctx_binding(IBindCtx *bctx)
{
IBinding *binding;
IUnknown *unk;
HRESULT hres;
hres = IBindCtx_GetObjectParam(bctx, cbinding_contextW, &unk);
if(FAILED(hres))
return NULL;
hres = IUnknown_QueryInterface(unk, &IID_IBinding, (void*)&binding);
IUnknown_Release(unk);
if(FAILED(hres))
return NULL;
/* FIXME!!! */
return BINDING_THIS(binding);
}
#undef BINDING_THIS
static const IBindingVtbl BindingVtbl = {
@ -631,7 +865,7 @@ static void switch_proc(Binding *binding, task_header_t *t)
IInternetProtocol_Continue(binding->protocol, &task->data);
urlmon_free(task);
heap_free(task);
}
static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface,
@ -642,7 +876,7 @@ static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface,
TRACE("(%p)->(%p)\n", This, pProtocolData);
task = urlmon_alloc(sizeof(switch_task_t));
task = heap_alloc(sizeof(switch_task_t));
memcpy(&task->data, pProtocolData, sizeof(PROTOCOLDATA));
push_task(This, &task->header, switch_proc);
@ -670,8 +904,8 @@ static void on_progress_proc(Binding *binding, task_header_t *t)
IBindStatusCallback_OnProgress(binding->callback, task->progress,
task->progress_max, task->status_code, task->status_text);
urlmon_free(task->status_text);
urlmon_free(task);
heap_free(task->status_text);
heap_free(task);
}
static void on_progress(Binding *This, ULONG progress, ULONG progress_max,
@ -685,7 +919,7 @@ static void on_progress(Binding *This, ULONG progress, ULONG progress_max,
return;
}
task = urlmon_alloc(sizeof(on_progress_task_t));
task = heap_alloc(sizeof(on_progress_task_t));
task->progress = progress;
task->progress_max = progress_max;
@ -694,7 +928,7 @@ static void on_progress(Binding *This, ULONG progress, ULONG progress_max,
if(status_text) {
DWORD size = (strlenW(status_text)+1)*sizeof(WCHAR);
task->status_text = urlmon_alloc(size);
task->status_text = heap_alloc(size);
memcpy(task->status_text, status_text, size);
}else {
task->status_text = NULL;
@ -725,18 +959,16 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink
case BINDSTATUS_BEGINDOWNLOADDATA:
fill_stream_buffer(This->stream);
break;
case BINDSTATUS_MIMETYPEAVAILABLE: {
int len = strlenW(szStatusText)+1;
This->mime = urlmon_alloc(len*sizeof(WCHAR));
memcpy(This->mime, szStatusText, len*sizeof(WCHAR));
case BINDSTATUS_MIMETYPEAVAILABLE:
set_binding_mime(This, szStatusText);
break;
}
case BINDSTATUS_SENDINGREQUEST:
on_progress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, szStatusText);
break;
case BINDSTATUS_PROTOCOLCLASSID:
break;
case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
This->report_mime = FALSE;
on_progress(This, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, szStatusText);
mime_available(This, szStatusText, FALSE);
break;
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
break;
@ -762,21 +994,10 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
return;
if(GetCurrentThreadId() != This->apartment_thread)
FIXME("called from worked hread\n");
FIXME("called from worker thread\n");
if(This->report_mime) {
LPWSTR mime;
This->report_mime = FALSE;
fill_stream_buffer(This->stream);
FindMimeFromData(NULL, This->url, This->stream->buf,
min(This->stream->buf_size, 255), This->mime, 0, &mime, 0);
IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
BINDSTATUS_MIMETYPEAVAILABLE, mime);
}
if(This->report_mime)
mime_available(This, NULL, TRUE);
if(This->download_state == BEFORE_DOWNLOAD) {
fill_stream_buffer(This->stream);
@ -796,16 +1017,22 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
BINDSTATUS_DOWNLOADINGDATA, This->url);
}
if(!This->request_locked) {
HRESULT hres = IInternetProtocol_LockRequest(This->protocol, 0);
This->request_locked = SUCCEEDED(hres);
}
if(This->to_object) {
if(!(This->state & BINDING_OBJAVAIL))
create_object(This);
}else {
if(!(This->state & BINDING_LOCKED)) {
HRESULT hres = IInternetProtocol_LockRequest(This->protocol, 0);
if(SUCCEEDED(hres))
This->state |= BINDING_LOCKED;
}
IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress,
&formatetc, &This->stgmed);
formatetc.cfFormat = This->clipboard_format;
IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress,
&formatetc, &This->stgmed);
if(This->download_state == END_DOWNLOAD) {
IBindStatusCallback_OnStopBinding(This->callback, S_OK, NULL);
if(This->download_state == END_DOWNLOAD)
stop_binding(This, S_OK, NULL);
}
}
@ -822,7 +1049,7 @@ static void report_data_proc(Binding *binding, task_header_t *t)
report_data(binding, task->bscf, task->progress, task->progress_max);
urlmon_free(task);
heap_free(task);
}
static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface,
@ -836,7 +1063,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *ifa
FIXME("called from worked hread\n");
if(This->continue_call) {
report_data_task_t *task = urlmon_alloc(sizeof(report_data_task_t));
report_data_task_t *task = heap_alloc(sizeof(report_data_task_t));
task->bscf = grfBSCF;
task->progress = ulProgress;
task->progress_max = ulProgressMax;
@ -849,16 +1076,23 @@ static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *ifa
return S_OK;
}
typedef struct {
task_header_t header;
HRESULT hres;
LPWSTR str;
} report_result_task_t;
static void report_result_proc(Binding *binding, task_header_t *t)
{
report_result_task_t *task = (report_result_task_t*)t;
IInternetProtocol_Terminate(binding->protocol, 0);
if(binding->request_locked) {
IInternetProtocol_UnlockRequest(binding->protocol);
binding->request_locked = FALSE;
}
stop_binding(binding, task->hres, task->str);
urlmon_free(t);
heap_free(task->str);
heap_free(task);
}
static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
@ -870,9 +1104,14 @@ static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *i
if(GetCurrentThreadId() == This->apartment_thread && !This->continue_call) {
IInternetProtocol_Terminate(This->protocol, 0);
stop_binding(This, hrResult, szResult);
}else {
task_header_t *task = urlmon_alloc(sizeof(task_header_t));
push_task(This, task, report_result_proc);
report_result_task_t *task = heap_alloc(sizeof(report_result_task_t));
task->hres = hrResult;
task->str = heap_strdupW(szResult);
push_task(This, &task->header, report_result_proc);
}
return S_OK;
@ -1038,9 +1277,7 @@ static HRESULT get_callback(IBindCtx *pbc, IBindStatusCallback **callback)
IUnknown *unk;
HRESULT hres;
static WCHAR wszBSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
hres = IBindCtx_GetObjectParam(pbc, wszBSCBHolder, &unk);
hres = IBindCtx_GetObjectParam(pbc, bscb_holderW, &unk);
if(SUCCEEDED(hres)) {
hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)callback);
IUnknown_Release(unk);
@ -1049,33 +1286,6 @@ static HRESULT get_callback(IBindCtx *pbc, IBindStatusCallback **callback)
return SUCCEEDED(hres) ? S_OK : MK_E_SYNTAX;
}
static HRESULT get_protocol(Binding *This, LPCWSTR url)
{
IClassFactory *cf = NULL;
HRESULT hres;
hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IInternetProtocol,
(void**)&This->protocol);
if(SUCCEEDED(hres))
return S_OK;
if(This->service_provider) {
hres = IServiceProvider_QueryService(This->service_provider, &IID_IInternetProtocol,
&IID_IInternetProtocol, (void**)&This->protocol);
if(SUCCEEDED(hres))
return S_OK;
}
hres = get_protocol_handler(url, NULL, &cf);
if(FAILED(hres))
return hres;
hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&This->protocol);
IClassFactory_Release(cf);
return hres;
}
static BOOL is_urlmon_protocol(LPCWSTR url)
{
static const WCHAR wszCdl[] = {'c','d','l'};
@ -1110,20 +1320,20 @@ static BOOL is_urlmon_protocol(LPCWSTR url)
return FALSE;
}
static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding **binding)
static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, IBindCtx *pbc,
BOOL to_obj, REFIID riid, Binding **binding)
{
Binding *ret;
int len;
HRESULT hres;
if(!IsEqualGUID(&IID_IStream, riid)) {
if(!to_obj && !IsEqualGUID(&IID_IStream, riid)) {
FIXME("Unsupported riid %s\n", debugstr_guid(riid));
return E_NOTIMPL;
}
URLMON_LockModule();
ret = urlmon_alloc(sizeof(Binding));
ret = heap_alloc_zero(sizeof(Binding));
ret->lpBindingVtbl = &BindingVtbl;
ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
@ -1132,23 +1342,24 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding *
ret->ref = 1;
ret->callback = NULL;
ret->protocol = NULL;
ret->service_provider = NULL;
ret->stream = NULL;
ret->mime = NULL;
ret->url = NULL;
ret->to_object = to_obj;
ret->iid = *riid;
ret->apartment_thread = GetCurrentThreadId();
ret->notif_hwnd = get_notif_hwnd();
ret->report_mime = TRUE;
ret->continue_call = 0;
ret->request_locked = FALSE;
ret->report_mime = !binding_ctx;
ret->download_state = BEFORE_DOWNLOAD;
ret->task_queue_head = ret->task_queue_tail = NULL;
memset(&ret->bindinfo, 0, sizeof(BINDINFO));
if(to_obj) {
IBindCtx_AddRef(pbc);
ret->bctx = pbc;
}
if(mon) {
IMoniker_AddRef(mon);
ret->mon = mon;
}
ret->bindinfo.cbSize = sizeof(BINDINFO);
ret->bindf = 0;
InitializeCriticalSection(&ret->section);
ret->section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": Binding.section");
@ -1163,11 +1374,16 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding *
IBindStatusCallback_QueryInterface(ret->callback, &IID_IServiceProvider,
(void**)&ret->service_provider);
hres = get_protocol(ret, url);
if(FAILED(hres)) {
WARN("Could not get protocol handler\n");
IBinding_Release(BINDING(ret));
return hres;
if(binding_ctx) {
ret->protocol = binding_ctx->protocol;
IInternetProtocol_AddRef(ret->protocol);
}else {
hres = create_binding_protocol(url, TRUE, &ret->protocol);
if(FAILED(hres)) {
WARN("Could not get protocol handler\n");
IBinding_Release(BINDING(ret));
return hres;
}
}
hres = IBindStatusCallback_GetBindInfo(ret->callback, &ret->bindf, &ret->bindinfo);
@ -1177,18 +1393,25 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding *
return hres;
}
TRACE("bindf %08x\n", ret->bindf);
dump_BINDINFO(&ret->bindinfo);
ret->bindf |= BINDF_FROMURLMON;
if(to_obj)
ret->bindinfo.dwOptions |= 0x100000;
if(!is_urlmon_protocol(url))
ret->bindf |= BINDF_NEEDFILE;
len = strlenW(url)+1;
ret->url = urlmon_alloc(len*sizeof(WCHAR));
memcpy(ret->url, url, len*sizeof(WCHAR));
ret->url = heap_strdupW(url);
ret->stream = create_stream(ret->protocol);
if(binding_ctx) {
ret->stream = binding_ctx->stream;
IStream_AddRef(STREAM(ret->stream));
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 */
@ -1197,41 +1420,44 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding *
return S_OK;
}
HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
static HRESULT start_binding(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, IBindCtx *pbc,
BOOL to_obj, REFIID riid, Binding **ret)
{
Binding *binding = NULL;
HRESULT hres;
MSG msg;
*ppv = NULL;
hres = Binding_Create(url, pbc, riid, &binding);
hres = Binding_Create(mon, binding_ctx, url, pbc, to_obj, riid, &binding);
if(FAILED(hres))
return hres;
hres = IBindStatusCallback_OnStartBinding(binding->callback, 0, BINDING(binding));
if(FAILED(hres)) {
WARN("OnStartBinding failed: %08x\n", hres);
IBindStatusCallback_OnStopBinding(binding->callback, 0x800c0008, NULL);
stop_binding(binding, 0x800c0008, NULL);
IBinding_Release(BINDING(binding));
return hres;
}
hres = IInternetProtocol_Start(binding->protocol, url, PROTSINK(binding),
BINDINF(binding), 0, 0);
if(binding_ctx) {
set_binding_sink(binding->protocol, PROTSINK(binding));
report_data(binding, 0, 0, 0);
}else {
hres = IInternetProtocol_Start(binding->protocol, url, PROTSINK(binding),
BINDINF(binding), 0, 0);
if(FAILED(hres)) {
WARN("Start failed: %08x\n", hres);
TRACE("start ret %08x\n", hres);
IInternetProtocol_Terminate(binding->protocol, 0);
IBindStatusCallback_OnStopBinding(binding->callback, S_OK, NULL);
IBinding_Release(BINDING(binding));
if(FAILED(hres)) {
stop_binding(binding, hres, NULL);
IBinding_Release(BINDING(binding));
return hres;
return hres;
}
}
while(!(binding->bindf & BINDF_ASYNCHRONOUS) &&
binding->download_state != END_DOWNLOAD) {
!(binding->state & BINDING_STOPPED)) {
MsgWaitForMultipleObjects(0, NULL, FALSE, 5000, QS_POSTMESSAGE);
while (PeekMessageW(&msg, binding->notif_hwnd, WM_USER, WM_USER+117, PM_REMOVE|PM_NOYIELD)) {
TranslateMessage(&msg);
@ -1239,8 +1465,29 @@ HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
}
}
if(binding->stream->init_buf) {
if(binding->request_locked)
*ret = binding;
return S_OK;
}
HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
{
Binding *binding = NULL, *binding_ctx;
HRESULT hres;
*ppv = NULL;
binding_ctx = get_bctx_binding(pbc);
hres = start_binding(NULL, binding_ctx, url, pbc, FALSE, riid, &binding);
if(binding_ctx)
IBinding_Release(BINDING(binding_ctx));
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->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED))
IInternetProtocol_UnlockRequest(binding->protocol);
IStream_AddRef(STREAM(binding->stream));
@ -1255,3 +1502,29 @@ HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
return hres;
}
HRESULT bind_to_object(IMoniker *mon, LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
{
Binding *binding;
HRESULT hres;
*ppv = NULL;
hres = start_binding(mon, NULL, url, pbc, TRUE, riid, &binding);
if(FAILED(hres))
return hres;
if(binding->hres != S_OK) {
hres = SUCCEEDED(binding->hres) ? S_OK : binding->hres;
}else if(binding->bindf & BINDF_ASYNCHRONOUS) {
hres = MK_S_ASYNCHRONOUS;
}else {
*ppv = binding->obj;
IUnknown_AddRef(binding->obj);
hres = S_OK;
}
IBinding_Release(BINDING(binding));
return hres;
}

View file

@ -16,17 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -35,6 +25,7 @@ typedef struct {
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
const IInternetBindInfoVtbl *lpInternetBindInfoVtbl;
const IInternetPriorityVtbl *lpInternetPriorityVtbl;
const IServiceProviderVtbl *lpServiceProviderVtbl;
const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl;
LONG ref;
@ -42,13 +33,18 @@ typedef struct {
IInternetProtocol *protocol;
IInternetBindInfo *bind_info;
IInternetProtocolSink *protocol_sink;
IServiceProvider *service_provider;
LONG priority;
BOOL reported_result;
BOOL from_urlmon;
} BindProtocol;
#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
#define BINDINFO(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl)
#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
#define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
#define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl)
#define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocol, iface)
@ -76,7 +72,8 @@ static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocol *iface, REFI
}else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
FIXME("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
FIXME("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
*ppv = SERVPROV(This);
}else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) {
TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv);
*ppv = PROTSINK(This);
@ -111,10 +108,9 @@ static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface)
IInternetProtocol_Release(This->protocol);
if(This->bind_info)
IInternetBindInfo_Release(This->bind_info);
if(This->protocol_sink)
IInternetProtocolSink_Release(This->protocol_sink);
urlmon_free(This);
set_binding_sink(PROTOCOL(This), NULL);
heap_free(This);
URLMON_UnlockModule();
}
@ -157,16 +153,23 @@ static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
if(FAILED(hres))
return hres;
hres = IClassFactory_CreateInstance(cf, (IUnknown*)BINDINFO(This),
&IID_IUnknown, (void**)&unk);
IClassFactory_Release(cf);
if(FAILED(hres))
return hres;
if(This->from_urlmon) {
hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&protocol);
IClassFactory_Release(cf);
if(FAILED(hres))
return hres;
}else {
hres = IClassFactory_CreateInstance(cf, (IUnknown*)BINDINFO(This),
&IID_IUnknown, (void**)&unk);
IClassFactory_Release(cf);
if(FAILED(hres))
return hres;
hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&protocol);
IUnknown_Release(unk);
if(FAILED(hres))
return hres;
hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&protocol);
IUnknown_Release(unk);
if(FAILED(hres))
return hres;
}
}
StringFromCLSID(&clsid, &clsid_str);
@ -178,8 +181,7 @@ static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
IInternetBindInfo_AddRef(pOIBindInfo);
This->bind_info = pOIBindInfo;
IInternetProtocolSink_AddRef(pOIProtSink);
This->protocol_sink = pOIProtSink;
set_binding_sink(PROTOCOL(This), pOIProtSink);
hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority);
if(SUCCEEDED(hres)) {
@ -193,8 +195,10 @@ static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
static HRESULT WINAPI BindProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
{
BindProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)->(%p)\n", This, pProtocolData);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, pProtocolData);
return IInternetProtocol_Continue(This->protocol, pProtocolData);
}
static HRESULT WINAPI BindProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
@ -211,7 +215,18 @@ static HRESULT WINAPI BindProtocol_Terminate(IInternetProtocol *iface, DWORD dwO
TRACE("(%p)->(%08x)\n", This, dwOptions);
if(!This->reported_result)
return E_FAIL;
IInternetProtocol_Terminate(This->protocol, 0);
set_binding_sink(PROTOCOL(This), NULL);
if(This->bind_info) {
IInternetBindInfo_Release(This->bind_info);
This->bind_info = NULL;
}
return S_OK;
}
@ -255,15 +270,38 @@ static HRESULT WINAPI BindProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER
static HRESULT WINAPI BindProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
BindProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)->(%08x)\n", This, dwOptions);
return E_NOTIMPL;
TRACE("(%p)->(%08x)\n", This, dwOptions);
return IInternetProtocol_LockRequest(This->protocol, dwOptions);
}
static HRESULT WINAPI BindProtocol_UnlockRequest(IInternetProtocol *iface)
{
BindProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
TRACE("(%p)\n", This);
return IInternetProtocol_UnlockRequest(This->protocol);
}
void set_binding_sink(IInternetProtocol *bind_protocol, IInternetProtocolSink *sink)
{
BindProtocol *This = PROTOCOL_THIS(bind_protocol);
IInternetProtocolSink *prev_sink;
IServiceProvider *service_provider = NULL;
if(sink)
IInternetProtocolSink_AddRef(sink);
prev_sink = InterlockedExchangePointer((void**)&This->protocol_sink, sink);
if(prev_sink)
IInternetProtocolSink_Release(prev_sink);
if(sink)
IInternetProtocolSink_QueryInterface(sink, &IID_IServiceProvider, (void**)&service_provider);
service_provider = InterlockedExchangePointer((void**)&This->service_provider, service_provider);
if(service_provider)
IServiceProvider_Release(service_provider);
}
#undef PROTOCOL_THIS
@ -327,8 +365,10 @@ static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface,
ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched)
{
BindProtocol *This = BINDINFO_THIS(iface);
FIXME("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
return E_NOTIMPL;
TRACE("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched);
return IInternetBindInfo_GetBindString(This->bind_info, ulStringType, ppwzStr, cEl, pcElFetched);
}
#undef BINDFO_THIS
@ -395,34 +435,44 @@ static const IInternetPriorityVtbl InternetPriorityVtbl = {
#define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocolSink, iface)
static HRESULT WINAPI InternetProtocolSink_QueryInterface(IInternetProtocolSink *iface,
static HRESULT WINAPI BPInternetProtocolSink_QueryInterface(IInternetProtocolSink *iface,
REFIID riid, void **ppv)
{
BindProtocol *This = PROTSINK_THIS(iface);
return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
}
static ULONG WINAPI InternetProtocolSink_AddRef(IInternetProtocolSink *iface)
static ULONG WINAPI BPInternetProtocolSink_AddRef(IInternetProtocolSink *iface)
{
BindProtocol *This = PROTSINK_THIS(iface);
return IInternetProtocol_AddRef(PROTOCOL(This));
}
static ULONG WINAPI InternetProtocolSink_Release(IInternetProtocolSink *iface)
static ULONG WINAPI BPInternetProtocolSink_Release(IInternetProtocolSink *iface)
{
BindProtocol *This = PROTSINK_THIS(iface);
return IInternetProtocol_Release(PROTOCOL(This));
}
static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface,
static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface,
PROTOCOLDATA *pProtocolData)
{
BindProtocol *This = PROTSINK_THIS(iface);
FIXME("(%p)->(%p)\n", This, pProtocolData);
return E_NOTIMPL;
TRACE("(%p)->(%p)\n", This, pProtocolData);
TRACE("flags %x state %x data %p cb %u\n", pProtocolData->grfFlags, pProtocolData->dwState,
pProtocolData->pData, pProtocolData->cbData);
if(!This->protocol_sink) {
IInternetProtocol_Continue(This->protocol, pProtocolData);
return S_OK;
}
return IInternetProtocolSink_Switch(This->protocol_sink, pProtocolData);
}
static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface,
ULONG ulStatusCode, LPCWSTR szStatusText)
{
BindProtocol *This = PROTSINK_THIS(iface);
@ -430,15 +480,24 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink
TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText));
switch(ulStatusCode) {
case BINDSTATUS_FINDINGRESOURCE:
case BINDSTATUS_CONNECTING:
case BINDSTATUS_BEGINDOWNLOADDATA:
case BINDSTATUS_SENDINGREQUEST:
return IInternetProtocolSink_ReportProgress(This->protocol_sink,
ulStatusCode, NULL);
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
case BINDSTATUS_DIRECTBIND:
case BINDSTATUS_MIMETYPEAVAILABLE:
if(!This->protocol_sink)
return S_OK;
return IInternetProtocolSink_ReportProgress(This->protocol_sink,
ulStatusCode, szStatusText);
case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
if(!This->protocol_sink)
return S_OK;
return IInternetProtocolSink_ReportProgress(This->protocol_sink,
BINDSTATUS_MIMETYPEAVAILABLE, szStatusText);
This->from_urlmon ? BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE,
szStatusText);
default:
FIXME("unsupported ulStatusCode %u\n", ulStatusCode);
}
@ -446,52 +505,101 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink
return E_NOTIMPL;
}
static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface,
static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *iface,
DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
BindProtocol *This = PROTSINK_THIS(iface);
TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
return S_OK;
if(!This->protocol_sink)
return S_OK;
return IInternetProtocolSink_ReportData(This->protocol_sink, grfBSCF, ulProgress, ulProgressMax);
}
static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink *iface,
HRESULT hrResult, DWORD dwError, LPCWSTR szResult)
{
BindProtocol *This = PROTSINK_THIS(iface);
TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
if(!This->protocol_sink)
return E_FAIL;
This->reported_result = TRUE;
return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult);
}
#undef PROTSINK_THIS
static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = {
InternetProtocolSink_QueryInterface,
InternetProtocolSink_AddRef,
InternetProtocolSink_Release,
InternetProtocolSink_Switch,
InternetProtocolSink_ReportProgress,
InternetProtocolSink_ReportData,
InternetProtocolSink_ReportResult
BPInternetProtocolSink_QueryInterface,
BPInternetProtocolSink_AddRef,
BPInternetProtocolSink_Release,
BPInternetProtocolSink_Switch,
BPInternetProtocolSink_ReportProgress,
BPInternetProtocolSink_ReportData,
BPInternetProtocolSink_ReportResult
};
HRESULT create_binding_protocol(LPCWSTR url, IInternetProtocol **protocol)
#define SERVPROV_THIS(iface) DEFINE_THIS(BindProtocol, ServiceProvider, iface)
static HRESULT WINAPI BPServiceProvider_QueryInterface(IServiceProvider *iface,
REFIID riid, void **ppv)
{
BindProtocol *ret = urlmon_alloc(sizeof(BindProtocol));
BindProtocol *This = SERVPROV_THIS(iface);
return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
}
static ULONG WINAPI BPServiceProvider_AddRef(IServiceProvider *iface)
{
BindProtocol *This = SERVPROV_THIS(iface);
return IInternetProtocol_AddRef(PROTOCOL(This));
}
static ULONG WINAPI BPServiceProvider_Release(IServiceProvider *iface)
{
BindProtocol *This = SERVPROV_THIS(iface);
return IInternetProtocol_Release(PROTOCOL(This));
}
static HRESULT WINAPI BPServiceProvider_QueryService(IServiceProvider *iface,
REFGUID guidService, REFIID riid, void **ppv)
{
BindProtocol *This = SERVPROV_THIS(iface);
TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
if(!This->service_provider)
return E_NOINTERFACE;
return IServiceProvider_QueryService(This->service_provider, guidService, riid, ppv);
}
#undef SERVPROV_THIS
static const IServiceProviderVtbl ServiceProviderVtbl = {
BPServiceProvider_QueryInterface,
BPServiceProvider_AddRef,
BPServiceProvider_Release,
BPServiceProvider_QueryService
};
HRESULT create_binding_protocol(LPCWSTR url, BOOL from_urlmon, IInternetProtocol **protocol)
{
BindProtocol *ret = heap_alloc_zero(sizeof(BindProtocol));
ret->lpInternetProtocolVtbl = &BindProtocolVtbl;
ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl;
ret->lpInternetPriorityVtbl = &InternetPriorityVtbl;
ret->lpServiceProviderVtbl = &ServiceProviderVtbl;
ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl;
ret->ref = 1;
ret->protocol = NULL;
ret->bind_info = NULL;
ret->protocol_sink = NULL;
ret->priority = 0;
ret->from_urlmon = from_urlmon;
URLMON_LockModule();

View file

@ -16,17 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -92,7 +82,7 @@ static ULONG WINAPI FileProtocol_Release(IInternetProtocol *iface)
if(!ref) {
if(This->file)
CloseHandle(This->file);
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -135,10 +125,10 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
return MK_E_SYNTAX;
len = lstrlenW(szUrl)+16;
url = urlmon_alloc(len*sizeof(WCHAR));
url = heap_alloc(len*sizeof(WCHAR));
hres = CoInternetParseUrl(szUrl, PARSE_ENCODE, 0, url, len, &len, 0);
if(FAILED(hres)) {
urlmon_free(url);
heap_free(url);
return hres;
}
@ -163,7 +153,7 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
This->file = NULL;
IInternetProtocolSink_ReportResult(pOIProtSink, INET_E_RESOURCE_NOT_FOUND,
GetLastError(), NULL);
urlmon_free(url);
heap_free(url);
return INET_E_RESOURCE_NOT_FOUND;
}
@ -180,7 +170,7 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
}
}
urlmon_free(url);
heap_free(url);
if(GetFileSizeEx(This->file, &size))
IInternetProtocolSink_ReportData(pOIProtSink,
@ -353,7 +343,7 @@ HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
URLMON_LockModule();
ret = urlmon_alloc(sizeof(FileProtocol));
ret = heap_alloc(sizeof(FileProtocol));
ret->lpInternetProtocolVtbl = &FileProtocolVtbl;
ret->lpInternetPriorityVtbl = &FilePriorityVtbl;

View file

@ -16,17 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -54,6 +44,7 @@ static HRESULT WINAPI EnumFORMATETC_QueryInterface(IEnumFORMATETC *iface, REFIID
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumFORMATETC, riid)) {
IEnumFORMATETC_AddRef(iface);
*ppv = iface;
return S_OK;
}
@ -78,8 +69,8 @@ static ULONG WINAPI EnumFORMATETC_Release(IEnumFORMATETC *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
urlmon_free(This->fetc);
urlmon_free(This);
heap_free(This->fetc);
heap_free(This);
URLMON_UnlockModule();
}
@ -160,7 +151,7 @@ static const IEnumFORMATETCVtbl EnumFORMATETCVtbl = {
static IEnumFORMATETC *EnumFORMATETC_Create(UINT cfmtetc, const FORMATETC *rgfmtetc, UINT it)
{
EnumFORMATETC *ret = urlmon_alloc(sizeof(EnumFORMATETC));
EnumFORMATETC *ret = heap_alloc(sizeof(EnumFORMATETC));
URLMON_LockModule();
@ -169,7 +160,7 @@ static IEnumFORMATETC *EnumFORMATETC_Create(UINT cfmtetc, const FORMATETC *rgfmt
ret->it = it;
ret->fetc_cnt = cfmtetc;
ret->fetc = urlmon_alloc(cfmtetc*sizeof(FORMATETC));
ret->fetc = heap_alloc(cfmtetc*sizeof(FORMATETC));
memcpy(ret->fetc, rgfmtetc, cfmtetc*sizeof(FORMATETC));
return (IEnumFORMATETC*)ret;

View file

@ -16,17 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -81,7 +71,7 @@ static ULONG WINAPI FtpProtocol_Release(IInternetProtocol *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -191,7 +181,7 @@ HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
URLMON_LockModule();
ret = urlmon_alloc(sizeof(FtpProtocol));
ret = heap_alloc(sizeof(FtpProtocol));
ret->lpInternetProtocolVtbl = &FtpProtocolVtbl;
ret->ref = 1;

View file

@ -22,21 +22,10 @@
* - Handle redirects as native.
*/
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "wininet.h"
#include "urlmon_main.h"
#include "wininet.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -159,7 +148,7 @@ static void HTTPPROTOCOL_Close(HttpProtocol *This)
if (This->full_header)
{
if (This->full_header != wszHeaders)
urlmon_free(This->full_header);
heap_free(This->full_header);
This->full_header = 0;
}
This->flags = 0;
@ -234,7 +223,7 @@ static inline LPWSTR strndupW(LPCWSTR string, int len)
{
LPWSTR ret = NULL;
if (string &&
(ret = urlmon_alloc((len+1)*sizeof(WCHAR))) != NULL)
(ret = heap_alloc((len+1)*sizeof(WCHAR))) != NULL)
{
memcpy(ret, string, len*sizeof(WCHAR));
ret[len] = 0;
@ -296,7 +285,7 @@ static ULONG WINAPI HttpProtocol_Release(IInternetProtocol *iface)
if(!ref) {
HTTPPROTOCOL_Close(This);
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -317,7 +306,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
LPWSTR host = 0, path = 0, user = 0, pass = 0, addl_header = 0,
post_cookie = 0, optional = 0;
BYTE security_id[512];
LPOLESTR user_agent, accept_mimes[257];
LPOLESTR user_agent = NULL, accept_mimes[257];
HRESULT hres;
static const WCHAR wszHttp[] = {'h','t','t','p',':'};
@ -378,7 +367,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
{
WARN("ObtainUserAgentString failed: %08x\n", hres);
}
else if (!(user_agenta = urlmon_alloc(len*sizeof(CHAR))))
else if (!(user_agenta = heap_alloc(len*sizeof(CHAR))))
{
WARN("Out of memory\n");
}
@ -393,7 +382,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
else
MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len*sizeof(WCHAR));
}
urlmon_free(user_agenta);
heap_free(user_agenta);
}
This->internet = InternetOpenW(user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC);
@ -472,7 +461,7 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
else
{
int len_addl_header = lstrlenW(addl_header);
This->full_header = urlmon_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));
This->full_header = heap_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));
if (!This->full_header)
{
WARN("Out of memory\n");
@ -556,10 +545,10 @@ done:
CoTaskMemFree(accept_mimes[num++]);
CoTaskMemFree(user_agent);
urlmon_free(pass);
urlmon_free(user);
urlmon_free(path);
urlmon_free(host);
heap_free(pass);
heap_free(user);
heap_free(path);
heap_free(host);
return hres;
}
@ -609,7 +598,7 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA
if ((!HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF, response_headers, &len,
NULL) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
!(response_headers = urlmon_alloc(len)) ||
!(response_headers = heap_alloc(len)) ||
!HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF, response_headers, &len,
NULL))
{
@ -630,7 +619,7 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA
len = 0;
if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
!(content_type = urlmon_alloc(len)) ||
!(content_type = heap_alloc(len)) ||
!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL))
{
WARN("HttpQueryInfo failed: %d\n", GetLastError());
@ -656,7 +645,7 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA
len = 0;
if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
!(content_length = urlmon_alloc(len)) ||
!(content_length = heap_alloc(len)) ||
!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL))
{
WARN("HttpQueryInfo failed: %d\n", GetLastError());
@ -693,9 +682,9 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA
}
done:
urlmon_free(response_headers);
urlmon_free(content_type);
urlmon_free(content_length);
heap_free(response_headers);
heap_free(content_type);
heap_free(content_length);
/* Returns S_OK on native */
return S_OK;
@ -925,7 +914,7 @@ HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
URLMON_LockModule();
ret = urlmon_alloc(sizeof(HttpProtocol));
ret = heap_alloc(sizeof(HttpProtocol));
ret->lpInternetProtocolVtbl = &HttpProtocolVtbl;
ret->lpInternetPriorityVtbl = &HttpPriorityVtbl;

View file

@ -16,21 +16,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "urlmon_main.h"
#include "winreg.h"
#include "shlwapi.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -264,3 +254,47 @@ HRESULT WINAPI CoInternetCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCo
return UrlCompareW(pwzUrl1, pwzUrl2, dwCompareFlags) ? S_FALSE : S_OK;
}
/***********************************************************************
* CoInternetQueryInfo (URLMON.@)
*
* Retrieves information relevant to a specified URL
*
*/
HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption,
DWORD dwQueryFlags, LPVOID pvBuffer, DWORD cbBuffer, DWORD *pcbBuffer,
DWORD dwReserved)
{
IInternetProtocolInfo *protocol_info;
HRESULT hres;
TRACE("(%s, %x, %x, %p, %x, %p, %x): stub\n", debugstr_w(pwzUrl),
QueryOption, dwQueryFlags, pvBuffer, cbBuffer, pcbBuffer, dwReserved);
protocol_info = get_protocol_info(pwzUrl);
if(protocol_info) {
hres = IInternetProtocolInfo_QueryInfo(protocol_info, pwzUrl, QueryOption, dwQueryFlags,
pvBuffer, cbBuffer, pcbBuffer, dwReserved);
IInternetProtocolInfo_Release(protocol_info);
return SUCCEEDED(hres) ? hres : E_FAIL;
}
switch(QueryOption) {
case QUERY_USES_NETWORK:
if(!pvBuffer || cbBuffer < sizeof(DWORD))
return E_FAIL;
*(DWORD*)pvBuffer = 0;
if(pcbBuffer)
*pcbBuffer = sizeof(DWORD);
break;
default:
FIXME("Not supported option %d\n", QueryOption);
return E_NOTIMPL;
}
return S_OK;
}

View file

@ -16,19 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -88,7 +77,7 @@ static ULONG WINAPI MkProtocol_Release(IInternetProtocol *iface)
if(This->stream)
IStream_Release(This->stream);
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -153,11 +142,11 @@ static HRESULT WINAPI MkProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
if(!ptr)
return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
progid = urlmon_alloc((ptr-ptr2+1)*sizeof(WCHAR));
progid = heap_alloc((ptr-ptr2+1)*sizeof(WCHAR));
memcpy(progid, ptr2, (ptr-ptr2)*sizeof(WCHAR));
progid[ptr-ptr2] = 0;
hres = CLSIDFromProgID(progid, &clsid);
urlmon_free(progid);
heap_free(progid);
if(FAILED(hres))
return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER);
@ -169,10 +158,10 @@ static HRESULT WINAPI MkProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
}
len = strlenW(--ptr2);
display_name = urlmon_alloc((len+1)*sizeof(WCHAR));
display_name = heap_alloc((len+1)*sizeof(WCHAR));
memcpy(display_name, ptr2, (len+1)*sizeof(WCHAR));
hres = IParseDisplayName_ParseDisplayName(pdn, NULL /* FIXME */, display_name, &eaten, &mon);
urlmon_free(display_name);
heap_free(display_name);
IParseDisplayName_Release(pdn);
if(FAILED(hres)) {
WARN("ParseDisplayName failed: %08x\n", hres);
@ -307,7 +296,7 @@ HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
URLMON_LockModule();
ret = urlmon_alloc(sizeof(MkProtocol));
ret = heap_alloc(sizeof(MkProtocol));
ret->lpInternetProtocolVtbl = &MkProtocolVtbl;
ret->ref = 1;

View file

@ -18,26 +18,15 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
#include "winreg.h"
#include "winerror.h"
#include "advpub.h"
#include "objbase.h"
#include "urlmon.h"
#include "wine/debug.h"
#include "urlmon_main.h"
#include "winreg.h"
#include "advpub.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
/*
@ -550,7 +539,7 @@ static HRESULT register_inf(BOOL doregister)
INF_SET_CLSID(MkProtocol);
for(i = 0; i < sizeof(pse)/sizeof(pse[0]); i++) {
pse[i].pszValue = urlmon_alloc(39);
pse[i].pszValue = heap_alloc(39);
sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
clsids[i]->Data1, clsids[i]->Data2, clsids[i]->Data3, clsids[i]->Data4[0],
clsids[i]->Data4[1], clsids[i]->Data4[2], clsids[i]->Data4[3], clsids[i]->Data4[4],
@ -566,7 +555,7 @@ static HRESULT register_inf(BOOL doregister)
hres = pRegInstall(URLMON_hInstance, doregister ? "RegisterDll" : "UnregisterDll", &strtable);
for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++)
urlmon_free(pse[i].pszValue);
heap_free(pse[i].pszValue);
return hres;
}

View file

@ -19,20 +19,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "wine/debug.h"
#include "ole2.h"
#include "wine/unicode.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "winreg.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -173,7 +165,7 @@ static ULONG WINAPI SecManagerImpl_Release(IInternetSecurityManager* iface)
if(This->custom_manager)
IInternetSecurityManager_Release(This->custom_manager);
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -260,7 +252,7 @@ static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *ifac
FIXME("not supported flags: %08x\n", dwFlags);
size = (strlenW(pwszUrl)+16) * sizeof(WCHAR);
url = urlmon_alloc(size);
url = heap_alloc(size);
hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, url, size/sizeof(WCHAR), &size, 0);
if(FAILED(hres))
@ -268,7 +260,7 @@ static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *ifac
hres = map_url_to_zone(url, pdwZone);
urlmon_free(url);
heap_free(url);
return hres;
}
@ -300,7 +292,7 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa
FIXME("dwReserved is not supported\n");
len = strlenW(pwszUrl)+1;
buf = urlmon_alloc((len+16)*sizeof(WCHAR));
buf = heap_alloc((len+16)*sizeof(WCHAR));
hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, buf, len, &size, 0);
if(FAILED(hres))
@ -308,7 +300,7 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa
hres = map_url_to_zone(buf, &zone);
if(FAILED(hres)) {
urlmon_free(buf);
heap_free(buf);
return hres == 0x80041001 ? E_INVALIDARG : hres;
}
@ -318,7 +310,7 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa
static const BYTE secidFile[] = {'f','i','l','e',':'};
urlmon_free(buf);
heap_free(buf);
if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone))
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
@ -344,12 +336,12 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa
len = WideCharToMultiByte(CP_ACP, 0, buf, -1, NULL, 0, NULL, NULL)-1;
if(len+sizeof(DWORD) > *pcbSecurityId) {
urlmon_free(buf);
heap_free(buf);
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
WideCharToMultiByte(CP_ACP, 0, buf, -1, (LPSTR)pbSecurityId, -1, NULL, NULL);
urlmon_free(buf);
heap_free(buf);
*(DWORD*)(pbSecurityId+len) = zone;
@ -464,7 +456,7 @@ HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
SecManagerImpl *This;
TRACE("(%p,%p)\n",pUnkOuter,ppobj);
This = urlmon_alloc(sizeof(*This));
This = heap_alloc(sizeof(*This));
/* Initialize the virtual function table. */
This->lpInternetSecurityManagerVtbl = &VT_SecManagerImpl;
@ -577,7 +569,7 @@ static ULONG WINAPI ZoneMgrImpl_Release(IInternetZoneManager* iface)
TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
if(!refCount) {
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -790,7 +782,7 @@ static const IInternetZoneManagerVtbl ZoneMgrImplVtbl = {
HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
ZoneMgrImpl* ret = urlmon_alloc(sizeof(ZoneMgrImpl));
ZoneMgrImpl* ret = heap_alloc(sizeof(ZoneMgrImpl));
TRACE("(%p %p)\n", pUnkOuter, ppobj);
ret->lpVtbl = &ZoneMgrImplVtbl;

View file

@ -16,20 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "winreg.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -41,7 +31,16 @@ typedef struct name_space {
struct name_space *next;
} name_space;
typedef struct mime_filter {
IClassFactory *cf;
CLSID clsid;
LPWSTR mime;
struct mime_filter *next;
} mime_filter;
static name_space *name_space_list = NULL;
static mime_filter *mime_filter_list = NULL;
static name_space *find_name_space(LPCWSTR protocol)
{
@ -68,12 +67,12 @@ static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid,
{'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'};
static const WCHAR wszCLSID[] = {'C','L','S','I','D',0};
wszKey = urlmon_alloc(sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR));
wszKey = heap_alloc(sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR));
memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey));
memcpy(wszKey + sizeof(wszProtocolsKey)/sizeof(WCHAR), schema, (schema_len+1)*sizeof(WCHAR));
res = RegOpenKeyW(HKEY_CLASSES_ROOT, wszKey, &hkey);
urlmon_free(wszKey);
heap_free(wszKey);
if(res != ERROR_SUCCESS) {
TRACE("Could not open protocol handler key\n");
return E_FAIL;
@ -194,7 +193,6 @@ static HRESULT WINAPI InternetSession_RegisterNameSpace(IInternetSession *iface,
const LPCWSTR *ppwzPatterns, DWORD dwReserved)
{
name_space *new_name_space;
int size;
TRACE("(%p %s %s %d %p %d)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzProtocol),
cPatterns, ppwzPatterns, dwReserved);
@ -207,15 +205,12 @@ static HRESULT WINAPI InternetSession_RegisterNameSpace(IInternetSession *iface,
if(!pCF || !pwzProtocol)
return E_INVALIDARG;
new_name_space = urlmon_alloc(sizeof(name_space));
size = (strlenW(pwzProtocol)+1)*sizeof(WCHAR);
new_name_space->protocol = urlmon_alloc(size);
memcpy(new_name_space->protocol, pwzProtocol, size);
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;
@ -247,8 +242,8 @@ static HRESULT WINAPI InternetSession_UnregisterNameSpace(IInternetSession *ifac
name_space_list = iter->next;
IClassFactory_Release(iter->cf);
urlmon_free(iter->protocol);
urlmon_free(iter);
heap_free(iter->protocol);
heap_free(iter);
return S_OK;
}
@ -256,15 +251,49 @@ static HRESULT WINAPI InternetSession_UnregisterNameSpace(IInternetSession *ifac
static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface,
IClassFactory *pCF, REFCLSID rclsid, LPCWSTR pwzType)
{
FIXME("(%p %s %s)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzType));
return E_NOTIMPL;
mime_filter *filter;
TRACE("(%p %s %s)\n", pCF, debugstr_guid(rclsid), debugstr_w(pwzType));
filter = heap_alloc(sizeof(mime_filter));
IClassFactory_AddRef(pCF);
filter->cf = pCF;
filter->clsid = *rclsid;
filter->mime = heap_strdupW(pwzType);
filter->next = mime_filter_list;
mime_filter_list = filter;
return S_OK;
}
static HRESULT WINAPI InternetSession_UnregisterMimeFilter(IInternetSession *iface,
IClassFactory *pCF, LPCWSTR pwzType)
{
FIXME("(%p %s)\n", pCF, debugstr_w(pwzType));
return E_NOTIMPL;
mime_filter *iter, *prev = NULL;
TRACE("(%p %s)\n", pCF, debugstr_w(pwzType));
for(iter = mime_filter_list; iter; iter = iter->next) {
if(iter->cf == pCF && !strcmpW(iter->mime, pwzType))
break;
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);
return S_OK;
}
static HRESULT WINAPI InternetSession_CreateBinding(IInternetSession *iface,
@ -277,7 +306,7 @@ static HRESULT WINAPI InternetSession_CreateBinding(IInternetSession *iface,
if(pBC || pUnkOuter || ppUnk || dwOption)
FIXME("Unsupported arguments\n");
return create_binding_protocol(szUrl, ppOInetProt);
return create_binding_protocol(szUrl, FALSE, ppOInetProt);
}
static HRESULT WINAPI InternetSession_SetSessionOption(IInternetSession *iface,

View file

@ -20,26 +20,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "urlmon_main.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "winuser.h"
#include "objbase.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "ole2.h"
#include "urlmon.h"
#include "wininet.h"
#include "shlwapi.h"
#include "urlmon_main.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -101,7 +91,7 @@ static ULONG WINAPI Binding_Release(IBinding* iface)
TRACE("(%p) ref=%d\n",This, ref);
if(!ref) {
urlmon_free(This->URLName);
heap_free(This->URLName);
if (This->hCacheFile)
CloseHandle(This->hCacheFile);
if (This->pstrCache)
@ -112,7 +102,7 @@ static ULONG WINAPI Binding_Release(IBinding* iface)
if (This->pbscb)
IBindStatusCallback_Release(This->pbscb);
urlmon_free(This);
heap_free(This);
URLMON_UnlockModule();
}
@ -356,8 +346,8 @@ static ULONG WINAPI URLMonikerImpl_Release(IMoniker* iface)
/* destroy the object if there's no more reference on it */
if (!refCount) {
urlmon_free(This->URLName);
urlmon_free(This);
heap_free(This->URLName);
heap_free(This);
URLMON_UnlockModule();
}
@ -420,8 +410,8 @@ static HRESULT WINAPI URLMonikerImpl_Load(IMoniker* iface,IStream* pStm)
res = IStream_Read(pStm, &size, sizeof(ULONG), &got);
if(SUCCEEDED(res)) {
if(got == sizeof(ULONG)) {
urlmon_free(This->URLName);
This->URLName = urlmon_alloc(size);
heap_free(This->URLName);
This->URLName = heap_alloc(size);
if(!This->URLName)
res = E_OUTOFMEMORY;
else {
@ -483,16 +473,21 @@ static HRESULT WINAPI URLMonikerImpl_BindToObject(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
VOID** ppv)
{
URLMonikerImpl *This = (URLMonikerImpl *)iface;
IRunningObjectTable *obj_tbl;
HRESULT hres;
*ppvResult=0;
TRACE("(%p)->(%p,%p,%s,%p): stub\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppv);
FIXME("(%p)->(%p,%p,%s,%p): stub\n",This,pbc,pmkToLeft,debugstr_guid(riid),
ppvResult);
hres = IBindCtx_GetRunningObjectTable(pbc, &obj_tbl);
if(SUCCEEDED(hres)) {
FIXME("use running object table\n");
IRunningObjectTable_Release(obj_tbl);
}
return E_NOTIMPL;
return bind_to_object(iface, This->URLName, pbc, riid, ppv);
}
/******************************************************************************
@ -517,13 +512,13 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
return E_NOTIMPL;
}
bind = urlmon_alloc_zero(sizeof(Binding));
bind = heap_alloc_zero(sizeof(Binding));
bind->lpVtbl = &BindingVtbl;
bind->ref = 1;
URLMON_LockModule();
len = lstrlenW(URLName)+1;
bind->URLName = urlmon_alloc(len*sizeof(WCHAR));
bind->URLName = heap_alloc(len*sizeof(WCHAR));
memcpy(bind->URLName, URLName, len*sizeof(WCHAR));
hres = UMCreateStreamOnCacheFile(bind->URLName, 0, szFileName, &bind->hCacheFile, &bind->pstrCache);
@ -561,15 +556,15 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
url.dwStructSize = sizeof(url);
url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength = url.dwPasswordLength = 1;
InternetCrackUrlW(URLName, 0, ICU_ESCAPE, &url);
host = urlmon_alloc((url.dwHostNameLength + 1) * sizeof(WCHAR));
host = heap_alloc((url.dwHostNameLength + 1) * sizeof(WCHAR));
memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR));
host[url.dwHostNameLength] = '\0';
path = urlmon_alloc((url.dwUrlPathLength + 1) * sizeof(WCHAR));
path = heap_alloc((url.dwUrlPathLength + 1) * sizeof(WCHAR));
memcpy(path, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR));
path[url.dwUrlPathLength] = '\0';
if (url.dwUserNameLength)
{
user = urlmon_alloc(((url.dwUserNameLength + 1) * sizeof(WCHAR)));
user = heap_alloc(((url.dwUserNameLength + 1) * sizeof(WCHAR)));
memcpy(user, url.lpszUserName, url.dwUserNameLength * sizeof(WCHAR));
user[url.dwUserNameLength] = 0;
}
@ -579,7 +574,7 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
}
if (url.dwPasswordLength)
{
pass = urlmon_alloc(((url.dwPasswordLength + 1) * sizeof(WCHAR)));
pass = heap_alloc(((url.dwPasswordLength + 1) * sizeof(WCHAR)));
memcpy(pass, url.lpszPassword, url.dwPasswordLength * sizeof(WCHAR));
pass[url.dwPasswordLength] = 0;
}
@ -711,10 +706,10 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
Binding_FinishedDownload(bind, hres);
Binding_CloseCacheDownload(bind);
urlmon_free(user);
urlmon_free(pass);
urlmon_free(path);
urlmon_free(host);
heap_free(user);
heap_free(pass);
heap_free(path);
heap_free(host);
}
}
}
@ -753,7 +748,7 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface,
TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject);
return start_binding(This->URLName, pbc, riid, ppvObject);
return bind_to_storage(This->URLName, pbc, riid, ppvObject);
}
/******************************************************************************
@ -1042,7 +1037,7 @@ static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeft
This->lpvtbl = &VT_URLMonikerImpl;
This->ref = 0;
This->URLName = urlmon_alloc(INTERNET_MAX_URL_LENGTH*sizeof(WCHAR));
This->URLName = heap_alloc(INTERNET_MAX_URL_LENGTH*sizeof(WCHAR));
if(lpszLeftURLName)
hres = CoInternetCombineUrl(lpszLeftURLName, lpszURLName, URL_FILE_USE_PATHURL,
@ -1052,14 +1047,14 @@ static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeft
This->URLName, INTERNET_MAX_URL_LENGTH, &sizeStr, 0);
if(FAILED(hres)) {
urlmon_free(This->URLName);
heap_free(This->URLName);
return hres;
}
URLMON_LockModule();
if(sizeStr != INTERNET_MAX_URL_LENGTH)
This->URLName = urlmon_realloc(This->URLName, (sizeStr+1)*sizeof(WCHAR));
This->URLName = heap_realloc(This->URLName, (sizeStr+1)*sizeof(WCHAR));
TRACE("URLName = %s\n", debugstr_w(This->URLName));
@ -1092,7 +1087,7 @@ HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker
if (dwFlags & URL_MK_UNIFORM) FIXME("ignoring flag URL_MK_UNIFORM\n");
if(!(obj = urlmon_alloc(sizeof(*obj))))
if(!(obj = heap_alloc(sizeof(*obj))))
return E_OUTOFMEMORY;
if(pmkContext) {
@ -1111,7 +1106,7 @@ HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker
if(SUCCEEDED(hres))
hres = URLMonikerImpl_QueryInterface((IMoniker*)obj, &IID_IMoniker, (void**)ppmk);
else
urlmon_free(obj);
heap_free(obj);
return hres;
}
@ -1135,26 +1130,6 @@ HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **
return CreateURLMonikerEx(pmkContext, szURL, ppmk, URL_MK_LEGACY);
}
/***********************************************************************
* CoInternetQueryInfo (URLMON.@)
*
* Retrieves information relevant to a specified URL
*
* RETURNS
* S_OK success
* S_FALSE buffer too small
* INET_E_QUERYOPTIONUNKNOWN invalid option
*
*/
HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption,
DWORD dwQueryFlags, LPVOID pvBuffer, DWORD cbBuffer, DWORD * pcbBuffer,
DWORD dwReserved)
{
FIXME("(%s, %x, %x, %p, %x, %p, %x): stub\n", debugstr_w(pwzUrl),
QueryOption, dwQueryFlags, pvBuffer, cbBuffer, pcbBuffer, dwReserved);
return S_OK;
}
/***********************************************************************
* IsAsyncMoniker (URLMON.@)
*/
@ -1194,6 +1169,8 @@ HRESULT WINAPI BindAsyncMoniker(IMoniker *pmk, DWORD grfOpt, IBindStatusCallback
LPBC pbc = NULL;
HRESULT hr = E_INVALIDARG;
TRACE("(%p %08x %p %s %p)\n", pmk, grfOpt, pbsc, debugstr_guid(iidResult), ppvResult);
if (pmk && ppvResult)
{
*ppvResult = NULL;
@ -1437,12 +1414,12 @@ HRESULT WINAPI URLDownloadToCacheFileA(LPUNKNOWN lpUnkCaller, LPCSTR szURL, LPST
if(szURL) {
len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
url = urlmon_alloc(len*sizeof(WCHAR));
url = heap_alloc(len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, szURL, -1, url, -1);
}
if(szFileName)
file_name = urlmon_alloc(dwBufLength*sizeof(WCHAR));
file_name = heap_alloc(dwBufLength*sizeof(WCHAR));
hres = URLDownloadToCacheFileW(lpUnkCaller, url, file_name, dwBufLength*sizeof(WCHAR),
dwReserved, pBSC);
@ -1450,8 +1427,8 @@ HRESULT WINAPI URLDownloadToCacheFileA(LPUNKNOWN lpUnkCaller, LPCSTR szURL, LPST
if(SUCCEEDED(hres) && file_name)
WideCharToMultiByte(CP_ACP, 0, file_name, -1, szFileName, dwBufLength, NULL, NULL);
urlmon_free(url);
urlmon_free(file_name);
heap_free(url);
heap_free(file_name);
return hres;
}

View file

@ -19,23 +19,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "urlmon_main.h"
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "winuser.h"
#include "objbase.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "ole2.h"
#include "urlmon.h"
#include "wininet.h"
#include "shlwapi.h"
#include "urlmon_main.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
@ -54,7 +45,7 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL,
HRESULT hr;
size = (strlenW(pszURL)+1)*sizeof(WCHAR);
url = urlmon_alloc(size);
url = heap_alloc(size);
memcpy(url, pszURL, size);
for (c = url; *c && *c != '#' && *c != '?'; ++c)
@ -72,7 +63,7 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL,
else
hr = 0;
urlmon_free(url);
heap_free(url);
if (hr)
return hr;
@ -99,13 +90,13 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL,
}
}
ucstr = urlmon_alloc_zero(sizeof(IUMCacheStream));
ucstr = heap_alloc_zero(sizeof(IUMCacheStream));
if(ucstr)
{
ucstr->pszURL = urlmon_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszURL) + 1));
ucstr->pszURL = heap_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszURL) + 1));
if (ucstr->pszURL)
{
ucstr->pszFileName = urlmon_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszFileName) + 1));
ucstr->pszFileName = heap_alloc_zero(sizeof(WCHAR) * (lstrlenW(pszFileName) + 1));
if (ucstr->pszFileName)
{
ucstr->lpVtbl=&stvt;
@ -119,9 +110,9 @@ HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL,
return S_OK;
}
urlmon_free(ucstr->pszURL);
heap_free(ucstr->pszURL);
}
urlmon_free(ucstr);
heap_free(ucstr);
}
CloseHandle(handle);
if (phfile)
@ -207,9 +198,9 @@ static ULONG WINAPI IStream_fnRelease(IStream *iface)
TRACE(" destroying UMCacheStream (%p)\n",This);
UMCloseCacheFileStream(This);
CloseHandle(This->handle);
urlmon_free(This->pszFileName);
urlmon_free(This->pszURL);
urlmon_free(This);
heap_free(This->pszFileName);
heap_free(This->pszURL);
heap_free(This);
}
return refCount;
}
@ -591,7 +582,7 @@ HRESULT WINAPI URLOpenBlockingStreamA(LPUNKNOWN pCaller, LPCSTR szURL,
return E_INVALIDARG;
len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
szURLW = urlmon_alloc(len * sizeof(WCHAR));
szURLW = heap_alloc(len * sizeof(WCHAR));
if (!szURLW)
{
*ppStream = NULL;
@ -601,7 +592,7 @@ HRESULT WINAPI URLOpenBlockingStreamA(LPUNKNOWN pCaller, LPCSTR szURL,
hr = URLOpenBlockingStreamW(pCaller, szURLW, ppStream, dwReserved, lpfnCB);
urlmon_free(szURLW);
heap_free(szURLW);
return hr;
}
@ -643,14 +634,14 @@ HRESULT WINAPI URLOpenStreamA(LPUNKNOWN pCaller, LPCSTR szURL, DWORD dwReserved,
return E_INVALIDARG;
len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
szURLW = urlmon_alloc(len * sizeof(WCHAR));
szURLW = heap_alloc(len * sizeof(WCHAR));
if (!szURLW)
return E_OUTOFMEMORY;
MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);
hr = URLOpenStreamW(pCaller, szURLW, dwReserved, lpfnCB);
urlmon_free(szURLW);
heap_free(szURLW);
return hr;
}

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<group>
<module name="urlmon" type="win32dll" baseaddress="${BASEADDRESS_URLMON}" installbase="system32" installname="urlmon.dll" allowwarnings="true">
<autoregister infsection="OleControlDlls" type="Both" />
<importlibrary definition="urlmon.spec.def" />
@ -35,3 +36,4 @@
<file>rsrc.rc</file>
<file>urlmon.spec</file>
</module>
</group>

View file

@ -20,21 +20,15 @@
#include <stdarg.h>
#define COBJMACROS
#include "urlmon_main.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#define NO_SHLWAPI_REG
#include "shlwapi.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "winuser.h"
#include "urlmon.h"
#include "urlmon_main.h"
#include "ole2.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);

View file

@ -21,8 +21,17 @@
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
#include "wine/unicode.h"
extern HINSTANCE URLMON_hInstance;
extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
@ -59,28 +68,45 @@ void UMCloseCacheFileStream(IUMCacheStream *pstr);
IInternetProtocolInfo *get_protocol_info(LPCWSTR url);
HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret);
HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv);
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);
HRESULT create_binding_protocol(LPCWSTR url, IInternetProtocol **protocol);
HRESULT create_binding_protocol(LPCWSTR url, BOOL from_urlmon, IInternetProtocol **protocol);
void set_binding_sink(IInternetProtocol *bind_protocol, IInternetProtocolSink *sink);
static inline void *urlmon_alloc(size_t len)
static inline void *heap_alloc(size_t len)
{
return HeapAlloc(GetProcessHeap(), 0, len);
}
static inline void *urlmon_alloc_zero(size_t len)
static inline void *heap_alloc_zero(size_t len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}
static inline void *urlmon_realloc(void *mem, size_t len)
static inline void *heap_realloc(void *mem, size_t len)
{
return HeapReAlloc(GetProcessHeap(), 0, mem, len);
}
static inline BOOL urlmon_free(void *mem)
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
}
static inline LPWSTR heap_strdupW(LPCWSTR str)
{
LPWSTR ret = NULL;
if(str) {
DWORD size;
size = (strlenW(str)+1)*sizeof(WCHAR);
ret = heap_alloc(size);
memcpy(ret, str, size);
}
return ret;
}
#endif /* __WINE_URLMON_MAIN_H */