Huw Davies : msxml3: Use url monikers to load xml.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Feb 21 13:13:06 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 7ee50b699dc599c63fc94076c2c96fe03c87463f
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=7ee50b699dc599c63fc94076c2c96fe03c87463f

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue Feb 21 11:50:59 2006 +0000

msxml3: Use url monikers to load xml.

---

 dlls/msxml3/Makefile.in |    2 
 dlls/msxml3/domdoc.c    |  204 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 187 insertions(+), 19 deletions(-)

diff --git a/dlls/msxml3/Makefile.in b/dlls/msxml3/Makefile.in
index 874d593..35e2fd3 100644
--- a/dlls/msxml3/Makefile.in
+++ b/dlls/msxml3/Makefile.in
@@ -4,7 +4,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = msxml3.dll
-IMPORTS   = oleaut32 advapi32 kernel32 ntdll
+IMPORTS   = urlmon shlwapi oleaut32 ole32 advapi32 kernel32 ntdll
 EXTRALIBS = -luuid $(LIBUNICODE) @XML2LIBS@ @XSLTLIBS@
 EXTRAINCL = @XML2INCL@ @XSLTINCL@
 
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 9e30ed5..bfccc1e 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -30,6 +30,10 @@
 #include "winnls.h"
 #include "ole2.h"
 #include "msxml2.h"
+#include "wininet.h"
+#include "urlmon.h"
+#include "winreg.h"
+#include "shlwapi.h"
 
 #include "wine/debug.h"
 
@@ -39,6 +43,124 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
 
 #ifdef HAVE_LIBXML2
 
+typedef struct {
+    const struct IBindStatusCallbackVtbl *lpVtbl;
+} bsc;
+
+static HRESULT WINAPI bsc_QueryInterface(
+    IBindStatusCallback *iface,
+    REFIID riid,
+    LPVOID *ppobj )
+{
+    if (IsEqualGUID(riid, &IID_IUnknown) ||
+        IsEqualGUID(riid, &IID_IBindStatusCallback))
+    {
+        IBindStatusCallback_AddRef( iface );
+        *ppobj = iface;
+        return S_OK;
+    }
+
+    FIXME("interface %s not implemented\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI bsc_AddRef(
+    IBindStatusCallback *iface )
+{
+    return 2;
+}
+
+static ULONG WINAPI bsc_Release(
+    IBindStatusCallback *iface )
+{
+    return 1;
+}
+
+static HRESULT WINAPI bsc_OnStartBinding(
+        IBindStatusCallback* iface,
+        DWORD dwReserved,
+        IBinding* pib)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI bsc_GetPriority(
+        IBindStatusCallback* iface,
+        LONG* pnPriority)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnLowResource(
+        IBindStatusCallback* iface,
+        DWORD reserved)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnProgress(
+        IBindStatusCallback* iface,
+        ULONG ulProgress,
+        ULONG ulProgressMax,
+        ULONG ulStatusCode,
+        LPCWSTR szStatusText)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnStopBinding(
+        IBindStatusCallback* iface,
+        HRESULT hresult,
+        LPCWSTR szError)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI bsc_GetBindInfo(
+        IBindStatusCallback* iface,
+        DWORD* grfBINDF,
+        BINDINFO* pbindinfo)
+{
+    *grfBINDF = BINDF_RESYNCHRONIZE;
+    
+    return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnDataAvailable(
+        IBindStatusCallback* iface,
+        DWORD grfBSCF,
+        DWORD dwSize,
+        FORMATETC* pformatetc,
+        STGMEDIUM* pstgmed)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI bsc_OnObjectAvailable(
+        IBindStatusCallback* iface,
+        REFIID riid,
+        IUnknown* punk)
+{
+    return S_OK;
+}
+
+const struct IBindStatusCallbackVtbl bsc_vtbl =
+{
+    bsc_QueryInterface,
+    bsc_AddRef,
+    bsc_Release,
+    bsc_OnStartBinding,
+    bsc_GetPriority,
+    bsc_OnLowResource,
+    bsc_OnProgress,
+    bsc_OnStopBinding,
+    bsc_GetBindInfo,
+    bsc_OnDataAvailable,
+    bsc_OnObjectAvailable
+};
+
+static bsc domdoc_bsc = { &bsc_vtbl };
+
 typedef struct _domdoc
 {
     const struct IXMLDOMDocumentVtbl *lpVtbl;
@@ -750,39 +872,85 @@ static xmlDocPtr doparse( char *ptr, int
 
 static xmlDocPtr doread( LPWSTR filename )
 {
-    HANDLE handle, mapping;
-    DWORD len;
     xmlDocPtr xmldoc = NULL;
-    char *ptr;
+    HRESULT hr;
+    IBindCtx *pbc;
+    IStream *stream, *memstream;
+    WCHAR url[INTERNET_MAX_URL_LENGTH];
+    BYTE buf[4096];
+    DWORD read, written;
 
     TRACE("%s\n", debugstr_w( filename ));
 
-    handle = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ,
-                         NULL, OPEN_EXISTING, 0, NULL );
-    if( handle == INVALID_HANDLE_VALUE )
-        return xmldoc;
+    if(!PathIsURLW(filename))
+    {
+        WCHAR fullpath[MAX_PATH];
+        DWORD needed = sizeof(url)/sizeof(WCHAR);
+
+        if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
+        {
+            WARN("can't find path\n");
+            return NULL;
+        }
 
-    len = GetFileSize( handle, NULL );
-    if( len != INVALID_FILE_SIZE || GetLastError() == NO_ERROR )
+        if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
+        {
+            ERR("can't create url from path\n");
+            return NULL;
+        }
+        filename = url;
+    }
+
+    hr = CreateBindCtx(0, &pbc);
+    if(SUCCEEDED(hr))
     {
-        mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
-        if ( mapping )
+        hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
+        if(SUCCEEDED(hr))
         {
-            ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, len );
-            if ( ptr )
+            IMoniker *moniker;
+            hr = CreateURLMoniker(NULL, filename, &moniker);
+            if(SUCCEEDED(hr))
             {
-                xmldoc = doparse( ptr, len );
-                UnmapViewOfFile( ptr );
+                hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
+                IMoniker_Release(moniker);
             }
-            CloseHandle( mapping );
         }
+        IBindCtx_Release(pbc);
+    }
+    if(FAILED(hr))
+        return NULL;
+
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
+    if(FAILED(hr))
+    {
+        IStream_Release(stream);
+        return NULL;
     }
-    CloseHandle( handle );
 
+    do
+    {
+        IStream_Read(stream, buf, sizeof(buf), &read);
+        hr = IStream_Write(memstream, buf, read, &written);
+    } while(SUCCEEDED(hr) && written != 0 && read != 0);
+
+    if(SUCCEEDED(hr))
+    {
+        HGLOBAL hglobal;
+        hr = GetHGlobalFromStream(memstream, &hglobal);
+        if(SUCCEEDED(hr))
+        {
+            DWORD len = GlobalSize(hglobal);
+            char *ptr = GlobalLock(hglobal);
+            if(len != 0)
+                xmldoc = doparse( ptr, len );
+            GlobalUnlock(hglobal);
+        }
+    }
+    IStream_Release(memstream);
+    IStream_Release(stream);
     return xmldoc;
 }
 
-
 static HRESULT WINAPI domdoc_load(
     IXMLDOMDocument *iface,
     VARIANT xmlSource,




More information about the wine-cvs mailing list