msxml3: Use url monikers to load xml
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Tue Feb 21 05:50:59 CST 2006
Huw Davies <huw at codeweavers.com>
msxml3: Use url monikers to load xml.
--
Huw Davies
huw at codeweavers.com
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-patches
mailing list