MSHTML: Added about protocol implementation

Jacek Caban jack at itma.pwr.wroc.pl
Tue Aug 2 16:30:07 CDT 2005


Changelog:
    Added about protocol implementation
-------------- next part --------------
Index: dlls/mshtml/protocol.c
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/protocol.c,v
retrieving revision 1.6
diff -u -p -r1.6 protocol.c
--- dlls/mshtml/protocol.c	2 Aug 2005 09:49:06 -0000	1.6
+++ dlls/mshtml/protocol.c	2 Aug 2005 21:23:36 -0000
@@ -138,7 +138,12 @@ static HRESULT WINAPI ClassFactory_LockS
 
 typedef struct {
     const IInternetProtocolVtbl *lpInternetProtocolVtbl;
+
     LONG ref;
+
+    BYTE *data;
+    ULONG data_len;
+    ULONG cur;
 } AboutProtocol;
 
 static HRESULT WINAPI AboutProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
@@ -184,6 +189,7 @@ static ULONG WINAPI AboutProtocol_Releas
     TRACE("(%p) ref=%lx\n", iface, ref);
 
     if(!ref) {
+        HeapFree(GetProcessHeap(), 0, This->data);
         HeapFree(GetProcessHeap(), 0, This);
         UNLOCK_MODULE();
     }
@@ -196,9 +202,53 @@ static HRESULT WINAPI AboutProtocol_Star
         DWORD grfPI, DWORD dwReserved)
 {
     AboutProtocol *This = (AboutProtocol*)iface;
-    FIXME("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
+    BINDINFO bindinfo;
+    DWORD grfBINDF = 0;
+    LPCWSTR text = NULL;
+
+    static const WCHAR html_begin[] = {0xfeff,'<','H','T','M','L','>',0};
+    static const WCHAR html_end[] = {'<','/','H','T','M','L','>',0};
+    static const WCHAR wszBlank[] = {'b','l','a','n','k',0};
+    static const WCHAR wszAbout[] = {'a','b','o','u','t',':'};
+
+    /* NOTE:
+     * the about protocol seams not to work as I would expect. It creates html document
+     * for a given url, eg. about:some_text -> <HTML>some_text</HTML> except for the case when
+     * some_text = "blank", when document is blank (<HTML></HMTL>). The same happends
+     * when the url does not have "about:" in the beginning.
+     */
+
+    TRACE("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
             pOIBindInfo, grfPI, dwReserved);
-    return E_NOTIMPL;
+
+    memset(&bindinfo, 0, sizeof(bindinfo));
+    bindinfo.cbSize = sizeof(BINDINFO);
+    IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
+
+    if(strlenW(szUrl)>=sizeof(wszAbout)/sizeof(WCHAR) && !memcmp(wszAbout, szUrl, sizeof(wszAbout))) {
+        text = szUrl + sizeof(wszAbout)/sizeof(WCHAR);
+        if(!strcmpW(wszBlank, text))
+            text = NULL;
+    }
+
+    This->data_len = sizeof(html_begin)+sizeof(html_end)-sizeof(WCHAR) 
+        + (text ? strlenW(text)*sizeof(WCHAR) : 0);
+    This->data = HeapAlloc(GetProcessHeap(), 0, This->data_len);
+
+    memcpy(This->data, html_begin, sizeof(html_begin));
+    if(text)
+        strcatW((LPWSTR)This->data, text);
+    strcatW((LPWSTR)This->data, html_end);
+    
+    This->cur = 0;
+
+    IInternetProtocolSink_ReportData(pOIProtSink,
+            BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
+            This->data_len, This->data_len);
+
+    IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI AboutProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData)
@@ -219,8 +269,8 @@ static HRESULT WINAPI AboutProtocol_Abor
 static HRESULT WINAPI AboutProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
 {
     AboutProtocol *This = (AboutProtocol*)iface;
-    FIXME("(%p)->(%08lx)\n", This, dwOptions);
-    return E_NOTIMPL;
+    TRACE("(%p)->(%08lx)\n", This, dwOptions);
+    return S_OK;
 }
 
 static HRESULT WINAPI AboutProtocol_Suspend(IInternetProtocol *iface)
@@ -240,8 +290,21 @@ static HRESULT WINAPI AboutProtocol_Resu
 static HRESULT WINAPI AboutProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
 {
     AboutProtocol *This = (AboutProtocol*)iface;
-    FIXME("(%p)->(%lu %p)\n", This, cb, pcbRead);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%p %lu %p)\n", This, pv, cb, pcbRead);
+
+    if(!This->data)
+        return E_FAIL;
+
+    *pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb);
+
+    if(!*pcbRead)
+        return S_FALSE;
+
+    memcpy(pv, This->data, *pcbRead);
+    This->cur += *pcbRead;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI AboutProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
@@ -255,15 +318,19 @@ static HRESULT WINAPI AboutProtocol_Seek
 static HRESULT WINAPI AboutProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
 {
     AboutProtocol *This = (AboutProtocol*)iface;
-    FIXME("(%p)->(%ld)\n", This, dwOptions);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%ld)\n", This, dwOptions);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI AboutProtocol_UnlockRequest(IInternetProtocol *iface)
 {
     AboutProtocol *This = (AboutProtocol*)iface;
-    FIXME("(%p)\n", This);
-    return E_NOTIMPL;
+
+    TRACE("(%p)\n", This);
+
+    return S_OK;
 }
 
 static const IInternetProtocolVtbl AboutProtocolVtbl = {
@@ -293,6 +360,10 @@ static HRESULT WINAPI AboutProtocolFacto
     ret = HeapAlloc(GetProcessHeap(), 0, sizeof(AboutProtocol));
     ret->lpInternetProtocolVtbl = &AboutProtocolVtbl;
     ret->ref = 0;
+
+    ret->data = NULL;
+    ret->data_len = 0;
+    ret->cur = 0;
 
     hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);
 
