[PATCH v2 02/11] msscript.ocx: Add initial IScriptModule stub implementation.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Jun 1 11:14:34 CDT 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/msscript.ocx/msscript.c | 253 ++++++++++++++++++++++++++++++++++-
 1 file changed, 251 insertions(+), 2 deletions(-)

diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index 57200da..749bae8 100644
--- a/dlls/msscript.ocx/msscript.c
+++ b/dlls/msscript.ocx/msscript.c
@@ -50,6 +50,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msscript);
 #endif
 
 struct ScriptControl;
+typedef struct ScriptModule ScriptModule;
 typedef struct ConnectionPoint ConnectionPoint;
 
 struct ConnectionPoint {
@@ -65,6 +66,19 @@ struct named_item {
     IDispatch *disp;
 };
 
+struct module {
+    BSTR name;
+    ScriptModule *object;
+};
+
+struct ScriptModule {
+    IScriptModule IScriptModule_iface;
+    LONG ref;
+
+    ScriptControl *control;
+    struct module *module;
+};
+
 typedef struct ScriptHost {
     IActiveScriptSite IActiveScriptSite_iface;
     IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
@@ -107,6 +121,8 @@ struct ScriptControl {
     DWORD view_sink_flags;
 
     /* modules */
+    UINT num_modules;
+    struct module *modules;
     IScriptModuleCollection IScriptModuleCollection_iface;
 
     ScriptHost *host;
@@ -117,6 +133,7 @@ static HINSTANCE msscript_instance;
 typedef enum tid_t {
     IScriptControl_tid,
     IScriptModuleCollection_tid,
+    IScriptModule_tid,
     LAST_tid
 } tid_t;
 
@@ -126,6 +143,7 @@ static ITypeInfo *typeinfos[LAST_tid];
 static REFIID tid_ids[] = {
     &IID_IScriptControl,
     &IID_IScriptModuleCollection,
+    &IID_IScriptModule
 };
 
 static HRESULT load_typelib(void)
@@ -287,6 +305,11 @@ static inline ScriptControl *impl_from_IScriptModuleCollection(IScriptModuleColl
     return CONTAINING_RECORD(iface, ScriptControl, IScriptModuleCollection_iface);
 }
 
+static inline ScriptModule *impl_from_IScriptModule(IScriptModule *iface)
+{
+    return CONTAINING_RECORD(iface, ScriptModule, IScriptModule_iface);
+}
+
 static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
 {
     return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
@@ -561,6 +584,216 @@ static const IServiceProviderVtbl ServiceProviderVtbl = {
     ServiceProvider_QueryService
 };
 
+static void release_modules(ScriptControl *control)
+{
+    UINT i = control->num_modules - 1;
+
+    if (!control->modules) return;
+    do
+    {
+        struct module *module = &control->modules[i];
+        if (module->object)
+        {
+            module->object->control = NULL;
+            IScriptControl_Release(&control->IScriptControl_iface);
+        }
+        SysFreeString(module->name);
+    } while (i--);
+
+    heap_free(control->modules);
+}
+
+static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
+        IsEqualGUID(&IID_IScriptModule, riid))
+    {
+        *ppv = &This->IScriptModule_iface;
+    }
+    else
+    {
+        WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI ScriptModule_AddRef(IScriptModule *iface)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI ScriptModule_Release(IScriptModule *iface)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if (!ref)
+    {
+        if (This->control)
+        {
+            This->module->object = NULL;
+            IScriptControl_Release(&This->control->IScriptControl_iface);
+        }
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI ScriptModule_GetTypeInfoCount(IScriptModule *iface, UINT *pctinfo)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    TRACE("(%p)->(%p)\n", This, pctinfo);
+
+    *pctinfo = 1;
+    return S_OK;
+}
+
+static HRESULT WINAPI ScriptModule_GetTypeInfo(IScriptModule *iface, UINT iTInfo,
+        LCID lcid, ITypeInfo **ppTInfo)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
+
+    return get_typeinfo(IScriptModule_tid, ppTInfo);
+}
+
+static HRESULT WINAPI ScriptModule_GetIDsOfNames(IScriptModule *iface, REFIID riid,
+        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+    ITypeInfo *typeinfo;
+    HRESULT hr;
+
+    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
+
+    hr = get_typeinfo(IScriptModule_tid, &typeinfo);
+    if (SUCCEEDED(hr))
+    {
+        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
+        ITypeInfo_Release(typeinfo);
+    }
+
+    return hr;
+}
+
+static HRESULT WINAPI ScriptModule_Invoke(IScriptModule *iface, DISPID dispIdMember,
+        REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
+        EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+    ITypeInfo *typeinfo;
+    HRESULT hr;
+
+    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
+           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+
+    hr = get_typeinfo(IScriptModule_tid, &typeinfo);
+    if(SUCCEEDED(hr))
+    {
+        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
+                              pDispParams, pVarResult, pExcepInfo, puArgErr);
+        ITypeInfo_Release(typeinfo);
+    }
+
+    return hr;
+}
+
+static HRESULT WINAPI ScriptModule_get_Name(IScriptModule *iface, BSTR *pbstrName)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    FIXME("(%p)->(%p)\n", This, pbstrName);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptModule_get_CodeObject(IScriptModule *iface, IDispatch **ppdispObject)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    FIXME("(%p)->(%p)\n", This, ppdispObject);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptModule_get_Procedures(IScriptModule *iface, IScriptProcedureCollection **ppdispProcedures)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    FIXME("(%p)->(%p)\n", This, ppdispProcedures);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptModule_AddCode(IScriptModule *iface, BSTR code)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    FIXME("(%p)->(%s)\n", This, debugstr_w(code));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptModule_Eval(IScriptModule *iface, BSTR expression, VARIANT *res)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    FIXME("(%p)->(%s, %p)\n", This, debugstr_w(expression), res);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptModule_ExecuteStatement(IScriptModule *iface, BSTR statement)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    FIXME("(%p)->(%s)\n", This, debugstr_w(statement));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptModule_Run(IScriptModule *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
+{
+    ScriptModule *This = impl_from_IScriptModule(iface);
+
+    FIXME("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
+
+    return E_NOTIMPL;
+}
+
+static const IScriptModuleVtbl ScriptModuleVtbl = {
+    ScriptModule_QueryInterface,
+    ScriptModule_AddRef,
+    ScriptModule_Release,
+    ScriptModule_GetTypeInfoCount,
+    ScriptModule_GetTypeInfo,
+    ScriptModule_GetIDsOfNames,
+    ScriptModule_Invoke,
+    ScriptModule_get_Name,
+    ScriptModule_get_CodeObject,
+    ScriptModule_get_Procedures,
+    ScriptModule_AddCode,
+    ScriptModule_Eval,
+    ScriptModule_ExecuteStatement,
+    ScriptModule_Run
+};
+
 static HRESULT WINAPI ScriptModuleCollection_QueryInterface(IScriptModuleCollection *iface, REFIID riid, void **ppv)
 {
     ScriptControl *This = impl_from_IScriptModuleCollection(iface);
@@ -677,9 +910,12 @@ static HRESULT WINAPI ScriptModuleCollection_get_Count(IScriptModuleCollection *
 {
     ScriptControl *This = impl_from_IScriptModuleCollection(iface);
 
-    FIXME("(%p)->(%p)\n", This, plCount);
+    TRACE("(%p)->(%p)\n", This, plCount);
 
-    return E_NOTIMPL;
+    if (!plCount) return E_POINTER;
+
+    *plCount = This->num_modules;
+    return S_OK;
 }
 
 static HRESULT WINAPI ScriptModuleCollection_Add(IScriptModuleCollection *iface, BSTR name,
@@ -850,6 +1086,7 @@ static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
             IOleClientSite_Release(This->site);
         if (This->host)
             release_script_engine(This->host);
+        release_modules(This);
         heap_free(This);
     }
 
@@ -939,6 +1176,7 @@ static HRESULT WINAPI ScriptControl_get_Language(IScriptControl *iface, BSTR *p)
 static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR language)
 {
     ScriptControl *This = impl_from_IScriptControl(iface);
+    struct module *modules;
     CLSID clsid;
 
     TRACE("(%p)->(%s)\n", This, debugstr_w(language));
@@ -946,11 +1184,19 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan
     if (language && FAILED(CLSIDFromProgID(language, &clsid)))
         return CTL_E_INVALIDPROPERTYVALUE;
 
+    /* Alloc new global module */
+    modules = heap_alloc_zero(sizeof(*modules));
+    if (!modules) return E_OUTOFMEMORY;
+
     if (This->host) {
         release_script_engine(This->host);
         This->host = NULL;
     }
 
+    release_modules(This);
+    This->modules = modules;
+    This->num_modules = 1;
+
     if (!language)
         return S_OK;
 
@@ -1080,6 +1326,8 @@ static HRESULT WINAPI ScriptControl_get_Modules(IScriptControl *iface, IScriptMo
 
     TRACE("(%p)->(%p)\n", This, p);
 
+    if (!This->modules) return E_FAIL;
+
     *p = &This->IScriptModuleCollection_iface;
     IScriptControl_AddRef(iface);
     return S_OK;
@@ -2201,6 +2449,7 @@ static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknow
     script_control->allow_ui = VARIANT_TRUE;
     script_control->use_safe_subset = VARIANT_FALSE;
     script_control->state = Initialized;
+    script_control->modules = NULL;
 
     ConnectionPoint_Init(&script_control->cp_scsource, script_control, &DIID_DScriptControlSource);
     ConnectionPoint_Init(&script_control->cp_propnotif, script_control, &IID_IPropertyNotifySink);
-- 
2.21.0




More information about the wine-devel mailing list