msxml3: Support loading windows file paths.
This commit is contained in:
parent
c70f3816ab
commit
89c92bee63
@ -32,6 +32,7 @@
|
|||||||
#include "msxml.h"
|
#include "msxml.h"
|
||||||
#include "msxml2.h"
|
#include "msxml2.h"
|
||||||
|
|
||||||
|
#include "wine/unicode.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/library.h"
|
#include "wine/library.h"
|
||||||
|
|
||||||
@ -39,6 +40,68 @@
|
|||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
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)
|
HRESULT WINAPI DllCanUnloadNow(void)
|
||||||
{
|
{
|
||||||
FIXME("\n");
|
FIXME("\n");
|
||||||
@ -96,6 +159,12 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||||||
for this thread and as default for new threads */
|
for this thread and as default for new threads */
|
||||||
xmlTreeIndentString = "\t";
|
xmlTreeIndentString = "\t";
|
||||||
xmlThrDefTreeIndentString("\t");
|
xmlThrDefTreeIndentString("\t");
|
||||||
|
|
||||||
|
/* Register callbacks for loading XML files */
|
||||||
|
if(xmlRegisterInputCallbacks(wineXmlMatchCallback, wineXmlOpenCallback,
|
||||||
|
wineXmlReadCallback, wineXmlFileCloseCallback) == -1)
|
||||||
|
WARN("Failed to register callbacks\n");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
init_libxslt();
|
init_libxslt();
|
||||||
DisableThreadLibraryCalls(hInstDLL);
|
DisableThreadLibraryCalls(hInstDLL);
|
||||||
@ -110,6 +179,10 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBXML2
|
#ifdef HAVE_LIBXML2
|
||||||
|
/* Restore default Callbacks */
|
||||||
|
xmlCleanupInputCallbacks();
|
||||||
|
xmlRegisterDefaultInputCallbacks();
|
||||||
|
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
#endif
|
#endif
|
||||||
release_typelib();
|
release_typelib();
|
||||||
|
@ -150,6 +150,37 @@ static const CHAR szTypeValueXML[] =
|
|||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||||
"<string>Wine</string>";
|
"<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[] = {
|
static const WCHAR szNonExistentFile[] = {
|
||||||
'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
|
'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();
|
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)
|
START_TEST(domdoc)
|
||||||
{
|
{
|
||||||
HRESULT r;
|
HRESULT r;
|
||||||
@ -3981,6 +4104,7 @@ START_TEST(domdoc)
|
|||||||
test_Namespaces();
|
test_Namespaces();
|
||||||
test_FormattingXML();
|
test_FormattingXML();
|
||||||
test_NodeTypeValue();
|
test_NodeTypeValue();
|
||||||
|
test_TransformWithLoadingLocalFile();
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user