Module: wine Branch: master Commit: 299ce6c18eb7dfaf8f339658b2f5e606936fb8bc URL: http://source.winehq.org/git/wine.git/?a=commit;h=299ce6c18eb7dfaf8f339658b2...
Author: Jacek Caban jacek@codeweavers.com Date: Thu May 14 00:49:01 2009 +0200
urlmon: Added PI_MIMEVERIFICATION support.
---
dlls/urlmon/bindprot.c | 163 ++++++++++++++++++++++++++++++++++++----------- 1 files changed, 125 insertions(+), 38 deletions(-)
diff --git a/dlls/urlmon/bindprot.c b/dlls/urlmon/bindprot.c index 7235b63..d431095 100644 --- a/dlls/urlmon/bindprot.c +++ b/dlls/urlmon/bindprot.c @@ -50,6 +50,7 @@ struct BindProtocol { LONG priority;
BOOL reported_result; + BOOL reported_mime; BOOL from_urlmon; DWORD pi;
@@ -59,6 +60,11 @@ struct BindProtocol {
CRITICAL_SECTION section; task_header_t *task_queue_head, *task_queue_tail; + + BYTE *buf; + DWORD buf_size; + LPWSTR mime; + LPWSTR url; };
#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) @@ -67,6 +73,9 @@ struct BindProtocol { #define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl) #define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl)
+#define BUFFER_SIZE 2048 +#define MIME_TEST_SIZE 255 + #define WM_MK_CONTINUE (WM_USER+101) #define WM_MK_RELEASE (WM_USER+102)
@@ -272,6 +281,9 @@ static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface) 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(); @@ -300,6 +312,7 @@ static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl return E_INVALIDARG;
This->pi = grfPI; + This->url = heap_strdupW(szUrl);
hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider, (void**)&service_provider); @@ -417,11 +430,30 @@ static HRESULT WINAPI BindProtocol_Read(IInternetProtocol *iface, void *pv, { BindProtocol *This = PROTOCOL_THIS(iface); ULONG read = 0; - HRESULT hres; + HRESULT hres = S_OK;
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
- hres = IInternetProtocol_Read(This->protocol, pv, cb, &read); + 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, &cread); + read += cread; + }
*pcbRead = read; return hres; @@ -674,6 +706,47 @@ static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface return IInternetProtocolSink_Switch(This->protocol_sink, pProtocolData); }
+static void report_progress(BindProtocol *This, ULONG status_code, LPCWSTR status_text) +{ + switch(status_code) { + case BINDSTATUS_FINDINGRESOURCE: + case BINDSTATUS_CONNECTING: + case BINDSTATUS_BEGINDOWNLOADDATA: + case BINDSTATUS_SENDINGREQUEST: + 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->reported_mime) { + heap_free(This->mime); + This->mime = heap_strdupW(status_text); + } + + if(This->protocol_sink && !(This->pi & PI_MIMEVERIFICATION)) + IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text); + break; + + case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: + if(!This->reported_mime) { + heap_free(This->mime); + This->mime = heap_strdupW(status_text); + } + + if(This->protocol_sink) { + This->reported_mime = TRUE; + IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, status_text); + } + break; + + default: + FIXME("unsupported ulStatusCode %u\n", status_code); + } +} + typedef struct { task_header_t header;
@@ -685,63 +758,79 @@ static void on_progress_proc(BindProtocol *This, task_header_t *t) { on_progress_task_t *task = (on_progress_task_t*)t;
- IInternetProtocolSink_ReportProgress(This->protocol_sink, task->status_code, task->status_text); + report_progress(This, task->status_code, task->status_text);
heap_free(task->status_text); heap_free(task); }
-static void report_progress(BindProtocol *This, ULONG status_code, LPCWSTR status_text) +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)) { - IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text); + report_progress(This, ulStatusCode, szStatusText); }else { on_progress_task_t *task;
task = heap_alloc(sizeof(on_progress_task_t));
- task->status_code = status_code; - task->status_text = heap_strdupW(status_text); + task->status_code = ulStatusCode; + task->status_text = heap_strdupW(szStatusText);
push_task(This, &task->header, on_progress_proc); } + + return S_OK; }
-static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, - ULONG ulStatusCode, LPCWSTR szStatusText) +static HRESULT report_data(BindProtocol *This, DWORD bscf, ULONG progress, ULONG progress_max) { - BindProtocol *This = PROTSINK_THIS(iface); + if(!This->protocol_sink) + return S_OK;
- TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText)); + if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) { + DWORD read = 0; + LPWSTR mime; + HRESULT hres;
- switch(ulStatusCode) { - case BINDSTATUS_FINDINGRESOURCE: - case BINDSTATUS_CONNECTING: - case BINDSTATUS_BEGINDOWNLOADDATA: - case BINDSTATUS_SENDINGREQUEST: - case BINDSTATUS_CACHEFILENAMEAVAILABLE: - case BINDSTATUS_DIRECTBIND: - case BINDSTATUS_ACCEPTRANGES: - case BINDSTATUS_MIMETYPEAVAILABLE: - if(!This->protocol_sink) - return S_OK; - report_progress(This, ulStatusCode, szStatusText); - break; + if(!This->buf) { + This->buf = heap_alloc(BUFFER_SIZE); + if(!This->buf) + return E_OUTOFMEMORY; + }
- case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: - if(!This->protocol_sink) + do { + read = 0; + hres = IInternetProtocol_Read(This->protocol, This->buf+This->buf_size, BUFFER_SIZE-This->buf_size, &read); + if(hres != S_OK) + break; + This->buf_size += read; + }while(This->buf_size < MIME_TEST_SIZE); + if(FAILED(hres) && hres != E_PENDING) + return hres; + + This->buf_size += read; + if(This->buf_size < MIME_TEST_SIZE && hres != S_FALSE) return S_OK; - report_progress(This, - This->from_urlmon ? BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE, - szStatusText); - break;
- 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; + + heap_free(This->mime); + This->mime = heap_strdupW(mime); + CoTaskMemFree(mime); + + This->reported_mime = TRUE; + IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, This->mime); }
- return S_OK; + return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max); }
typedef struct { @@ -755,9 +844,7 @@ static void report_data_proc(BindProtocol *This, task_header_t *t) { report_data_task_t *task = (report_data_task_t*)t;
- if(This->protocol_sink) - IInternetProtocolSink_ReportData(This->protocol_sink, task->bscf, task->progress, task->progress_max); - + report_data(This, task->bscf, task->progress, task->progress_max); heap_free(task); }
@@ -786,7 +873,7 @@ static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *i return S_OK; }
- return IInternetProtocolSink_ReportData(This->protocol_sink, grfBSCF, ulProgress, ulProgressMax); + return report_data(This, grfBSCF, ulProgress, ulProgressMax); }
typedef struct {