Jacek Caban : itss: Added ITS protocol implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 26 06:49:13 CST 2006


Module: wine
Branch: master
Commit: 1f6c8f975d4f9c16c72cfd9147a6e6f45c2c15a4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1f6c8f975d4f9c16c72cfd9147a6e6f45c2c15a4

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Dec 25 16:08:20 2006 +0100

itss: Added ITS protocol implementation.

---

 dlls/itss/Makefile.in |    2 +-
 dlls/itss/protocol.c  |  155 ++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 143 insertions(+), 14 deletions(-)

diff --git a/dlls/itss/Makefile.in b/dlls/itss/Makefile.in
index 65f8967..612e419 100644
--- a/dlls/itss/Makefile.in
+++ b/dlls/itss/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = itss.dll
-IMPORTS   = ole32 user32 advapi32 kernel32 ntdll
+IMPORTS   = urlmon ole32 user32 advapi32 kernel32 ntdll
 EXTRALIBS = -luuid
 EXTRADEFS = -DCOM_NO_WINDOWS_H
 
diff --git a/dlls/itss/protocol.c b/dlls/itss/protocol.c
index 5a192af..c278954 100644
--- a/dlls/itss/protocol.c
+++ b/dlls/itss/protocol.c
@@ -26,20 +26,36 @@
 #include "ole2.h"
 #include "urlmon.h"
 #include "itsstor.h"
+#include "chm_lib.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(itss);
 
 typedef struct {
     const IInternetProtocolVtbl  *lpInternetProtocolVtbl;
+
     LONG ref;
-} ITSProtocol;
 
-#define PROTOCOL_THIS(iface) DEFINE_THIS(ITSProtocol, InternetProtocol, iface)
+    ULONG offset;
+    struct chmFile *chm_file;
+    struct chmUnitInfo chm_object;
+} ITSProtocol;
 
 #define PROTOCOL(x)  ((IInternetProtocol*)  &(x)->lpInternetProtocolVtbl)
 
+static void release_chm(ITSProtocol *This)
+{
+    if(This->chm_file) {
+        chm_close(This->chm_file);
+        This->chm_file = NULL;
+    }
+    This->offset = 0;
+}
+
+#define PROTOCOL_THIS(iface) DEFINE_THIS(ITSProtocol, InternetProtocol, iface)
+
 static HRESULT WINAPI ITSProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
 {
     ITSProtocol *This = PROTOCOL_THIS(iface);
@@ -81,21 +97,120 @@ static ULONG WINAPI ITSProtocol_Release(
     TRACE("(%p) ref=%d\n", This, ref);
 
     if(!ref) {
+        release_chm(This);
         HeapFree(GetProcessHeap(), 0, This);
+
         ITSS_UnlockModule();
     }
 
     return ref;
 }
 
+static LPCWSTR skip_schema(LPCWSTR url)
+{
+    static const WCHAR its_schema[] = {'i','t','s',':'};
+    static const WCHAR msits_schema[] = {'m','s','-','i','t','s',':'};
+    static const WCHAR mk_schema[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':'};
+
+    if(!strncmpiW(its_schema, url, sizeof(its_schema)/sizeof(WCHAR)))
+        return url+sizeof(its_schema)/sizeof(WCHAR);
+    if(!strncmpiW(msits_schema, url, sizeof(msits_schema)/sizeof(WCHAR)))
+        return url+sizeof(msits_schema)/sizeof(WCHAR);
+    if(!strncmpiW(mk_schema, url, sizeof(mk_schema)/sizeof(WCHAR)))
+        return url+sizeof(mk_schema)/sizeof(WCHAR);
+
+    return NULL;
+}
+
+static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres)
+{
+    IInternetProtocolSink_ReportResult(sink, hres, 0, NULL);
+    return hres;
+}
+
 static HRESULT WINAPI ITSProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
         IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
         DWORD grfPI, DWORD dwReserved)
 {
     ITSProtocol *This = PROTOCOL_THIS(iface);
-    FIXME("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
+    BINDINFO bindinfo;
+    DWORD bindf = 0, len;
+    LPWSTR file_name, mime;
+    LPCWSTR object_name, path;
+    struct chmFile *chm_file;
+    struct chmUnitInfo chm_object;
+    int res;
+    HRESULT hres;
+
+    static const WCHAR separator[] = {':',':',0};
+
+    TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl), pOIProtSink,
             pOIBindInfo, grfPI, dwReserved);
