Author: dchapyshev Date: Sat May 23 14:20:22 2009 New Revision: 41060
URL: http://svn.reactos.org/svn/reactos?rev=41060&view=rev Log: - Sync shlwapi, traffic, urlmon with Wine 1.1.22
Added: trunk/reactos/dll/win32/urlmon/protproxy.c (with props) Modified: trunk/reactos/dll/win32/shlwapi/ordinal.c trunk/reactos/dll/win32/shlwapi/shlwapi.spec trunk/reactos/dll/win32/traffic/traffic.spec trunk/reactos/dll/win32/traffic/traffic_main.c trunk/reactos/dll/win32/urlmon/binding.c trunk/reactos/dll/win32/urlmon/bindprot.c trunk/reactos/dll/win32/urlmon/file.c trunk/reactos/dll/win32/urlmon/ftp.c trunk/reactos/dll/win32/urlmon/gopher.c trunk/reactos/dll/win32/urlmon/http.c trunk/reactos/dll/win32/urlmon/mk.c trunk/reactos/dll/win32/urlmon/session.c trunk/reactos/dll/win32/urlmon/urlmon.rbuild trunk/reactos/dll/win32/urlmon/urlmon_main.c trunk/reactos/dll/win32/urlmon/urlmon_main.h
Modified: trunk/reactos/dll/win32/shlwapi/ordinal.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shlwapi/ordinal.c... ============================================================================== --- trunk/reactos/dll/win32/shlwapi/ordinal.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shlwapi/ordinal.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -1081,11 +1081,11 @@ */ LONG WINAPI SHSetWindowBits(HWND hwnd, INT offset, UINT wMask, UINT wFlags) { - LONG ret = GetWindowLongPtrA(hwnd, offset); + LONG ret = GetWindowLongA(hwnd, offset); LONG newFlags = (wFlags & wMask) | (ret & ~wFlags);
if (newFlags != ret) - ret = SetWindowLongPtrA(hwnd, offset, newFlags); + ret = SetWindowLongA(hwnd, offset, newFlags); return ret; }
@@ -2912,6 +2912,26 @@
return S_OK; } + +/************************************************************************* + * IConnectionPoint_InvokeWithCancel [SHLWAPI.283] + */ +HRESULT WINAPI IConnectionPoint_InvokeWithCancel( IConnectionPoint* iCP, + DISPID dispId, DISPPARAMS* dispParams, + DWORD unknown1, DWORD unknown2 ) +{ + IID iid; + HRESULT result; + + FIXME("(%p)->(0x%x %p %x %x) partial stub\n", iCP, dispId, dispParams, unknown1, unknown2); + + result = IConnectionPoint_GetConnectionInterface(iCP, &iid); + if (SUCCEEDED(result)) + result = SHLWAPI_InvokeByIID(iCP, &iid, dispId, dispParams); + + return result; +} +
/************************************************************************* * @ [SHLWAPI.284]
Modified: trunk/reactos/dll/win32/shlwapi/shlwapi.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shlwapi/shlwapi.s... ============================================================================== --- trunk/reactos/dll/win32/shlwapi/shlwapi.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shlwapi/shlwapi.spec [iso-8859-1] Sat May 23 14:20:22 2009 @@ -280,7 +280,7 @@ 280 stdcall -noname SHRegGetIntW(ptr wstr long) 281 stdcall -noname SHPackDispParamsV(ptr ptr long ptr) 282 varargs -noname SHPackDispParams(ptr ptr long) -283 stub -noname IConnectionPoint_InvokeWithCancel +283 stdcall -noname IConnectionPoint_InvokeWithCancel(ptr long long long long) 284 stdcall -noname IConnectionPoint_SimpleInvoke(ptr long ptr) 285 stdcall -noname IConnectionPoint_OnChanged(ptr long) 286 varargs -noname IUnknown_CPContainerInvokeParam(ptr ptr long ptr long)
Modified: trunk/reactos/dll/win32/traffic/traffic.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/traffic/traffic.s... ============================================================================== --- trunk/reactos/dll/win32/traffic/traffic.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/traffic/traffic.spec [iso-8859-1] Sat May 23 14:20:22 2009 @@ -15,7 +15,7 @@ @ stub TcQueryFlowA @ stub TcQueryFlowW @ stub TcQueryInterface -@ stub TcRegisterClient +@ stdcall TcRegisterClient(long ptr ptr ptr) @ stub TcSetFlowA @ stub TcSetFlowW @ stub TcSetInterface
Modified: trunk/reactos/dll/win32/traffic/traffic_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/traffic/traffic_m... ============================================================================== --- trunk/reactos/dll/win32/traffic/traffic_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/traffic/traffic_main.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -21,6 +21,7 @@
#include "windef.h" #include "winbase.h" +#include "traffic.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(traffic); @@ -42,3 +43,14 @@
return TRUE; } + +/***************************************************************************** + * TcRegisterClient [TRAFFIC.@] + */ +ULONG WINAPI TcRegisterClient(ULONG version, HANDLE context, + PTCI_CLIENT_FUNC_LIST list, PHANDLE buffer) +{ + FIXME("(%u %p %p %p) stub\n", version, context, list, buffer); + if(buffer) *buffer = INVALID_HANDLE_VALUE; + return ERROR_CALL_NOT_IMPLEMENTED; +}
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] Sat May 23 14:20:22 2009 @@ -78,7 +78,7 @@
struct Binding { const IBindingVtbl *lpBindingVtbl; - const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl; + const IInternetProtocolSinkVtbl *lpIInternetProtocolSinkVtbl; const IInternetBindInfoVtbl *lpInternetBindInfoVtbl; const IWinInetHttpInfoVtbl *lpWinInetHttpInfoVtbl; const IServiceProviderVtbl *lpServiceProviderVtbl; @@ -100,66 +100,24 @@ LPWSTR url; IID iid; BOOL report_mime; - DWORD continue_call; DWORD state; HRESULT hres; download_state_t download_state; IUnknown *obj; IMoniker *mon; IBindCtx *bctx; - - DWORD apartment_thread; HWND notif_hwnd;
- task_header_t *task_queue_head, *task_queue_tail; CRITICAL_SECTION section; };
#define BINDING(x) ((IBinding*) &(x)->lpBindingVtbl) -#define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl) #define BINDINF(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl) #define INETINFO(x) ((IWinInetHttpInfo*) &(x)->lpWinInetHttpInfoVtbl) #define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
#define STREAM(x) ((IStream*) &(x)->lpStreamVtbl) #define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl) - -#define WM_MK_CONTINUE (WM_USER+101) - -static void push_task(Binding *binding, task_header_t *task, task_proc_t proc) -{ - task->proc = proc; - task->next = NULL; - - EnterCriticalSection(&binding->section); - - if(binding->task_queue_tail) { - binding->task_queue_tail->next = task; - binding->task_queue_tail = task; - }else { - binding->task_queue_tail = binding->task_queue_head = task; - } - - LeaveCriticalSection(&binding->section); -} - -static task_header_t *pop_task(Binding *binding) -{ - task_header_t *ret; - - EnterCriticalSection(&binding->section); - - ret = binding->task_queue_head; - if(ret) { - binding->task_queue_head = ret->next; - if(!binding->task_queue_head) - binding->task_queue_tail = NULL; - } - - LeaveCriticalSection(&binding->section); - - return ret; -}
static void fill_stgmed_buffer(stgmed_buf_t *buf) { @@ -173,59 +131,6 @@ buf->size += read; if(read > 0) buf->init = TRUE; -} - -static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if(msg == WM_MK_CONTINUE) { - Binding *binding = (Binding*)lParam; - task_header_t *task; - - while((task = pop_task(binding))) { - binding->continue_call++; - task->proc(binding, task); - binding->continue_call--; - } - - IBinding_Release(BINDING(binding)); - return 0; - } - - return DefWindowProcW(hwnd, msg, wParam, lParam); -} - -static HWND get_notif_hwnd(void) -{ - static ATOM wnd_class = 0; - HWND hwnd; - - static const WCHAR wszURLMonikerNotificationWindow[] = - {'U','R','L',' ','M','o','n','i','k','e','r',' ', - 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0}; - - if(!wnd_class) { - static WNDCLASSEXW wndclass = { - sizeof(wndclass), 0, - notif_wnd_proc, 0, 0, - NULL, NULL, NULL, NULL, NULL, - wszURLMonikerNotificationWindow, - NULL - }; - - wndclass.hInstance = URLMON_hInstance; - - wnd_class = RegisterClassExW(&wndclass); - if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS) - wnd_class = 1; - } - - hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow, - wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE, - NULL, URLMON_hInstance, NULL); - - TRACE("hwnd = %p\n", hwnd); - - return hwnd; }
static void dump_BINDINFO(BINDINFO *bi) @@ -272,73 +177,17 @@ ); }
-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) +static void mime_available(Binding *This, LPCWSTR mime) +{ + heap_free(This->mime); + This->mime = heap_strdupW(mime); + + if(!This->mime || !This->report_mime) return;
- if(verify) { - LPWSTR mime = NULL; - - 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); - 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); - } + IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, This->mime); + + This->clipboard_format = RegisterClipboardFormatW(This->mime); }
static void stop_binding(Binding *binding, HRESULT hres, LPCWSTR str) @@ -957,8 +806,8 @@ TRACE("(%p) ref=%d\n", This, ref);
if(!ref) { - if (This->notif_hwnd) - DestroyWindow( This->notif_hwnd ); + if(This->notif_hwnd) + release_notif_hwnd(This->notif_hwnd); if(This->mon) IMoniker_Release(This->mon); if(This->callback) @@ -1066,7 +915,7 @@ Binding_GetBindResult };
-#define PROTSINK_THIS(iface) DEFINE_THIS(Binding, InternetProtocolSink, iface) +#define PROTSINK_THIS(iface) DEFINE_THIS(Binding, IInternetProtocolSink, iface)
static HRESULT WINAPI InternetProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv) @@ -1087,92 +936,21 @@ return IBinding_Release(BINDING(This)); }
-typedef struct { - task_header_t header; - PROTOCOLDATA data; -} switch_task_t; - -static void switch_proc(Binding *binding, task_header_t *t) -{ - switch_task_t *task = (switch_task_t*)t; - - IInternetProtocol_Continue(binding->protocol, &task->data); - - heap_free(task); -} - static HRESULT WINAPI InternetProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData) { Binding *This = PROTSINK_THIS(iface); - switch_task_t *task; - - TRACE("(%p)->(%p)\n", This, pProtocolData); - - task = heap_alloc(sizeof(switch_task_t)); - task->data = *pProtocolData; - - push_task(This, &task->header, switch_proc); - - IBinding_AddRef(BINDING(This)); - PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); - - return S_OK; -} - -typedef struct { - task_header_t header; - - Binding *binding; - ULONG progress; - ULONG progress_max; - ULONG status_code; - LPWSTR status_text; -} on_progress_task_t; - -static void on_progress_proc(Binding *binding, task_header_t *t) -{ - on_progress_task_t *task = (on_progress_task_t*)t; - - IBindStatusCallback_OnProgress(binding->callback, task->progress, - task->progress_max, task->status_code, task->status_text); - - heap_free(task->status_text); - heap_free(task); + + WARN("(%p)->(%p)\n", This, pProtocolData); + + return E_FAIL; }
static void on_progress(Binding *This, ULONG progress, ULONG progress_max, ULONG status_code, LPCWSTR status_text) { - on_progress_task_t *task; - - if(GetCurrentThreadId() == This->apartment_thread && !This->continue_call) { - IBindStatusCallback_OnProgress(This->callback, progress, progress_max, - status_code, status_text); - return; - } - - task = heap_alloc(sizeof(on_progress_task_t)); - - task->progress = progress; - task->progress_max = progress_max; - task->status_code = status_code; - - if(status_text) { - DWORD size = (strlenW(status_text)+1)*sizeof(WCHAR); - - task->status_text = heap_alloc(size); - memcpy(task->status_text, status_text, size); - }else { - task->status_text = NULL; - } - - push_task(This, &task->header, on_progress_proc); - - if(GetCurrentThreadId() != This->apartment_thread) { - IBinding_AddRef(BINDING(This)); - PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); - } + IBindStatusCallback_OnProgress(This->callback, progress, progress_max, + status_code, status_text); }
static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, @@ -1192,22 +970,26 @@ case BINDSTATUS_BEGINDOWNLOADDATA: fill_stgmed_buffer(This->stgmed_buf); break; - 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_MIMETYPEAVAILABLE: case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: - mime_available(This, szStatusText, FALSE); + mime_available(This, szStatusText); break; case BINDSTATUS_CACHEFILENAMEAVAILABLE: heap_free(This->stgmed_buf->cache_file); This->stgmed_buf->cache_file = heap_strdupW(szStatusText); break; - case BINDSTATUS_DIRECTBIND: + case BINDSTATUS_DECODING: + IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_DECODING, szStatusText); + break; + case BINDSTATUS_LOADINGMIMEHANDLER: + on_progress(This, 0, 0, BINDSTATUS_LOADINGMIMEHANDLER, szStatusText); + break; + case BINDSTATUS_DIRECTBIND: /* FIXME: Handle BINDSTATUS_DIRECTBIND in BindProtocol */ This->report_mime = FALSE; break; case BINDSTATUS_ACCEPTRANGES: @@ -1230,12 +1012,6 @@ if(This->download_state == END_DOWNLOAD || (This->state & BINDING_STOPPED)) return;
- if(GetCurrentThreadId() != This->apartment_thread) - FIXME("called from worker thread\n"); - - if(This->report_mime) - mime_available(This, NULL, TRUE); - if(This->download_state == BEFORE_DOWNLOAD) { fill_stgmed_buffer(This->stgmed_buf);
@@ -1288,22 +1064,6 @@ } }
-typedef struct { - task_header_t header; - DWORD bscf; - ULONG progress; - ULONG progress_max; -} report_data_task_t; - -static void report_data_proc(Binding *binding, task_header_t *t) -{ - report_data_task_t *task = (report_data_task_t*)t; - - report_data(binding, task->bscf, task->progress, task->progress_max); - - heap_free(task); -} - static HRESULT WINAPI InternetProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) { @@ -1311,40 +1071,8 @@
TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax);
- if(GetCurrentThreadId() != This->apartment_thread) - FIXME("called from worked hread\n"); - - if(This->continue_call) { - report_data_task_t *task = heap_alloc(sizeof(report_data_task_t)); - task->bscf = grfBSCF; - task->progress = ulProgress; - task->progress_max = ulProgressMax; - - push_task(This, &task->header, report_data_proc); - }else { - report_data(This, grfBSCF, ulProgress, ulProgressMax); - } - + report_data(This, grfBSCF, ulProgress, ulProgressMax); 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); - - stop_binding(binding, task->hres, task->str); - - heap_free(task->str); - heap_free(task); }
static HRESULT WINAPI InternetProtocolSink_ReportResult(IInternetProtocolSink *iface, @@ -1354,18 +1082,8 @@
TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult));
- if(GetCurrentThreadId() == This->apartment_thread && !This->continue_call) { - IInternetProtocol_Terminate(This->protocol, 0); - stop_binding(This, hrResult, szResult); - }else { - 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); - } - + IInternetProtocol_Terminate(This->protocol, 0); + stop_binding(This, hrResult, szResult); return S_OK; }
@@ -1458,6 +1176,17 @@ IInternetBindInfo_Release(bindinfo);
return hres; + } + case BINDSTRING_URL: { + DWORD size = (strlenW(This->url)+1) * sizeof(WCHAR); + + if(!ppwzStr || !pcElFetched) + return E_INVALIDARG; + + *ppwzStr = CoTaskMemAlloc(size); + memcpy(*ppwzStr, This->url, size); + *pcElFetched = 1; + return S_OK; } }
@@ -1630,7 +1359,7 @@ ret = heap_alloc_zero(sizeof(Binding));
ret->lpBindingVtbl = &BindingVtbl; - ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl; + ret->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl; ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl; ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl; ret->lpServiceProviderVtbl = &ServiceProviderVtbl; @@ -1639,7 +1368,6 @@
ret->to_object = to_obj; ret->iid = *riid; - ret->apartment_thread = GetCurrentThreadId(); ret->notif_hwnd = get_notif_hwnd(); ret->report_mime = !binding_ctx; ret->download_state = BEFORE_DOWNLOAD; @@ -1749,7 +1477,7 @@ report_data(binding, 0, 0, 0); }else { hres = IInternetProtocol_Start(binding->protocol, url, PROTSINK(binding), - BINDINF(binding), 0, 0); + BINDINF(binding), PI_APARTMENTTHREADED|PI_MIMEVERIFICATION, 0);
TRACE("start ret %08x\n", hres);
Modified: trunk/reactos/dll/win32/urlmon/bindprot.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/bindprot.c... ============================================================================== --- trunk/reactos/dll/win32/urlmon/bindprot.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/bindprot.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -1,5 +1,5 @@ /* - * Copyright 2007 Jacek Caban for CodeWeavers + * Copyright 2007-2009 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 @@ -21,16 +21,30 @@
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-typedef struct { - const IInternetProtocolVtbl *lpInternetProtocolVtbl; - const IInternetBindInfoVtbl *lpInternetBindInfoVtbl; - const IInternetPriorityVtbl *lpInternetPriorityVtbl; - const IServiceProviderVtbl *lpServiceProviderVtbl; - const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl; +typedef struct BindProtocol BindProtocol; + +struct _task_header_t; + +typedef void (*task_proc_t)(BindProtocol*,struct _task_header_t*); + +typedef struct _task_header_t { + task_proc_t proc; + struct _task_header_t *next; +} task_header_t; + +struct BindProtocol { + const IInternetProtocolVtbl *lpIInternetProtocolVtbl; + const IInternetBindInfoVtbl *lpInternetBindInfoVtbl; + const IInternetPriorityVtbl *lpInternetPriorityVtbl; + const IServiceProviderVtbl *lpServiceProviderVtbl; + const IInternetProtocolSinkVtbl *lpIInternetProtocolSinkVtbl; + + const IInternetProtocolVtbl *lpIInternetProtocolHandlerVtbl;
LONG ref;
IInternetProtocol *protocol; + IInternetProtocol *protocol_handler; IInternetBindInfo *bind_info; IInternetProtocolSink *protocol_sink; IServiceProvider *service_provider; @@ -39,16 +53,240 @@ LONG priority;
BOOL reported_result; + BOOL reported_mime; BOOL from_urlmon; -} BindProtocol; - -#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) + DWORD pi; + + DWORD apartment_thread; + HWND notif_hwnd; + DWORD continue_call; + + CRITICAL_SECTION section; + task_header_t *task_queue_head, *task_queue_tail; + + BYTE *buf; + DWORD buf_size; + LPWSTR mime; + LPWSTR url; + ProtocolProxy *filter_proxy; +}; + #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) + +#define PROTOCOLHANDLER(x) ((IInternetProtocol*) &(x)->lpIInternetProtocolHandlerVtbl) + +#define BUFFER_SIZE 2048 +#define MIME_TEST_SIZE 255 + +#define WM_MK_CONTINUE (WM_USER+101) +#define WM_MK_RELEASE (WM_USER+102) + +static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_MK_CONTINUE: { + BindProtocol *This = (BindProtocol*)lParam; + task_header_t *task; + + while(1) { + EnterCriticalSection(&This->section); + + task = This->task_queue_head; + if(task) { + This->task_queue_head = task->next; + if(!This->task_queue_head) + This->task_queue_tail = NULL; + } + + LeaveCriticalSection(&This->section); + + if(!task) + break; + + This->continue_call++; + task->proc(This, task); + This->continue_call--; + } + + IInternetProtocol_Release(PROTOCOL(This)); + return 0; + } + case WM_MK_RELEASE: { + tls_data_t *data = get_tls_data(); + + if(!--data->notif_hwnd_cnt) { + DestroyWindow(hwnd); + data->notif_hwnd = NULL; + } + } + } + + return DefWindowProcW(hwnd, msg, wParam, lParam); +} + +HWND get_notif_hwnd(void) +{ + static ATOM wnd_class = 0; + tls_data_t *tls_data; + + static const WCHAR wszURLMonikerNotificationWindow[] = + {'U','R','L',' ','M','o','n','i','k','e','r',' ', + 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0}; + + tls_data = get_tls_data(); + if(!tls_data) + return NULL; + + if(tls_data->notif_hwnd_cnt) { + tls_data->notif_hwnd_cnt++; + return tls_data->notif_hwnd; + } + + if(!wnd_class) { + static WNDCLASSEXW wndclass = { + sizeof(wndclass), 0, + notif_wnd_proc, 0, 0, + NULL, NULL, NULL, NULL, NULL, + wszURLMonikerNotificationWindow, + NULL + }; + + wndclass.hInstance = URLMON_hInstance; + + wnd_class = RegisterClassExW(&wndclass); + if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS) + wnd_class = 1; + } + + tls_data->notif_hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow, + wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE, + NULL, URLMON_hInstance, NULL); + if(tls_data->notif_hwnd) + tls_data->notif_hwnd_cnt++; + + TRACE("hwnd = %p\n", tls_data->notif_hwnd); + + return tls_data->notif_hwnd; +} + +void release_notif_hwnd(HWND hwnd) +{ + tls_data_t *data = get_tls_data(); + + if(!data) + return; + + if(data->notif_hwnd != hwnd) { + PostMessageW(data->notif_hwnd, WM_MK_RELEASE, 0, 0); + return; + } + + if(!--data->notif_hwnd_cnt) { + DestroyWindow(data->notif_hwnd); + data->notif_hwnd = NULL; + } +} + +static void push_task(BindProtocol *This, task_header_t *task, task_proc_t proc) +{ + BOOL do_post = FALSE; + + task->proc = proc; + task->next = NULL; + + EnterCriticalSection(&This->section); + + if(This->task_queue_tail) { + This->task_queue_tail->next = task; + This->task_queue_tail = task; + }else { + This->task_queue_tail = This->task_queue_head = task; + do_post = TRUE; + } + + LeaveCriticalSection(&This->section); + + if(do_post) { + IInternetProtocol_AddRef(PROTOCOL(This)); + PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); + } +} + +static inline BOOL do_direct_notif(BindProtocol *This) +{ + return !(This->pi & PI_APARTMENTTHREADED) || (This->apartment_thread == GetCurrentThreadId() && !This->continue_call); +} + +static HRESULT handle_mime_filter(BindProtocol *This, IInternetProtocol *mime_filter, LPCWSTR mime) +{ + PROTOCOLFILTERDATA filter_data = { sizeof(PROTOCOLFILTERDATA), NULL, NULL, NULL, 0 }; + IInternetProtocolSink *protocol_sink, *old_sink; + ProtocolProxy *filter_proxy; + HRESULT hres; + + hres = IInternetProtocol_QueryInterface(mime_filter, &IID_IInternetProtocolSink, (void**)&protocol_sink); + if(FAILED(hres)) + return hres; + + hres = create_protocol_proxy(PROTOCOLHANDLER(This), This->protocol_sink, &filter_proxy); + if(FAILED(hres)) { + IInternetProtocolSink_Release(protocol_sink); + return hres; + } + + old_sink = This->protocol_sink; + This->protocol_sink = protocol_sink; + This->filter_proxy = filter_proxy; + + IInternetProtocol_AddRef(mime_filter); + This->protocol_handler = mime_filter; + + filter_data.pProtocol = PROTOCOL(filter_proxy); + hres = IInternetProtocol_Start(mime_filter, mime, PROTSINK(filter_proxy), BINDINFO(This), + PI_FILTER_MODE|PI_FORCE_ASYNC, (HANDLE_PTR)&filter_data); + if(FAILED(hres)) { + IInternetProtocolSink_Release(old_sink); + return hres; + } + + IInternetProtocolSink_ReportProgress(old_sink, BINDSTATUS_LOADINGMIMEHANDLER, NULL); + IInternetProtocolSink_Release(old_sink); + + This->pi &= ~PI_MIMEVERIFICATION; /* FIXME: more tests */ + return S_OK; +} + +static void mime_available(BindProtocol *This, LPCWSTR mime, BOOL verified) +{ + IInternetProtocol *mime_filter; + HRESULT hres; + + heap_free(This->mime); + This->mime = NULL; + + mime_filter = get_mime_filter(mime); + if(mime_filter) { + TRACE("Got mime filter for %s\n", debugstr_w(mime)); + + hres = handle_mime_filter(This, mime_filter, mime); + IInternetProtocol_Release(mime_filter); + if(FAILED(hres)) + FIXME("MIME filter failed: %08x\n", hres); + }else { + This->mime = heap_strdupW(mime); + + if(verified || !(This->pi & PI_MIMEVERIFICATION)) { + This->reported_mime = TRUE; + + if(This->protocol_sink) + IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, mime); + } + } +} + +#define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, IInternetProtocol, iface)
static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { @@ -111,8 +349,19 @@ IInternetProtocol_Release(This->protocol); if(This->bind_info) IInternetBindInfo_Release(This->bind_info); + if(This->protocol_handler && This->protocol_handler != PROTOCOLHANDLER(This)) + IInternetProtocol_Release(This->protocol_handler); + if(This->filter_proxy) + IInternetProtocol_Release(PROTOCOL(This->filter_proxy));
set_binding_sink(PROTOCOL(This), NULL); + + if(This->notif_hwnd) + release_notif_hwnd(This->notif_hwnd); + DeleteCriticalSection(&This->section); + + heap_free(This->mime); + heap_free(This->url); heap_free(This);
URLMON_UnlockModule(); @@ -126,77 +375,11 @@ DWORD grfPI, HANDLE_PTR dwReserved) { BindProtocol *This = PROTOCOL_THIS(iface); - IInternetProtocol *protocol = NULL; - IInternetPriority *priority; - IServiceProvider *service_provider; - BOOL urlmon_protocol = FALSE; - CLSID clsid = IID_NULL; - LPOLESTR clsid_str; - HRESULT hres;
TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved);
- if(!szUrl || !pOIProtSink || !pOIBindInfo) - return E_INVALIDARG; - - hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider, - (void**)&service_provider); - if(SUCCEEDED(hres)) { - /* FIXME: What's protocol CLSID here? */ - IServiceProvider_QueryService(service_provider, &IID_IInternetProtocol, - &IID_IInternetProtocol, (void**)&protocol); - IServiceProvider_Release(service_provider); - } - - if(!protocol) { - IClassFactory *cf; - IUnknown *unk; - - hres = get_protocol_handler(szUrl, &clsid, &urlmon_protocol, &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; - } - } - - StringFromCLSID(&clsid, &clsid_str); - IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_PROTOCOLCLASSID, clsid_str); - CoTaskMemFree(clsid_str); - - This->protocol = protocol; - - if(urlmon_protocol) - IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&This->wininet_info); - - IInternetBindInfo_AddRef(pOIBindInfo); - This->bind_info = pOIBindInfo; - - set_binding_sink(PROTOCOL(This), pOIProtSink); - - hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority); - if(SUCCEEDED(hres)) { - IInternetPriority_SetPriority(priority, This->priority); - IInternetPriority_Release(priority); - } - - return IInternetProtocol_Start(protocol, szUrl, PROTSINK(This), BINDINFO(This), 0, 0); + return IInternetProtocol_Start(This->protocol_handler, szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved); }
static HRESULT WINAPI BindProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) @@ -205,7 +388,7 @@
TRACE("(%p)->(%p)\n", This, pProtocolData);
- return IInternetProtocol_Continue(This->protocol, pProtocolData); + return IInternetProtocol_Continue(This->protocol_handler, pProtocolData); }
static HRESULT WINAPI BindProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason, @@ -222,19 +405,7 @@
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; + return IInternetProtocol_Terminate(This->protocol_handler, dwOptions); }
static HRESULT WINAPI BindProtocol_Suspend(IInternetProtocol *iface) @@ -255,15 +426,12 @@ ULONG cb, ULONG *pcbRead) { BindProtocol *This = PROTOCOL_THIS(iface); - ULONG read = 0; - HRESULT hres;
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
- hres = IInternetProtocol_Read(This->protocol, pv, cb, &read); - - *pcbRead = read; - return hres; + if(pcbRead) + *pcbRead = 0; + return IInternetProtocol_Read(This->protocol_handler, pv, cb, pcbRead); }
static HRESULT WINAPI BindProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, @@ -280,7 +448,7 @@
TRACE("(%p)->(%08x)\n", This, dwOptions);
- return IInternetProtocol_LockRequest(This->protocol, dwOptions); + return IInternetProtocol_LockRequest(This->protocol_handler, dwOptions); }
static HRESULT WINAPI BindProtocol_UnlockRequest(IInternetProtocol *iface) @@ -289,7 +457,7 @@
TRACE("(%p)\n", This);
- return IInternetProtocol_UnlockRequest(This->protocol); + return IInternetProtocol_UnlockRequest(This->protocol_handler); }
void set_binding_sink(IInternetProtocol *bind_protocol, IInternetProtocolSink *sink) @@ -336,6 +504,242 @@ BindProtocol_UnlockRequest };
+#define PROTOCOLHANDLER_THIS(iface) DEFINE_THIS(BindProtocol, IInternetProtocolHandler, iface) + +static HRESULT WINAPI ProtocolHandler_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) +{ + ERR("should not be called\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI ProtocolHandler_AddRef(IInternetProtocol *iface) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + return IInternetProtocol_AddRef(PROTOCOL(This)); +} + +static ULONG WINAPI ProtocolHandler_Release(IInternetProtocol *iface) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + return IInternetProtocol_Release(PROTOCOL(This)); +} + +static HRESULT WINAPI ProtocolHandler_Start(IInternetProtocol *iface, LPCWSTR szUrl, + IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, + DWORD grfPI, HANDLE_PTR dwReserved) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + IInternetProtocol *protocol = NULL; + IInternetPriority *priority; + IServiceProvider *service_provider; + BOOL urlmon_protocol = FALSE; + CLSID clsid = IID_NULL; + LPOLESTR clsid_str; + HRESULT hres; + + TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, + pOIBindInfo, grfPI, dwReserved); + + if(!szUrl || !pOIProtSink || !pOIBindInfo) + return E_INVALIDARG; + + This->pi = grfPI; + This->url = heap_strdupW(szUrl); + + hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider, + (void**)&service_provider); + if(SUCCEEDED(hres)) { + /* FIXME: What's protocol CLSID here? */ + IServiceProvider_QueryService(service_provider, &IID_IInternetProtocol, + &IID_IInternetProtocol, (void**)&protocol); + IServiceProvider_Release(service_provider); + } + + if(!protocol) { + IClassFactory *cf; + IUnknown *unk; + + hres = get_protocol_handler(szUrl, &clsid, &urlmon_protocol, &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; + } + } + + StringFromCLSID(&clsid, &clsid_str); + IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_PROTOCOLCLASSID, clsid_str); + CoTaskMemFree(clsid_str); + + This->protocol = protocol; + + if(urlmon_protocol) + IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&This->wininet_info); + + IInternetBindInfo_AddRef(pOIBindInfo); + This->bind_info = pOIBindInfo; + + set_binding_sink(PROTOCOL(This), pOIProtSink); + + hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority); + if(SUCCEEDED(hres)) { + IInternetPriority_SetPriority(priority, This->priority); + IInternetPriority_Release(priority); + } + + return IInternetProtocol_Start(protocol, szUrl, PROTSINK(This), BINDINFO(This), 0, 0); +} + +static HRESULT WINAPI ProtocolHandler_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pProtocolData); + + return IInternetProtocol_Continue(This->protocol, pProtocolData); +} + +static HRESULT WINAPI ProtocolHandler_Abort(IInternetProtocol *iface, HRESULT hrReason, + DWORD dwOptions) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProtocolHandler_Terminate(IInternetProtocol *iface, DWORD dwOptions) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + + TRACE("(%p)->(%08x)\n", This, dwOptions); + + if(!This->reported_result) + return E_FAIL; + + IInternetProtocol_Terminate(This->protocol, 0); + + if(This->filter_proxy) { + IInternetProtocol_Release(PROTOCOL(This->filter_proxy)); + This->filter_proxy = NULL; + } + + set_binding_sink(PROTOCOL(This), NULL); + + if(This->bind_info) { + IInternetBindInfo_Release(This->bind_info); + This->bind_info = NULL; + } + + return S_OK; +} + +static HRESULT WINAPI ProtocolHandler_Suspend(IInternetProtocol *iface) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProtocolHandler_Resume(IInternetProtocol *iface) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProtocolHandler_Read(IInternetProtocol *iface, void *pv, + ULONG cb, ULONG *pcbRead) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + ULONG read = 0; + HRESULT hres = S_OK; + + TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); + + if(This->buf) { + read = min(cb, This->buf_size); + memcpy(pv, This->buf, read); + + if(read == This->buf_size) { + heap_free(This->buf); + This->buf = NULL; + }else { + memmove(This->buf, This->buf+cb, This->buf_size-cb); + } + + This->buf_size -= read; + } + + if(read < cb) { + ULONG cread = 0; + + hres = IInternetProtocol_Read(This->protocol, (BYTE*)pv+read, cb-read, &cread); + read += cread; + } + + *pcbRead = read; + return hres; +} + +static HRESULT WINAPI ProtocolHandler_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, + DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProtocolHandler_LockRequest(IInternetProtocol *iface, DWORD dwOptions) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + + TRACE("(%p)->(%08x)\n", This, dwOptions); + + return IInternetProtocol_LockRequest(This->protocol, dwOptions); +} + +static HRESULT WINAPI ProtocolHandler_UnlockRequest(IInternetProtocol *iface) +{ + BindProtocol *This = PROTOCOLHANDLER_THIS(iface); + + TRACE("(%p)\n", This); + + return IInternetProtocol_UnlockRequest(This->protocol); +} + +#undef PROTOCOL_THIS + +static const IInternetProtocolVtbl InternetProtocolHandlerVtbl = { + ProtocolHandler_QueryInterface, + ProtocolHandler_AddRef, + ProtocolHandler_Release, + ProtocolHandler_Start, + ProtocolHandler_Continue, + ProtocolHandler_Abort, + ProtocolHandler_Terminate, + ProtocolHandler_Suspend, + ProtocolHandler_Resume, + ProtocolHandler_Read, + ProtocolHandler_Seek, + ProtocolHandler_LockRequest, + ProtocolHandler_UnlockRequest +}; + #define BINDINFO_THIS(iface) DEFINE_THIS(BindProtocol, InternetBindInfo, iface)
static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, @@ -447,7 +851,7 @@
};
-#define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, InternetProtocolSink, iface) +#define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, IInternetProtocolSink, iface)
static HRESULT WINAPI BPInternetProtocolSink_QueryInterface(IInternetProtocolSink *iface, REFIID riid, void **ppv) @@ -468,6 +872,20 @@ return IInternetProtocol_Release(PROTOCOL(This)); }
+typedef struct { + task_header_t header; + PROTOCOLDATA data; +} switch_task_t; + +static void switch_proc(BindProtocol *bind, task_header_t *t) +{ + switch_task_t *task = (switch_task_t*)t; + + IInternetProtocol_Continue(bind->protocol_handler, &task->data); + + heap_free(task); +} + static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOLDATA *pProtocolData) { @@ -478,22 +896,30 @@ TRACE("flags %x state %x data %p cb %u\n", pProtocolData->grfFlags, pProtocolData->dwState, pProtocolData->pData, pProtocolData->cbData);
+ if(!do_direct_notif(This)) { + switch_task_t *task; + + task = heap_alloc(sizeof(switch_task_t)); + if(!task) + return E_OUTOFMEMORY; + + task->data = *pProtocolData; + + push_task(This, &task->header, switch_proc); + return S_OK; + } + if(!This->protocol_sink) { - IInternetProtocol_Continue(This->protocol, pProtocolData); + IInternetProtocol_Continue(This->protocol_handler, pProtocolData); return S_OK; }
return IInternetProtocolSink_Switch(This->protocol_sink, pProtocolData); }
-static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, - ULONG ulStatusCode, LPCWSTR szStatusText) -{ - BindProtocol *This = PROTSINK_THIS(iface); - - TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText)); - - switch(ulStatusCode) { +static void report_progress(BindProtocol *This, ULONG status_code, LPCWSTR status_text) +{ + switch(status_code) { case BINDSTATUS_FINDINGRESOURCE: case BINDSTATUS_CONNECTING: case BINDSTATUS_BEGINDOWNLOADDATA: @@ -501,23 +927,116 @@ case BINDSTATUS_CACHEFILENAMEAVAILABLE: case BINDSTATUS_DIRECTBIND: case BINDSTATUS_ACCEPTRANGES: + if(This->protocol_sink) + IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text); + break; + case BINDSTATUS_MIMETYPEAVAILABLE: - if(!This->protocol_sink) + mime_available(This, status_text, FALSE); + break; + + case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: + mime_available(This, status_text, TRUE); + break; + + default: + FIXME("unsupported ulStatusCode %u\n", status_code); + } +} + +typedef struct { + task_header_t header; + + ULONG status_code; + LPWSTR status_text; +} on_progress_task_t; + +static void on_progress_proc(BindProtocol *This, task_header_t *t) +{ + on_progress_task_t *task = (on_progress_task_t*)t; + + report_progress(This, task->status_code, task->status_text); + + heap_free(task->status_text); + heap_free(task); +} + +static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, + ULONG ulStatusCode, LPCWSTR szStatusText) +{ + BindProtocol *This = PROTSINK_THIS(iface); + + TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText)); + + if(do_direct_notif(This)) { + report_progress(This, ulStatusCode, szStatusText); + }else { + on_progress_task_t *task; + + task = heap_alloc(sizeof(on_progress_task_t)); + + task->status_code = ulStatusCode; + task->status_text = heap_strdupW(szStatusText); + + push_task(This, &task->header, on_progress_proc); + } + + return S_OK; +} + +static HRESULT report_data(BindProtocol *This, DWORD bscf, ULONG progress, ULONG progress_max) +{ + if(!This->protocol_sink) + return S_OK; + + if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) { + DWORD read = 0; + LPWSTR mime; + HRESULT hres; + + if(!This->buf) { + This->buf = heap_alloc(BUFFER_SIZE); + if(!This->buf) + return E_OUTOFMEMORY; + } + + do { + read = 0; + hres = IInternetProtocol_Read(This->protocol, This->buf+This->buf_size, + BUFFER_SIZE-This->buf_size, &read); + if(FAILED(hres) && hres != E_PENDING) + return hres; + This->buf_size += read; + }while(This->buf_size < MIME_TEST_SIZE && hres == S_OK); + + if(This->buf_size < MIME_TEST_SIZE && hres != S_FALSE) 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, - This->from_urlmon ? BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE, - szStatusText); - default: - FIXME("unsupported ulStatusCode %u\n", ulStatusCode); - } - - return E_NOTIMPL; + + hres = FindMimeFromData(NULL, This->url, This->buf, min(This->buf_size, MIME_TEST_SIZE), + This->mime, 0, &mime, 0); + if(FAILED(hres)) + return hres; + + mime_available(This, mime, TRUE); + CoTaskMemFree(mime); + } + + return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max); +} + +typedef struct { + task_header_t header; + DWORD bscf; + ULONG progress; + ULONG progress_max; +} report_data_task_t; + +static void report_data_proc(BindProtocol *This, task_header_t *t) +{ + report_data_task_t *task = (report_data_task_t*)t; + + report_data(This, task->bscf, task->progress, task->progress_max); + heap_free(task); }
static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *iface, @@ -530,7 +1049,41 @@ if(!This->protocol_sink) return S_OK;
- return IInternetProtocolSink_ReportData(This->protocol_sink, grfBSCF, ulProgress, ulProgressMax); + if(!do_direct_notif(This)) { + report_data_task_t *task; + + task = heap_alloc(sizeof(report_data_task_t)); + if(!task) + return E_OUTOFMEMORY; + + task->bscf = grfBSCF; + task->progress = ulProgress; + task->progress_max = ulProgressMax; + + push_task(This, &task->header, report_data_proc); + return S_OK; + } + + return report_data(This, grfBSCF, ulProgress, ulProgressMax); +} + +typedef struct { + task_header_t header; + + HRESULT hres; + DWORD err; + LPWSTR str; +} report_result_task_t; + +static void report_result_proc(BindProtocol *This, task_header_t *t) +{ + report_result_task_t *task = (report_result_task_t*)t; + + if(This->protocol_sink) + IInternetProtocolSink_ReportResult(This->protocol_sink, task->hres, task->err, task->str); + + heap_free(task->str); + heap_free(task); }
static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink *iface, @@ -544,6 +1097,21 @@ return E_FAIL;
This->reported_result = TRUE; + + if(!do_direct_notif(This)) { + report_result_task_t *task; + + task = heap_alloc(sizeof(report_result_task_t)); + if(!task) + return E_OUTOFMEMORY; + + task->hres = hrResult; + task->err = dwError; + task->str = heap_strdupW(szResult); + + push_task(This, &task->header, report_result_proc); + return S_OK; + }
return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult); } @@ -607,14 +1175,19 @@ { BindProtocol *ret = heap_alloc_zero(sizeof(BindProtocol));
- ret->lpInternetProtocolVtbl = &BindProtocolVtbl; - ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl; - ret->lpInternetPriorityVtbl = &InternetPriorityVtbl; - ret->lpServiceProviderVtbl = &ServiceProviderVtbl; - ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl; + ret->lpIInternetProtocolVtbl = &BindProtocolVtbl; + ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl; + ret->lpInternetPriorityVtbl = &InternetPriorityVtbl; + ret->lpServiceProviderVtbl = &ServiceProviderVtbl; + ret->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl; + ret->lpIInternetProtocolHandlerVtbl = &InternetProtocolHandlerVtbl;
ret->ref = 1; ret->from_urlmon = from_urlmon; + ret->apartment_thread = GetCurrentThreadId(); + ret->notif_hwnd = get_notif_hwnd(); + ret->protocol_handler = PROTOCOLHANDLER(ret); + InitializeCriticalSection(&ret->section);
URLMON_LockModule();
Modified: trunk/reactos/dll/win32/urlmon/file.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/file.c?rev... ============================================================================== --- trunk/reactos/dll/win32/urlmon/file.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/file.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -22,7 +22,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
typedef struct { - const IInternetProtocolVtbl *lpInternetProtocolVtbl; + const IInternetProtocolVtbl *lpIInternetProtocolVtbl; const IInternetPriorityVtbl *lpInternetPriorityVtbl;
HANDLE file; @@ -31,10 +31,9 @@ LONG ref; } FileProtocol;
-#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
-#define PROTOCOL_THIS(iface) DEFINE_THIS(FileProtocol, InternetProtocol, iface) +#define PROTOCOL_THIS(iface) DEFINE_THIS(FileProtocol, IInternetProtocol, iface)
static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { @@ -360,7 +359,7 @@
ret = heap_alloc(sizeof(FileProtocol));
- ret->lpInternetProtocolVtbl = &FileProtocolVtbl; + ret->lpIInternetProtocolVtbl = &FileProtocolVtbl; ret->lpInternetPriorityVtbl = &FilePriorityVtbl; ret->file = NULL; ret->priority = 0;
Modified: trunk/reactos/dll/win32/urlmon/ftp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/ftp.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/urlmon/ftp.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/ftp.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -24,14 +24,13 @@ typedef struct { Protocol base;
- const IInternetProtocolVtbl *lpInternetProtocolVtbl; + const IInternetProtocolVtbl *lpIInternetProtocolVtbl; const IInternetPriorityVtbl *lpInternetPriorityVtbl; const IWinInetHttpInfoVtbl *lpWinInetHttpInfoVtbl;
LONG ref; } FtpProtocol;
-#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl) #define INETHTTPINFO(x) ((IWinInetHttpInfo*) &(x)->lpWinInetHttpInfoVtbl)
@@ -80,7 +79,7 @@ FtpProtocol_close_connection };
-#define PROTOCOL_THIS(iface) DEFINE_THIS(FtpProtocol, InternetProtocol, iface) +#define PROTOCOL_THIS(iface) DEFINE_THIS(FtpProtocol, IInternetProtocol, iface)
static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { @@ -360,9 +359,9 @@ ret = heap_alloc_zero(sizeof(FtpProtocol));
ret->base.vtbl = &AsyncProtocolVtbl; - ret->lpInternetProtocolVtbl = &FtpProtocolVtbl; - ret->lpInternetPriorityVtbl = &FtpPriorityVtbl; - ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl; + ret->lpIInternetProtocolVtbl = &FtpProtocolVtbl; + ret->lpInternetPriorityVtbl = &FtpPriorityVtbl; + ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl; ret->ref = 1;
*ppobj = PROTOCOL(ret);
Modified: trunk/reactos/dll/win32/urlmon/gopher.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/gopher.c?r... ============================================================================== --- trunk/reactos/dll/win32/urlmon/gopher.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/gopher.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -24,13 +24,12 @@ typedef struct { Protocol base;
- const IInternetProtocolVtbl *lpInternetProtocolVtbl; + const IInternetProtocolVtbl *lpIInternetProtocolVtbl; const IInternetPriorityVtbl *lpInternetPriorityVtbl;
LONG ref; } GopherProtocol;
-#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(GopherProtocol, base, iface) @@ -67,7 +66,7 @@ GopherProtocol_close_connection };
-#define PROTOCOL_THIS(iface) DEFINE_THIS(GopherProtocol, InternetProtocol, iface) +#define PROTOCOL_THIS(iface) DEFINE_THIS(GopherProtocol, IInternetProtocol, iface)
static HRESULT WINAPI GopherProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { @@ -289,8 +288,8 @@ ret = heap_alloc_zero(sizeof(GopherProtocol));
ret->base.vtbl = &AsyncProtocolVtbl; - ret->lpInternetProtocolVtbl = &GopherProtocolVtbl; - ret->lpInternetPriorityVtbl = &GopherPriorityVtbl; + ret->lpIInternetProtocolVtbl = &GopherProtocolVtbl; + ret->lpInternetPriorityVtbl = &GopherPriorityVtbl; ret->ref = 1;
*ppobj = PROTOCOL(ret);
Modified: trunk/reactos/dll/win32/urlmon/http.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/http.c?rev... ============================================================================== --- trunk/reactos/dll/win32/urlmon/http.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/http.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -32,7 +32,7 @@ typedef struct { Protocol base;
- const IInternetProtocolVtbl *lpInternetProtocolVtbl; + const IInternetProtocolVtbl *lpIInternetProtocolVtbl; const IInternetPriorityVtbl *lpInternetPriorityVtbl; const IWinInetHttpInfoVtbl *lpWinInetHttpInfoVtbl;
@@ -43,7 +43,6 @@ LONG ref; } HttpProtocol;
-#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl) #define INETHTTPINFO(x) ((IWinInetHttpInfo*) &(x)->lpWinInetHttpInfoVtbl)
@@ -309,7 +308,7 @@ HttpProtocol_close_connection };
-#define PROTOCOL_THIS(iface) DEFINE_THIS(HttpProtocol, InternetProtocol, iface) +#define PROTOCOL_THIS(iface) DEFINE_THIS(HttpProtocol, IInternetProtocol, iface)
static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { @@ -590,9 +589,9 @@ return E_OUTOFMEMORY;
ret->base.vtbl = &AsyncProtocolVtbl; - ret->lpInternetProtocolVtbl = &HttpProtocolVtbl; - ret->lpInternetPriorityVtbl = &HttpPriorityVtbl; - ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl; + ret->lpIInternetProtocolVtbl = &HttpProtocolVtbl; + ret->lpInternetPriorityVtbl = &HttpPriorityVtbl; + ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl;
ret->https = https; ret->ref = 1;
Modified: trunk/reactos/dll/win32/urlmon/mk.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/mk.c?rev=4... ============================================================================== --- trunk/reactos/dll/win32/urlmon/mk.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/mk.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -22,16 +22,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
typedef struct { - const IInternetProtocolVtbl *lpInternetProtocolVtbl; + const IInternetProtocolVtbl *lpIInternetProtocolVtbl;
LONG ref;
IStream *stream; } MkProtocol;
-#define PROTOCOL_THIS(iface) DEFINE_THIS(MkProtocol, InternetProtocol, iface) - -#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) +#define PROTOCOL_THIS(iface) DEFINE_THIS(MkProtocol, IInternetProtocol, iface)
static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { @@ -293,7 +291,7 @@
ret = heap_alloc(sizeof(MkProtocol));
- ret->lpInternetProtocolVtbl = &MkProtocolVtbl; + ret->lpIInternetProtocolVtbl = &MkProtocolVtbl; ret->ref = 1; ret->stream = NULL;
Added: trunk/reactos/dll/win32/urlmon/protproxy.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/protproxy.... ============================================================================== --- trunk/reactos/dll/win32/urlmon/protproxy.c (added) +++ trunk/reactos/dll/win32/urlmon/protproxy.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -1,0 +1,290 @@ +/* + * Copyright 2009 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); + +#define PROTOCOL_THIS(iface) DEFINE_THIS(ProtocolProxy, IInternetProtocol, iface) + +static HRESULT WINAPI ProtocolProxy_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + + *ppv = NULL; + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = PROTOCOL(This); + }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { + TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv); + *ppv = PROTOCOL(This); + }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) { + TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv); + *ppv = PROTOCOL(This); + }else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) { + TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv); + *ppv = PROTSINK(This); + } + + if(*ppv) { + IInternetProtocol_AddRef(iface); + return S_OK; + } + + WARN("not supported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI ProtocolProxy_AddRef(IInternetProtocol *iface) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p) ref=%d\n", This, ref); + return ref; +} + +static ULONG WINAPI ProtocolProxy_Release(IInternetProtocol *iface) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + if(This->protocol_sink) + IInternetProtocolSink_Release(This->protocol_sink); + if(This->protocol) + IInternetProtocol_Release(This->protocol); + + heap_free(This); + + URLMON_UnlockModule(); + } + + return ref; +} + +static HRESULT WINAPI ProtocolProxy_Start(IInternetProtocol *iface, LPCWSTR szUrl, + IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, + DWORD grfPI, HANDLE_PTR dwReserved) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, + pOIBindInfo, grfPI, dwReserved); + + return IInternetProtocol_Start(This->protocol, szUrl, pOIProtSink, pOIBindInfo, grfPI, dwReserved); +} + +static HRESULT WINAPI ProtocolProxy_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pProtocolData); + + return IInternetProtocol_Continue(This->protocol, pProtocolData); +} + +static HRESULT WINAPI ProtocolProxy_Abort(IInternetProtocol *iface, HRESULT hrReason, + DWORD dwOptions) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProtocolProxy_Terminate(IInternetProtocol *iface, DWORD dwOptions) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%08x)\n", This, dwOptions); + + return IInternetProtocol_Terminate(This->protocol, dwOptions); +} + +static HRESULT WINAPI ProtocolProxy_Suspend(IInternetProtocol *iface) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProtocolProxy_Resume(IInternetProtocol *iface) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProtocolProxy_Read(IInternetProtocol *iface, void *pv, + ULONG cb, ULONG *pcbRead) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); + + return IInternetProtocol_Read(This->protocol, pv, cb, pcbRead); +} + +static HRESULT WINAPI ProtocolProxy_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, + DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); + return E_NOTIMPL; +} + +static HRESULT WINAPI ProtocolProxy_LockRequest(IInternetProtocol *iface, DWORD dwOptions) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + + TRACE("(%p)->(%08x)\n", This, dwOptions); + + return IInternetProtocol_LockRequest(This->protocol, dwOptions); +} + +static HRESULT WINAPI ProtocolProxy_UnlockRequest(IInternetProtocol *iface) +{ + ProtocolProxy *This = PROTOCOL_THIS(iface); + + TRACE("(%p)\n", This); + + return IInternetProtocol_UnlockRequest(This->protocol); +} + +#undef PROTOCOL_THIS + +static const IInternetProtocolVtbl ProtocolProxyVtbl = { + ProtocolProxy_QueryInterface, + ProtocolProxy_AddRef, + ProtocolProxy_Release, + ProtocolProxy_Start, + ProtocolProxy_Continue, + ProtocolProxy_Abort, + ProtocolProxy_Terminate, + ProtocolProxy_Suspend, + ProtocolProxy_Resume, + ProtocolProxy_Read, + ProtocolProxy_Seek, + ProtocolProxy_LockRequest, + ProtocolProxy_UnlockRequest +}; + +#define PROTSINK_THIS(iface) DEFINE_THIS(ProtocolProxy, IInternetProtocolSink, iface) + +static HRESULT WINAPI ProtocolProxySink_QueryInterface(IInternetProtocolSink *iface, + REFIID riid, void **ppv) +{ + ProtocolProxy *This = PROTSINK_THIS(iface); + return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv); +} + +static ULONG WINAPI ProtocolProxySink_AddRef(IInternetProtocolSink *iface) +{ + ProtocolProxy *This = PROTSINK_THIS(iface); + return IInternetProtocol_AddRef(PROTOCOL(This)); +} + +static ULONG WINAPI ProtocolProxySink_Release(IInternetProtocolSink *iface) +{ + ProtocolProxy *This = PROTSINK_THIS(iface); + return IInternetProtocol_Release(PROTOCOL(This)); +} + +static HRESULT WINAPI ProtocolProxySink_Switch(IInternetProtocolSink *iface, + PROTOCOLDATA *pProtocolData) +{ + ProtocolProxy *This = PROTSINK_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pProtocolData); + + return IInternetProtocolSink_Switch(This->protocol_sink, pProtocolData); +} + +static HRESULT WINAPI ProtocolProxySink_ReportProgress(IInternetProtocolSink *iface, + ULONG ulStatusCode, LPCWSTR szStatusText) +{ + ProtocolProxy *This = PROTSINK_THIS(iface); + + TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText)); + + switch(ulStatusCode) { + case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: + IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, szStatusText); + break; + default: + IInternetProtocolSink_ReportProgress(This->protocol_sink, ulStatusCode, szStatusText); + } + + return S_OK; +} + +static HRESULT WINAPI ProtocolProxySink_ReportData(IInternetProtocolSink *iface, + DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) +{ + ProtocolProxy *This = PROTSINK_THIS(iface); + + TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax); + + return IInternetProtocolSink_ReportData(This->protocol_sink, grfBSCF, ulProgress, ulProgressMax); +} + +static HRESULT WINAPI ProtocolProxySink_ReportResult(IInternetProtocolSink *iface, + HRESULT hrResult, DWORD dwError, LPCWSTR szResult) +{ + ProtocolProxy *This = PROTSINK_THIS(iface); + + TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult)); + + return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult); +} + +#undef PROTSINK_THIS + +static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = { + ProtocolProxySink_QueryInterface, + ProtocolProxySink_AddRef, + ProtocolProxySink_Release, + ProtocolProxySink_Switch, + ProtocolProxySink_ReportProgress, + ProtocolProxySink_ReportData, + ProtocolProxySink_ReportResult +}; + +HRESULT create_protocol_proxy(IInternetProtocol *protocol, IInternetProtocolSink *protocol_sink, ProtocolProxy **ret) +{ + ProtocolProxy *sink; + + sink = heap_alloc(sizeof(ProtocolProxy)); + if(!sink) + return E_OUTOFMEMORY; + + sink->lpIInternetProtocolVtbl = &ProtocolProxyVtbl; + sink->lpIInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl; + sink->ref = 1; + + IInternetProtocol_AddRef(protocol); + sink->protocol = protocol; + + IInternetProtocolSink_AddRef(protocol_sink); + sink->protocol_sink = protocol_sink; + + *ret = sink; + return S_OK; +}
Propchange: trunk/reactos/dll/win32/urlmon/protproxy.c ------------------------------------------------------------------------------ svn:eol-style = native
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] Sat May 23 14:20:22 2009 @@ -262,6 +262,36 @@ if(urlmon_protocol) *urlmon_protocol = FALSE; return get_protocol_cf(schema, schema_len, clsid, ret); +} + +IInternetProtocol *get_mime_filter(LPCWSTR mime) +{ + IClassFactory *cf = NULL; + IInternetProtocol *ret; + mime_filter *iter; + HRESULT hres; + + EnterCriticalSection(&session_cs); + + for(iter = mime_filter_list; iter; iter = iter->next) { + if(!strcmpW(iter->mime, mime)) { + cf = iter->cf; + break; + } + } + + LeaveCriticalSection(&session_cs); + + if(!cf) + return NULL; + + hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&ret); + if(FAILED(hres)) { + WARN("CreateInstance failed: %08x\n", hres); + return NULL; + } + + return ret; }
static HRESULT WINAPI InternetSession_QueryInterface(IInternetSession *iface,
Modified: trunk/reactos/dll/win32/urlmon/urlmon.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon.rbu... ============================================================================== --- trunk/reactos/dll/win32/urlmon/urlmon.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/urlmon.rbuild [iso-8859-1] Sat May 23 14:20:22 2009 @@ -21,6 +21,7 @@ <file>mimefilter.c</file> <file>mk.c</file> <file>protocol.c</file> + <file>protproxy.c</file> <file>regsvr.c</file> <file>sec_mgr.c</file> <file>session.c</file>
Modified: trunk/reactos/dll/win32/urlmon/urlmon_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon_mai... ============================================================================== --- trunk/reactos/dll/win32/urlmon/urlmon_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/urlmon_main.c [iso-8859-1] Sat May 23 14:20:22 2009 @@ -36,8 +36,87 @@
HINSTANCE URLMON_hInstance = 0; static HMODULE hCabinet = NULL; +static DWORD urlmon_tls;
static void init_session(BOOL); + +static struct list tls_list = LIST_INIT(tls_list); + +static CRITICAL_SECTION tls_cs; +static CRITICAL_SECTION_DEBUG tls_cs_dbg = +{ + 0, 0, &tls_cs, + { &tls_cs_dbg.ProcessLocksList, &tls_cs_dbg.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": tls") } +}; + +static CRITICAL_SECTION tls_cs = { &tls_cs_dbg, -1, 0, 0, 0, 0 }; + +tls_data_t *get_tls_data(void) +{ + tls_data_t *data; + + if(!urlmon_tls) { + DWORD tls = TlsAlloc(); + tls = InterlockedCompareExchange((LONG*)&urlmon_tls, tls, 0); + if(tls != urlmon_tls) + TlsFree(tls); + } + + data = TlsGetValue(urlmon_tls); + if(!data) { + data = heap_alloc_zero(sizeof(tls_data_t)); + if(!data) + return NULL; + + EnterCriticalSection(&tls_cs); + list_add_tail(&tls_list, &data->entry); + LeaveCriticalSection(&tls_cs); + + TlsSetValue(urlmon_tls, data); + } + + return data; +} + +static void free_tls_list(void) +{ + tls_data_t *data; + + if(!urlmon_tls) + return; + + while(!list_empty(&tls_list)) { + data = LIST_ENTRY(list_head(&tls_list), tls_data_t, entry); + list_remove(&data->entry); + heap_free(data); + } + + TlsFree(urlmon_tls); +} + +static void detach_thread(void) +{ + tls_data_t *data; + + if(!urlmon_tls) + return; + + data = TlsGetValue(urlmon_tls); + if(!data) + return; + + EnterCriticalSection(&tls_cs); + list_remove(&data->entry); + LeaveCriticalSection(&tls_cs); + + if(data->notif_hwnd) { + WARN("notif_hwnd not destroyed\n"); + DestroyWindow(data->notif_hwnd); + } + + heap_free(data); +}
/*********************************************************************** * DllMain (URLMON.init) @@ -48,7 +127,6 @@
switch(fdwReason) { case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); URLMON_hInstance = hinstDLL; init_session(TRUE); break; @@ -58,8 +136,13 @@ FreeLibrary(hCabinet); hCabinet = NULL; init_session(FALSE); + free_tls_list(); URLMON_hInstance = 0; break; + + case DLL_THREAD_DETACH: + detach_thread(); + break; } return TRUE; }
Modified: trunk/reactos/dll/win32/urlmon/urlmon_main.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon_mai... ============================================================================== --- trunk/reactos/dll/win32/urlmon/urlmon_main.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/urlmon/urlmon_main.h [iso-8859-1] Sat May 23 14:20:22 2009 @@ -34,6 +34,7 @@ #include "wininet.h"
#include "wine/unicode.h" +#include "wine/list.h"
extern HINSTANCE URLMON_hInstance; extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj); @@ -59,6 +60,7 @@
IInternetProtocolInfo *get_protocol_info(LPCWSTR); HRESULT get_protocol_handler(LPCWSTR,CLSID*,BOOL*,IClassFactory**); +IInternetProtocol *get_mime_filter(LPCWSTR); BOOL is_registered_protocol(LPCWSTR); void register_urlmon_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL);
@@ -105,6 +107,33 @@ HRESULT protocol_lock_request(Protocol*); HRESULT protocol_unlock_request(Protocol*); void protocol_close_connection(Protocol*); + +typedef struct { + const IInternetProtocolVtbl *lpIInternetProtocolVtbl; + const IInternetProtocolSinkVtbl *lpIInternetProtocolSinkVtbl; + + LONG ref; + + IInternetProtocolSink *protocol_sink; + IInternetProtocol *protocol; +} ProtocolProxy; + +#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpIInternetProtocolVtbl) +#define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpIInternetProtocolSinkVtbl) + +HRESULT create_protocol_proxy(IInternetProtocol*,IInternetProtocolSink*,ProtocolProxy**); + +typedef struct { + HWND notif_hwnd; + DWORD notif_hwnd_cnt; + + struct list entry; +} tls_data_t; + +tls_data_t *get_tls_data(void); + +HWND get_notif_hwnd(void); +void release_notif_hwnd(HWND);
static inline void *heap_alloc(size_t len) {