Alistair Leslie-Hughes : msxml3: Support loading windows file paths.

Alexandre Julliard julliard at winehq.org
Wed Aug 19 11:32:43 CDT 2009


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

Author: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Date:   Mon Aug 10 22:30:51 2009 +1000

msxml3: Support loading windows file paths.

---

 dlls/msxml3/main.c         |   73 ++++++++++++++++++++++++++
 dlls/msxml3/tests/domdoc.c |  124 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 197 insertions(+), 0 deletions(-)

diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c
index 358a5cb..c31a53a 100644
--- a/dlls/msxml3/main.c
+++ b/dlls/msxml3/main.c
@@ -32,6 +32,7 @@
 #include "msxml.h"
 #include "msxml2.h"
 
+#include "wine/unicode.h"
 #include "wine/debug.h"
 #include "wine/library.h"
 
@@ -39,6 +40,68 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
 
+#ifdef HAVE_LIBXML2
+
+/* Support for loading xml files from a Wine Windows drive */
+static int wineXmlMatchCallback (char const * filename)
+{
+    int nRet = 0;
+
+    TRACE("%s\n", filename);
+
+    /*
+     * We will deal with loading XML files from the file system
+     *   We only care about files that linux cannot find.
+     *    e.g. C:,D: etc
+     */
+    if(isalpha(filename[0]) && filename[1] == ':')
+        nRet = 1;
+
+    return nRet;
+}
+
+static void *wineXmlOpenCallback (char const * filename)
+{
+    BSTR sFilename = bstr_from_xmlChar( (xmlChar*)filename);
+    HANDLE hFile;
+
+    TRACE("%s\n", debugstr_w(sFilename));
+
+    hFile = CreateFileW(sFilename, GENERIC_READ,FILE_SHARE_READ, NULL,
+                       OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
+    if(hFile == INVALID_HANDLE_VALUE) hFile = 0;
+    SysFreeString(sFilename);
+    return hFile;
+}
+
+static int wineXmlReadCallback(void * context, char * buffer, int len)
+{
+    DWORD dwBytesRead;
+
+    TRACE("%p %s %d\n", context, buffer, len);
+
+    if ((context == NULL) || (buffer == NULL))
+        return(-1);
+
+    if(!ReadFile( context, buffer,len, &dwBytesRead, NULL))
+    {
+        ERR("Failed to read file\n");
+        return -1;
+    }
+
+    TRACE("Read %d\n", dwBytesRead);
+
+    return dwBytesRead;
+}
+
+static int wineXmlFileCloseCallback (void * context)
+{
+    return CloseHandle(context) ? 0 : -1;
+}
+
+#endif
+
+
 HRESULT WINAPI DllCanUnloadNow(void)
 {
     FIXME("\n");
@@ -96,6 +159,12 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
            for this thread and as default for new threads */
         xmlTreeIndentString = "\t";
         xmlThrDefTreeIndentString("\t");
+
+         /* Register callbacks for loading XML files */
+        if(xmlRegisterInputCallbacks(wineXmlMatchCallback, wineXmlOpenCallback,
+                            wineXmlReadCallback, wineXmlFileCloseCallback) == -1)
+            WARN("Failed to register callbacks\n");
+
 #endif
         init_libxslt();
         DisableThreadLibraryCalls(hInstDLL);
@@ -110,6 +179,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
         }
 #endif
 #ifdef HAVE_LIBXML2
+        /* Restore default Callbacks */
+        xmlCleanupInputCallbacks();
+        xmlRegisterDefaultInputCallbacks();
+
         xmlCleanupParser();
 #endif
         release_typelib();
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 0eddb38..2d831dd 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -150,6 +150,37 @@ static const CHAR szTypeValueXML[] =
 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
 "<string>Wine</string>";
 
+static const CHAR szBasicTransformSSXMLPart1[] =
+"<?xml version=\"1.0\"?>"
+"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
+"<xsl:output method=\"html\"/>\n"
+"<xsl:template match=\"/\">"
+"<HTML><BODY><TABLE>"
+"        <xsl:apply-templates select='document(\"";
+
+static const CHAR szBasicTransformSSXMLPart2[] =
+"\")/bottle/wine'>"
+"           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
+"        </xsl:apply-templates>"
+"</TABLE></BODY></HTML>"
+"</xsl:template>"
+"<xsl:template match=\"bottle\">"
+"   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
+"</xsl:template>"
+"<xsl:template match=\"name\">"
+"   <TD><xsl:apply-templates /></TD>"
+"</xsl:template>"
+"<xsl:template match=\"cost\">"
+"   <TD><xsl:apply-templates /></TD>"
+"</xsl:template>"
+"</xsl:stylesheet>";
+
+static const CHAR szBasicTransformXML[] =
+"<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
+
+static const CHAR szBasicTransformOutput[] =
+"<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
+
 static const WCHAR szNonExistentFile[] = {
     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
 };
@@ -3952,6 +3983,98 @@ static void test_NodeTypeValue(void)
     free_bstrs();
 }
 
