Jacek Caban : scrobj: Add beginning scriptlet parser implementation.

Alexandre Julliard julliard at winehq.org
Thu Sep 19 16:35:18 CDT 2019


Module: wine
Branch: master
Commit: f2fdbc3d86a8f282bff023411c74ed4a95fe44cd
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f2fdbc3d86a8f282bff023411c74ed4a95fe44cd

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Sep 19 17:28:44 2019 +0200

scrobj: Add beginning scriptlet parser implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/scrobj/Makefile.in |   2 +-
 dlls/scrobj/scrobj.c    | 150 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 151 insertions(+), 1 deletion(-)

diff --git a/dlls/scrobj/Makefile.in b/dlls/scrobj/Makefile.in
index b6965c635a..15a4032401 100644
--- a/dlls/scrobj/Makefile.in
+++ b/dlls/scrobj/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = scrobj.dll
-IMPORTS   = uuid ole32 oleaut32 advapi32
+IMPORTS   = uuid urlmon ole32 oleaut32 xmllite advapi32
 
 EXTRADLLFLAGS = -mno-cygwin
 
diff --git a/dlls/scrobj/scrobj.c b/dlls/scrobj/scrobj.c
index 87c073eb46..2bc746a179 100644
--- a/dlls/scrobj/scrobj.c
+++ b/dlls/scrobj/scrobj.c
@@ -27,6 +27,7 @@
 
 #include "initguid.h"
 #include "scrobj.h"
+#include "xmllite.h"
 
 #include "wine/debug.h"
 #include "wine/heap.h"
@@ -38,7 +39,11 @@ static HINSTANCE scrobj_instance;
 struct scriptlet_factory
 {
     IClassFactory IClassFactory_iface;
+
     LONG ref;
+
+    IXmlReader *xml_reader;
+    IMoniker *moniker;
 };
 
 typedef enum tid_t
@@ -116,6 +121,139 @@ static void release_typelib(void)
     ITypeLib_Release(typelib);
 }
 
