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