Jacek Caban : urlmon: Fixed handling MIME type in Binding object.
Alexandre Julliard
julliard at winehq.org
Fri Dec 14 07:39:37 CST 2007
Module: wine
Branch: master
Commit: 353bcf923f0f0b26a7c005b704698caddbbd8492
URL: http://source.winehq.org/git/wine.git/?a=commit;h=353bcf923f0f0b26a7c005b704698caddbbd8492
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Dec 13 20:25:59 2007 +0100
urlmon: Fixed handling MIME type in Binding object.
---
dlls/urlmon/binding.c | 97 +++++++++++++++++++++++++++++++++++---------
dlls/urlmon/tests/url.c | 2 +-
dlls/urlmon/urlmon_main.h | 17 ++++++++
3 files changed, 95 insertions(+), 21 deletions(-)
diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c
index 8f1ed4f..92d4fa2 100644
--- a/dlls/urlmon/binding.c
+++ b/dlls/urlmon/binding.c
@@ -80,6 +80,7 @@ struct Binding {
BINDINFO bindinfo;
DWORD bindf;
LPWSTR mime;
+ UINT clipboard_format;
LPWSTR url;
BOOL report_mime;
DWORD continue_call;
@@ -251,6 +252,75 @@ 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);
+ }
+}
+
#define STREAM_THIS(iface) DEFINE_THIS(ProtocolStream, Stream, iface)
static HRESULT WINAPI ProtocolStream_QueryInterface(IStream *iface,
@@ -725,18 +795,14 @@ 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 = heap_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_VERIFIEDMIMETYPEAVAILABLE:
- This->report_mime = FALSE;
- on_progress(This, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, szStatusText);
+ mime_available(This, szStatusText, FALSE);
break;
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
break;
@@ -764,19 +830,8 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
if(GetCurrentThreadId() != This->apartment_thread)
FIXME("called from worked hread\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);
@@ -801,6 +856,7 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
This->request_locked = SUCCEEDED(hres);
}
+ formatetc.cfFormat = This->clipboard_format;
IBindStatusCallback_OnDataAvailable(This->callback, bscf, progress,
&formatetc, &This->stgmed);
@@ -1137,6 +1193,7 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding *
ret->service_provider = NULL;
ret->stream = NULL;
ret->mime = NULL;
+ ret->clipboard_format = 0;
ret->url = NULL;
ret->apartment_thread = GetCurrentThreadId();
ret->notif_hwnd = get_notif_hwnd();
diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c
index 935e92b..91c705d 100644
--- a/dlls/urlmon/tests/url.c
+++ b/dlls/urlmon/tests/url.c
@@ -1080,7 +1080,7 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallback *iface, DWOR
ok(pformatetc != NULL, "pformatetx == NULL\n");
if(pformatetc) {
- if (mime_type[0]) todo_wine {
+ if (mime_type[0]) {
clipfmt[0] = 0;
ok(GetClipboardFormatName(pformatetc->cfFormat, clipfmt, sizeof(clipfmt)-1),
"GetClipboardFormatName failed, error %d\n", GetLastError());
diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h
index 9f31fb9..8803ffc 100644
--- a/dlls/urlmon/urlmon_main.h
+++ b/dlls/urlmon/urlmon_main.h
@@ -24,6 +24,8 @@
#include "windef.h"
#include "winbase.h"
+#include "wine/unicode.h"
+
extern HINSTANCE URLMON_hInstance;
extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
extern HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
@@ -83,4 +85,19 @@ 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 */
More information about the wine-cvs
mailing list