+static const char *debugstr_xml_name(struct scriptlet_factory *factory)
+{
+    const WCHAR *str;
+    UINT len;
+    HRESULT hres;
+    hres = IXmlReader_GetLocalName(factory->xml_reader, &str, &len);
+    if (FAILED(hres)) return "#err";
+    return debugstr_wn(str, len);
+}
+
+static HRESULT next_xml_node(struct scriptlet_factory *factory, XmlNodeType *node_type)
+{
+    HRESULT hres;
+    do hres = IXmlReader_Read(factory->xml_reader, node_type);
+    while (hres == S_OK && *node_type == XmlNodeType_Whitespace);
+    return hres;
+}
+
+static BOOL is_xml_name(struct scriptlet_factory *factory, const WCHAR *name)
+{
+    const WCHAR *qname;
+    UINT len;
+    HRESULT hres;
+    hres = IXmlReader_GetQualifiedName(factory->xml_reader, &qname, &len);
+    return hres == S_OK && len == wcslen(name) && !memcmp(qname, name, len * sizeof(WCHAR));
+}
+
+static HRESULT expect_no_attributes(struct scriptlet_factory *factory)
+{
+    UINT count;
+    HRESULT hres;
+    hres = IXmlReader_GetAttributeCount(factory->xml_reader, &count);
+    if (FAILED(hres)) return hres;
+    if (!count) return S_OK;
+    FIXME("Unexpected attributes\n");
+    return E_FAIL;
+}
+
+static HRESULT parse_scriptlet_registration(struct scriptlet_factory *factory)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT parse_scriptlet_public(struct scriptlet_factory *factory)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT parse_scriptlet_script(struct scriptlet_factory *factory)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT parse_scriptlet_file(struct scriptlet_factory *factory, const WCHAR *url)
+{
+    XmlNodeType node_type;
+    IBindCtx *bind_ctx;
+    IStream *stream;
+    HRESULT hres;
+
+    hres = CreateURLMoniker(NULL, url, &factory->moniker);
+    if (FAILED(hres))
+    {
+        WARN("CreateURLMoniker failed: %08x\n", hres);
+        return hres;
+    }
+
+    hres = CreateBindCtx(0, &bind_ctx);
+    if(FAILED(hres))
+        return hres;
+
+    hres = IMoniker_BindToStorage(factory->moniker, bind_ctx, NULL, &IID_IStream, (void**)&stream);
+    IBindCtx_Release(bind_ctx);
+    if (FAILED(hres))
+        return hres;
+
+    hres = CreateXmlReader(&IID_IXmlReader, (void**)&factory->xml_reader, NULL);
+    if(SUCCEEDED(hres))
+        hres = IXmlReader_SetInput(factory->xml_reader, (IUnknown*)stream);
+    IStream_Release(stream);
+    if (FAILED(hres))
+        return hres;
+
+    hres = next_xml_node(factory, &node_type);
+    if (hres == S_OK && node_type == XmlNodeType_XmlDeclaration)
+        hres = next_xml_node(factory, &node_type);
+
+    if (node_type != XmlNodeType_Element || !is_xml_name(factory, L"component"))
+    {
+        FIXME("Unexpected %s element\n", debugstr_xml_name(factory));
+        return E_FAIL;
+    }
+
+    hres = expect_no_attributes(factory);
+    if (FAILED(hres)) return hres;
+
+    for (;;)
+    {
+        hres = next_xml_node(factory, &node_type);
+        if (FAILED(hres)) return hres;
+        if (node_type == XmlNodeType_EndElement) break;
+        if (node_type != XmlNodeType_Element)
+        {
+            FIXME("Unexpected node type %u\n", node_type);
+            return E_FAIL;
+        }
+
+        if (is_xml_name(factory, L"registration"))
+            hres = parse_scriptlet_registration(factory);
+        else if (is_xml_name(factory, L"public"))
+            hres = parse_scriptlet_public(factory);
+        else if (is_xml_name(factory, L"script"))
+            hres = parse_scriptlet_script(factory);
+        else
+        {
+            FIXME("Unexpected element %s\n", debugstr_xml_name(factory));
+            return E_NOTIMPL;
+        }
+        if (FAILED(hres)) return hres;
+    }
+
+    hres = next_xml_node(factory, &node_type);
+    if (hres != S_FALSE)
+    {
+        FIXME("Unexpected node type %u\n", node_type);
+        return E_FAIL;
+    }
+    return S_OK;
+}
+
 static inline struct scriptlet_factory *impl_from_IClassFactory(IClassFactory *iface)
 {
     return CONTAINING_RECORD(iface, struct scriptlet_factory, IClassFactory_iface);
@@ -164,7 +302,11 @@ static ULONG WINAPI scriptlet_factory_Release(IClassFactory *iface)
     TRACE("(%p) ref=%d\n", This, ref);
 
     if (!ref)
+    {
+        if (This->moniker) IMoniker_Release(This->moniker);
+        if (This->xml_reader) IXmlReader_Release(This->xml_reader);
         heap_free(This);
+    }
     return ref;
 }
 
@@ -194,6 +336,7 @@ static const struct IClassFactoryVtbl scriptlet_factory_vtbl =
 static HRESULT create_scriptlet_factory(const WCHAR *url, struct scriptlet_factory **ret)
 {
     struct scriptlet_factory *factory;
+    HRESULT hres;
 
     TRACE("%s\n", debugstr_w(url));
 
@@ -206,6 +349,13 @@ static HRESULT create_scriptlet_factory(const WCHAR *url, struct scriptlet_facto
     factory->IClassFactory_iface.lpVtbl = &scriptlet_factory_vtbl;
     factory->ref = 1;
 
+    hres = parse_scriptlet_file(factory, url);
+    if (FAILED(hres))
+    {
+        IClassFactory_Release(&factory->IClassFactory_iface);
+        return hres;
+    }
+
     *ret = factory;
     return S_OK;
 }




More information about the wine-cvs mailing list