Index: dlls/mshtml/tests/protocol.c
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/tests/protocol.c,v
retrieving revision 1.2
diff -u -p -r1.2 protocol.c
--- dlls/mshtml/tests/protocol.c	18 Jul 2005 09:06:22 -0000	1.2
+++ dlls/mshtml/tests/protocol.c	2 Aug 2005 21:23:37 -0000
@@ -29,6 +29,7 @@
 #include "initguid.h"
 
 DEFINE_GUID(CLSID_ResProtocol, 0x3050F3BC, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
+DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
 
 static BOOL expect_GetBindInfo = FALSE, called_GetBindInfo = FALSE;
 static BOOL expect_ReportProgress = FALSE, called_ReportProgress = FALSE;
@@ -312,6 +313,83 @@ static void test_res_protocol(void)
             protocol_start(protocol, blank_url);
             hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
             ok(hres == S_OK, "Read failed: %08lx\n", hres);
+            hres = IInternetProtocol_Terminate(protocol, 0);
+            ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
+
+            IInternetProtocol_Release(protocol);
+        }
+
+        IClassFactory_Release(factory);
+    }
+
+    IUnknown_Release(unk);
+}
+
+static void test_about_protocol(void)
+{
+    IInternetProtocolInfo *protocol_info;
+    IUnknown *unk;
+    IClassFactory *factory;
+    HRESULT hres;
+
+    static const WCHAR blank_url[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
+    static const WCHAR test_url[] = {'a','b','o','u','t',':','t','e','s','t',0};
+    static const WCHAR res_url[] = {'r','e','s',':','b','l','a','n','k',0};
+    static const WCHAR blank_html[] = {0xfeff,'<','H','T','M','L','>','<','/','H','T','M','L','>',0};
+    static const WCHAR test_html[] =
+        {0xfeff,'<','H','T','M','L','>','t','e','s','t','<','/','H','T','M','L','>',0};
+
+    hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
+    ok(hres == S_OK, "CoGetClassObject failed: %08lx\n", hres);
+    if(!SUCCEEDED(hres))
+        return;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
+    ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08lx\n", hres);
+    if(SUCCEEDED(hres)) {
+        /* TODO: test IInternetProtocol interface */
+        IInternetProtocol_Release(protocol_info);
+    }
+
+    hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
+    ok(hres == S_OK, "Could not get IClassFactory interface\n");
+    if(SUCCEEDED(hres)) {
+        IInternetProtocol *protocol;
+        BYTE buf[512];
+        ULONG cb;
+        hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
+        ok(hres == S_OK, "Could not get IInternetProtocol: %08lx\n", hres);
+
+        if(SUCCEEDED(hres)) {
+            protocol_start(protocol, blank_url);
+            hres = IInternetProtocol_LockRequest(protocol, 0);
+            ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
+            hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
+            ok(hres == S_OK, "Read failed: %08lx\n", hres);
+            ok(cb == sizeof(blank_html), "cb=%ld, expected %d\n", cb, sizeof(blank_html));
+            ok(!memcmp(buf, blank_html, cb), "Readed wrong data\n");
+            hres = IInternetProtocol_UnlockRequest(protocol);
+            ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
+
+            protocol_start(protocol, test_url);
+            hres = IInternetProtocol_LockRequest(protocol, 0);
+            ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
+            hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
+            ok(hres == S_OK, "Read failed: %08lx\n", hres);
+            ok(cb == sizeof(test_html), "cb=%ld, expected %d\n", cb, sizeof(test_html));
+            ok(!memcmp(buf, test_html, cb), "Readed wrong data\n");
+            hres = IInternetProtocol_UnlockRequest(protocol);
+            ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
+
+            protocol_start(protocol, res_url);
+            hres = IInternetProtocol_LockRequest(protocol, 0);
+            ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
+            hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
+            ok(hres == S_OK, "Read failed: %08lx\n", hres);
+            ok(cb == sizeof(blank_html), "cb=%ld, expected %d\n", cb, sizeof(blank_html));
+            ok(!memcmp(buf, blank_html, cb), "Readed wrong data\n");
+            hres = IInternetProtocol_UnlockRequest(protocol);
+            ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
 
             IInternetProtocol_Release(protocol);
         }
@@ -327,6 +405,7 @@ START_TEST(protocol)
     OleInitialize(NULL);
 
     test_res_protocol();
+    test_about_protocol();
 
     OleUninitialize();
 }


More information about the wine-patches mailing list