+static void test_TransformWithLoadingLocalFile(void)
+{
+    IXMLDOMDocument2 *doc = NULL;
+    IXMLDOMDocument2 *xsl = NULL;
+    IXMLDOMNode *pNode;
+    VARIANT_BOOL bSucc;
+    HRESULT hr;
+    HANDLE file;
+    DWORD dwWritten;
+    char lpPathBuffer[MAX_PATH];
+    int i;
+
+    /* Create a Temp File. */
+    GetTempPathA(MAX_PATH, lpPathBuffer);
+    strcat(lpPathBuffer, "customers.xml" );
+
+    file = CreateFile(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
+    ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
+    if(file == INVALID_HANDLE_VALUE)
+        return;
+
+    WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
+    CloseHandle(file);
+
+    /* Correct path to not include a escape character. */
+    for(i=0; i < strlen(lpPathBuffer); i++)
+    {
+        if(lpPathBuffer[i] == '\\')
+            lpPathBuffer[i] = '/';
+    }
+
+    hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
+    if( hr != S_OK )
+        return;
+
+    hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&xsl );
+    if( hr != S_OK )
+    {
+        IXMLDOMDocument2_Release(doc);
+        return;
+    }
+
+    hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
+    ok(hr == S_OK, "ret %08x\n", hr );
+    ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
+    if(bSucc == VARIANT_TRUE)
+    {
+        BSTR sXSL;
+        BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
+        BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
+        BSTR sFileName = _bstr_(lpPathBuffer);
+        int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
+
+        sXSL = SysAllocStringLen(NULL, nLegnth);
+        lstrcpyW(sXSL, sPart1);
+        lstrcatW(sXSL, sFileName);
+        lstrcatW(sXSL, sPart2);
+
+        hr = IXMLDOMDocument2_loadXML(xsl, sXSL, &bSucc);
+        ok(hr == S_OK, "ret %08x\n", hr );
+        ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
+        if(bSucc == VARIANT_TRUE)
+        {
+            BSTR sResult;
+
+            hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (LPVOID*)&pNode );
+            ok(hr == S_OK, "ret %08x\n", hr );
+            if(hr == S_OK)
+            {
+                /* This will load the temp file via the XSL */
+                hr = IXMLDOMDocument2_transformNode(doc, pNode, &sResult);
+                ok(hr == S_OK, "ret %08x\n", hr );
+                if(hr == S_OK)
+                {
+                    ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
+                    SysFreeString(sResult);
+                }
+
+                IXMLDOMNode_Release(pNode);
+            }
+        }
+
+        SysFreeString(sXSL);
+    }
+
+    IXMLDOMDocument2_Release(doc);
+    IXMLDOMDocument2_Release(xsl);
+
+    DeleteFile(lpPathBuffer);
+    free_bstrs();
+}
+
 START_TEST(domdoc)
 {
     HRESULT r;
@@ -3981,6 +4104,7 @@ START_TEST(domdoc)
     test_Namespaces();
     test_FormattingXML();
     test_NodeTypeValue();
+    test_TransformWithLoadingLocalFile();
 
     CoUninitialize();
 }




More information about the wine-cvs mailing list