-    return E_NOTIMPL;
+
+    path = skip_schema(szUrl);
+    if(!path)
+        return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
+
+    memset(&bindinfo, 0, sizeof(bindinfo));
+    bindinfo.cbSize = sizeof(BINDINFO);
+    hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
+    if(FAILED(hres)) {
+        WARN("GetBindInfo failed: %08x\n", hres);
+        return hres;
+    }
+
+    ReleaseBindInfo(&bindinfo);
+
+    object_name = strstrW(path, separator);
+    if(!object_name) {
+        WARN("invalid url\n");
+        return report_result(pOIProtSink, STG_E_FILENOTFOUND);
+    }
+
+    len = object_name-path;
+    file_name = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
+    memcpy(file_name, path, len*sizeof(WCHAR));
+    file_name[len] = 0;
+    chm_file = chm_openW(file_name);
+    if(!chm_file) {
+        WARN("Could not open chm file\n");
+        return report_result(pOIProtSink, STG_E_FILENOTFOUND);
+    }
+
+    object_name += 2;
+    memset(&chm_object, 0, sizeof(chm_object));
+    res = chm_resolve_object(chm_file, object_name, &chm_object);
+    if(res != CHM_RESOLVE_SUCCESS) {
+        WARN("Could not resolve chm object\n");
+        chm_close(chm_file);
+        return report_result(pOIProtSink, STG_E_FILENOTFOUND);
+    }
+
+    IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, object_name+1);
+
+    /* FIXME: Native doesn't use FindMimeFromData */
+    hres = FindMimeFromData(NULL, szUrl, NULL, 0, NULL, 0, &mime, 0);
+    if(SUCCEEDED(hres)) {
+        IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
+        CoTaskMemFree(mime);
+    }
+
+    hres = IInternetProtocolSink_ReportData(pOIProtSink,
+            BSCF_FIRSTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE,
+            chm_object.length, chm_object.length);
+    if(FAILED(hres)) {
+        WARN("ReportData failed: %08x\n", hres);
+        chm_close(chm_file);
+        return report_result(pOIProtSink, hres);
+    }
+
+    hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
+
+    release_chm(This); /* Native leaks handle here */
+    This->chm_file = chm_file;
+    memcpy(&This->chm_object, &chm_object, sizeof(chm_object));
+
+    return report_result(pOIProtSink, hres);
 }
 
 static HRESULT WINAPI ITSProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
@@ -116,8 +231,10 @@ static HRESULT WINAPI ITSProtocol_Abort(
 static HRESULT WINAPI ITSProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
 {
     ITSProtocol *This = PROTOCOL_THIS(iface);
-    FIXME("(%p)->(%08x)\n", This, dwOptions);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%08x)\n", This, dwOptions);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI ITSProtocol_Suspend(IInternetProtocol *iface)
@@ -138,8 +255,16 @@ static HRESULT WINAPI ITSProtocol_Read(I
         ULONG cb, ULONG *pcbRead)
 {
     ITSProtocol *This = PROTOCOL_THIS(iface);
-    FIXME("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
+
+    if(!This->chm_file)
+        return INET_E_DATA_NOT_AVAILABLE;
+
+    *pcbRead = chm_retrieve_object(This->chm_file, &This->chm_object, pv, This->offset, cb);
+    This->offset += *pcbRead;
+
+    return *pcbRead ? S_OK : S_FALSE;
 }
 
 static HRESULT WINAPI ITSProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
@@ -153,15 +278,19 @@ static HRESULT WINAPI ITSProtocol_Seek(I
 static HRESULT WINAPI ITSProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
 {
     ITSProtocol *This = PROTOCOL_THIS(iface);
-    FIXME("(%p)->(%08x)\n", This, dwOptions);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%08x)\n", This, dwOptions);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI ITSProtocol_UnlockRequest(IInternetProtocol *iface)
 {
     ITSProtocol *This = PROTOCOL_THIS(iface);
-    FIXME("(%p)\n", This);
-    return E_NOTIMPL;
+
+    TRACE("(%p)\n", This);
+
+    return S_OK;
 }
 
 #undef PROTOCOL_THIS
@@ -190,7 +319,7 @@ HRESULT ITSProtocol_create(IUnknown *pUn
 
     ITSS_LockModule();
 
-    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ITSProtocol));
+    ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ITSProtocol));
 
     ret->lpInternetProtocolVtbl = &ITSProtocolVtbl;
     ret->ref = 1;




More information about the wine-cvs mailing list