[PATCH 01/11] msscript.ocx: Add the ScriptError stub implementation.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Mon Aug 24 09:56:10 CDT 2020
The error object has to be separate from the control, as it can be referenced
while the control is released. It is also available even without a script
host, and in fact the same object will be used (same address) when a host
is instantiated.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
dlls/msscript.ocx/msscript.c | 240 ++++++++++++++++++++++++++++-
dlls/msscript.ocx/tests/msscript.c | 39 +++--
2 files changed, 256 insertions(+), 23 deletions(-)
diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index d493065..c92a86a 100644
--- a/dlls/msscript.ocx/msscript.c
+++ b/dlls/msscript.ocx/msscript.c
@@ -119,6 +119,11 @@ struct procedure_enum {
ScriptProcedureCollection *procedures;
};
+typedef struct {
+ IScriptError IScriptError_iface;
+ LONG ref;
+} ScriptError;
+
struct ScriptHost {
IActiveScriptSite IActiveScriptSite_iface;
IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
@@ -164,12 +169,14 @@ struct ScriptControl {
IScriptModuleCollection IScriptModuleCollection_iface;
ScriptHost *host;
+ ScriptError *error;
};
static HINSTANCE msscript_instance;
typedef enum tid_t {
IScriptControl_tid,
+ IScriptError_tid,
IScriptModuleCollection_tid,
IScriptModule_tid,
IScriptProcedureCollection_tid,
@@ -182,6 +189,7 @@ static ITypeInfo *typeinfos[LAST_tid];
static REFIID tid_ids[] = {
&IID_IScriptControl,
+ &IID_IScriptError,
&IID_IScriptModuleCollection,
&IID_IScriptModule,
&IID_IScriptProcedureCollection,
@@ -516,6 +524,11 @@ static inline ScriptModule *impl_from_IScriptModule(IScriptModule *iface)
return CONTAINING_RECORD(iface, ScriptModule, IScriptModule_iface);
}
+static inline ScriptError *impl_from_IScriptError(IScriptError *iface)
+{
+ return CONTAINING_RECORD(iface, ScriptError, IScriptError_iface);
+}
+
static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
{
return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
@@ -2086,6 +2099,212 @@ static const IScriptModuleCollectionVtbl ScriptModuleCollectionVtbl = {
ScriptModuleCollection_Add
};
+static HRESULT WINAPI ScriptError_QueryInterface(IScriptError *iface, REFIID riid, void **ppv)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
+ IsEqualGUID(&IID_IScriptError, riid))
+ {
+ *ppv = &This->IScriptError_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 ScriptError_AddRef(IScriptError *iface)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+ LONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI ScriptError_Release(IScriptError *iface)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+ LONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if (!ref)
+ {
+ heap_free(This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI ScriptError_GetTypeInfoCount(IScriptError *iface, UINT *pctinfo)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ TRACE("(%p)->(%p)\n", This, pctinfo);
+
+ *pctinfo = 1;
+ return S_OK;
+}
+
+static HRESULT WINAPI ScriptError_GetTypeInfo(IScriptError *iface, UINT iTInfo,
+ LCID lcid, ITypeInfo **ppTInfo)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
+
+ return get_typeinfo(IScriptError_tid, ppTInfo);
+}
+
+static HRESULT WINAPI ScriptError_GetIDsOfNames(IScriptError *iface, REFIID riid,
+ LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+ ITypeInfo *typeinfo;
+ HRESULT hr;
+
+ TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
+
+ hr = get_typeinfo(IScriptError_tid, &typeinfo);
+ if (SUCCEEDED(hr))
+ {
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
+ ITypeInfo_Release(typeinfo);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI ScriptError_Invoke(IScriptError *iface, DISPID dispIdMember,
+ REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
+ EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+ ScriptError *This = impl_from_IScriptError(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(IScriptError_tid, &typeinfo);
+ if(SUCCEEDED(hr))
+ {
+ hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
+ pDispParams, pVarResult, pExcepInfo, puArgErr);
+ ITypeInfo_Release(typeinfo);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI ScriptError_get_Number(IScriptError *iface, LONG *plNumber)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->(%p)\n", This, plNumber);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptError_get_Source(IScriptError *iface, BSTR *pbstrSource)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->(%p)\n", This, pbstrSource);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptError_get_Description(IScriptError *iface, BSTR *pbstrDescription)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->(%p)\n", This, pbstrDescription);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptError_get_HelpFile(IScriptError *iface, BSTR *pbstrHelpFile)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->(%p)\n", This, pbstrHelpFile);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptError_get_HelpContext(IScriptError *iface, LONG *plHelpContext)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->(%p)\n", This, plHelpContext);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptError_get_Text(IScriptError *iface, BSTR *pbstrText)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->(%p)\n", This, pbstrText);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptError_get_Line(IScriptError *iface, LONG *plLine)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->(%p)\n", This, plLine);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptError_get_Column(IScriptError *iface, LONG *plColumn)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->(%p)\n", This, plColumn);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptError_Clear(IScriptError *iface)
+{
+ ScriptError *This = impl_from_IScriptError(iface);
+
+ FIXME("(%p)->()\n", This);
+
+ return E_NOTIMPL;
+}
+
+static const IScriptErrorVtbl ScriptErrorVtbl = {
+ ScriptError_QueryInterface,
+ ScriptError_AddRef,
+ ScriptError_Release,
+ ScriptError_GetTypeInfoCount,
+ ScriptError_GetTypeInfo,
+ ScriptError_GetIDsOfNames,
+ ScriptError_Invoke,
+ ScriptError_get_Number,
+ ScriptError_get_Source,
+ ScriptError_get_Description,
+ ScriptError_get_HelpFile,
+ ScriptError_get_HelpContext,
+ ScriptError_get_Text,
+ ScriptError_get_Line,
+ ScriptError_get_Column,
+ ScriptError_Clear
+};
+
static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
{
IObjectSafety *objsafety;
@@ -2233,6 +2452,7 @@ static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
release_modules(This, FALSE);
IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
}
+ IScriptError_Release(&This->error->IScriptError_iface);
heap_free(This);
}
@@ -2513,8 +2733,14 @@ static HRESULT WINAPI ScriptControl_get_Modules(IScriptControl *iface, IScriptMo
static HRESULT WINAPI ScriptControl_get_Error(IScriptControl *iface, IScriptError **p)
{
ScriptControl *This = impl_from_IScriptControl(iface);
- FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%p)\n", This, p);
+
+ if (!p) return E_POINTER;
+
+ *p = &This->error->IScriptError_iface;
+ IScriptError_AddRef(*p);
+ return S_OK;
}
static HRESULT WINAPI ScriptControl_get_CodeObject(IScriptControl *iface, IDispatch **p)
@@ -3543,6 +3769,13 @@ static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknow
if(!script_control)
return E_OUTOFMEMORY;
+ script_control->error = heap_alloc_zero(sizeof(*script_control->error));
+ if(!script_control->error)
+ {
+ heap_free(script_control);
+ return E_OUTOFMEMORY;
+ }
+
script_control->IScriptControl_iface.lpVtbl = &ScriptControlVtbl;
script_control->IPersistStreamInit_iface.lpVtbl = &PersistStreamInitVtbl;
script_control->IOleObject_iface.lpVtbl = &OleObjectVtbl;
@@ -3557,6 +3790,9 @@ static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknow
script_control->allow_ui = VARIANT_TRUE;
script_control->use_safe_subset = VARIANT_FALSE;
+ script_control->error->IScriptError_iface.lpVtbl = &ScriptErrorVtbl;
+ script_control->error->ref = 1;
+
ConnectionPoint_Init(&script_control->cp_scsource, script_control, &DIID_DScriptControlSource);
ConnectionPoint_Init(&script_control->cp_propnotif, script_control, &IID_IPropertyNotifySink);
diff --git a/dlls/msscript.ocx/tests/msscript.c b/dlls/msscript.ocx/tests/msscript.c
index 085913a..9bbbe4c 100644
--- a/dlls/msscript.ocx/tests/msscript.c
+++ b/dlls/msscript.ocx/tests/msscript.c
@@ -2075,15 +2075,12 @@ static void _check_error(IScriptControl *sc, LONG exp_num, int line)
hr = IScriptControl_get_Error(sc, &script_err);
ok_(__FILE__,line)(hr == S_OK, "IScriptControl_get_Error failed: 0x%08x.\n", hr);
- if (SUCCEEDED(hr))
- {
- error_num = 0xdeadbeef;
- hr = IScriptError_get_Number(script_err, &error_num);
- ok_(__FILE__,line)(hr == S_OK, "IScriptError_get_Number failed: 0x%08x.\n", hr);
- ok_(__FILE__,line)(error_num == exp_num, "got wrong error number: %d, expected %d.\n",
- error_num, exp_num);
- IScriptError_Release(script_err);
- }
+ error_num = 0xdeadbeef;
+ hr = IScriptError_get_Number(script_err, &error_num);
+ todo_wine ok_(__FILE__,line)(hr == S_OK, "IScriptError_get_Number failed: 0x%08x.\n", hr);
+ todo_wine ok_(__FILE__,line)(error_num == exp_num, "got wrong error number: %d, expected %d.\n",
+ error_num, exp_num);
+ IScriptError_Release(script_err);
}
static void test_IScriptControl_Eval(void)
@@ -2112,7 +2109,7 @@ static void test_IScriptControl_Eval(void)
ok(hr == E_FAIL, "IScriptControl_Eval returned: 0x%08x.\n", hr);
ok((V_VT(&var) == VT_EMPTY) && (V_I4(&var) == 0xdeadbeef), "V_VT(var) = %d, V_I4(var) = %d.\n",
V_VT(&var), V_I4(&var));
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
script_str = SysAllocString(L"1 + 1");
V_VT(&var) = VT_NULL;
@@ -2160,7 +2157,7 @@ static void test_IScriptControl_Eval(void)
ok(V_I4(&var) == 0xdeadbeef || broken(V_I4(&var) == 0) /* after Win8 */,
"V_I4(var) = %d.\n", V_I4(&var));
SysFreeString(script_str);
- todo_wine CHECK_ERROR(sc, 1004);
+ CHECK_ERROR(sc, 1004);
script_str = SysAllocString(L"var2 = var1 + var2");
V_VT(&var) = VT_NULL;
@@ -2287,13 +2284,13 @@ static void test_IScriptControl_AddCode(void)
hr = IScriptControl_AddCode(sc, code_str);
ok(hr == S_OK, "IScriptControl_AddCode failed: 0x%08x.\n", hr);
SysFreeString(code_str);
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
code_str = SysAllocString(L"invalid syntax");
hr = IScriptControl_AddCode(sc, code_str);
todo_wine ok(hr == 0x800a03ec, "IScriptControl_AddCode returned: 0x%08x.\n", hr);
SysFreeString(code_str);
- todo_wine CHECK_ERROR(sc, 1004);
+ CHECK_ERROR(sc, 1004);
IScriptControl_Release(sc);
@@ -2388,13 +2385,13 @@ static void test_IScriptControl_ExecuteStatement(void)
hr = IScriptControl_ExecuteStatement(sc, str);
ok(hr == S_OK, "IScriptControl_ExecuteStatement failed: 0x%08x.\n", hr);
SysFreeString(str);
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
str = SysAllocString(L"invalid syntax");
hr = IScriptControl_ExecuteStatement(sc, str);
todo_wine ok(hr == 0x800a03ec, "IScriptControl_ExecuteStatement returned: 0x%08x.\n", hr);
SysFreeString(str);
- todo_wine CHECK_ERROR(sc, 1004);
+ CHECK_ERROR(sc, 1004);
IScriptControl_Release(sc);
@@ -2500,13 +2497,13 @@ static void test_IScriptControl_Run(void)
str = SysAllocString(L"foobar");
hr = IScriptControl_Run(sc, str, ¶ms, &var);
ok(hr == DISP_E_UNKNOWNNAME, "IScriptControl_Run failed: 0x%08x.\n", hr);
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
SysFreeString(str);
str = SysAllocString(L"function subtract(a, b) { return a - b; }\n");
hr = IScriptControl_AddCode(sc, str);
ok(hr == S_OK, "IScriptControl_AddCode failed: 0x%08x.\n", hr);
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
SysFreeString(str);
str = SysAllocString(L"Subtract");
@@ -2517,12 +2514,12 @@ static void test_IScriptControl_Run(void)
str = SysAllocString(L"subtract");
hr = IScriptControl_Run(sc, str, ¶ms, NULL);
ok(hr == E_POINTER, "IScriptControl_Run failed: 0x%08x.\n", hr);
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
hr = IScriptControl_Run(sc, str, ¶ms, &var);
ok(hr == S_OK, "IScriptControl_Run failed: 0x%08x.\n", hr);
ok((V_VT(&var) == VT_I4) && (V_I4(&var) == 7), "V_VT(var) = %d, V_I4(var) = %d.\n", V_VT(&var), V_I4(&var));
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
SafeArrayDestroy(params);
/* The array's other dimensions are ignored */
@@ -3340,7 +3337,7 @@ static void test_IScriptControl_get_Procedures(void)
);
hr = IScriptControl_AddCode(sc, str);
ok(hr == S_OK, "IScriptControl_AddCode failed: 0x%08x.\n", hr);
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
SysFreeString(str);
hr = IScriptProcedureCollection_get_Count(procs, &count);
@@ -3480,7 +3477,7 @@ static void test_IScriptControl_get_Procedures(void)
hr = IScriptControl_AddCode(sc, str);
ok(hr == S_OK, "IScriptControl_AddCode failed: 0x%08x.\n", hr);
SysFreeString(str);
- todo_wine CHECK_ERROR(sc, 0);
+ CHECK_ERROR(sc, 0);
CHECK_CALLED(ParseScriptText);
GetScriptDispatch_expected_name = NULL;
--
2.21.0
More information about the wine-devel
mailing list