[PATCH 3/3] mshtml: Add console object stub implementation.
Paul Gofman
pgofman at codeweavers.com
Tue Jul 6 06:08:41 CDT 2021
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/mshtml/Makefile.in | 1 +
dlls/mshtml/console.c | 294 ++++++++++++++++++++++++++
dlls/mshtml/dispex.c | 21 +-
dlls/mshtml/htmlwindow.c | 36 +++-
dlls/mshtml/mshtml_private.h | 11 +
dlls/mshtml/tests/es5.js | 64 ++++++
include/wine/mshtml_private_iface.idl | 89 ++++++++
7 files changed, 508 insertions(+), 8 deletions(-)
create mode 100644 dlls/mshtml/console.c
diff --git a/dlls/mshtml/Makefile.in b/dlls/mshtml/Makefile.in
index 469667081e3..e0b539c92d4 100644
--- a/dlls/mshtml/Makefile.in
+++ b/dlls/mshtml/Makefile.in
@@ -7,6 +7,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \
conpoint.c \
+ console.c \
dispex.c \
editor.c \
htmlanchor.c \
diff --git a/dlls/mshtml/console.c b/dlls/mshtml/console.c
new file mode 100644
index 00000000000..58df32896cc
--- /dev/null
+++ b/dlls/mshtml/console.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2021 Paul Gofman for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "ole2.h"
+#include "mshtmdid.h"
+#include "shlguid.h"
+#include "shobjidl.h"
+#include "exdispid.h"
+
+#include "wine/debug.h"
+
+#include "mshtml_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+
+struct console {
+ DispatchEx dispex;
+ IWineMSHTMLConsole IWineMSHTMLConsole_iface;
+ LONG ref;
+};
+
+static inline struct console *impl_from_IWineMSHTMLConsole(IWineMSHTMLConsole *iface)
+{
+ return CONTAINING_RECORD(iface, struct console, IWineMSHTMLConsole_iface);
+}
+
+static HRESULT WINAPI console_QueryInterface(IWineMSHTMLConsole *iface, REFIID riid, void **ppv)
+{
+ struct console *console = impl_from_IWineMSHTMLConsole(iface);
+
+ TRACE("(%p)->(%s %p)\n", console, debugstr_mshtml_guid(riid), ppv);
+
+ if(IsEqualGUID(&IID_IUnknown, riid)) {
+ *ppv = &console->IWineMSHTMLConsole_iface;
+ }else if(IsEqualGUID(&IID_IWineMSHTMLConsole, riid)) {
+ *ppv = &console->IWineMSHTMLConsole_iface;
+ }else if(dispex_query_interface(&console->dispex, riid, ppv)) {
+ return *ppv ? S_OK : E_NOINTERFACE;
+ }else {
+ WARN("(%p)->(%s %p)\n", console, debugstr_mshtml_guid(riid), ppv);
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI console_AddRef(IWineMSHTMLConsole *iface)
+{
+ struct console *console = impl_from_IWineMSHTMLConsole(iface);
+ LONG ref = InterlockedIncrement(&console->ref);
+
+ TRACE("(%p) ref=%d\n", console, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI console_Release(IWineMSHTMLConsole *iface)
+{
+ struct console *console = impl_from_IWineMSHTMLConsole(iface);
+ LONG ref = InterlockedDecrement(&console->ref);
+
+ TRACE("(%p) ref=%d\n", console, ref);
+
+ if(!ref) {
+ release_dispex(&console->dispex);
+ heap_free(console);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI console_GetTypeInfoCount(IWineMSHTMLConsole *iface, UINT *pctinfo)
+{
+ struct console *console = impl_from_IWineMSHTMLConsole(iface);
+ FIXME("(%p)->(%p)\n", console, pctinfo);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI console_GetTypeInfo(IWineMSHTMLConsole *iface, UINT iTInfo,
+ LCID lcid, ITypeInfo **ppTInfo)
+{
+ struct console *console = impl_from_IWineMSHTMLConsole(iface);
+
+ return IDispatchEx_GetTypeInfo(&console->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
+}
+
+static HRESULT WINAPI console_GetIDsOfNames(IWineMSHTMLConsole *iface, REFIID riid,
+ LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+ struct console *console = impl_from_IWineMSHTMLConsole(iface);
+
+ return IDispatchEx_GetIDsOfNames(&console->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
+ lcid, rgDispId);
+}
+
+static HRESULT WINAPI console_Invoke(IWineMSHTMLConsole *iface, DISPID dispIdMember,
+ REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+ VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+ struct console *console = impl_from_IWineMSHTMLConsole(iface);
+
+ return IDispatchEx_Invoke(&console->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
+ pDispParams, pVarResult, pExcepInfo, puArgErr);
+}
+
+static HRESULT WINAPI console_assert(IWineMSHTMLConsole *iface, VARIANT_BOOL *assertion, VARIANT *vararg_start)
+{
+ FIXME("iface %p, assertion %p, vararg_start %p stub.\n", iface, assertion, vararg_start);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_clear(IWineMSHTMLConsole *iface)
+{
+ FIXME("iface %p stub.\n", iface);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_count(IWineMSHTMLConsole *iface, VARIANT *label)
+{
+ FIXME("iface %p, label %p stub.\n", iface, label);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_debug(IWineMSHTMLConsole *iface, VARIANT *vararg_start)
+{
+ FIXME("iface %p, vararg_start %p stub.\n", iface, vararg_start);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_dir(IWineMSHTMLConsole *iface, VARIANT *object)
+{
+ FIXME("iface %p, object %p stub.\n", iface, object);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_dirxml(IWineMSHTMLConsole *iface, VARIANT *object)
+{
+ FIXME("iface %p, object %p stub.\n", iface, object);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_error(IWineMSHTMLConsole *iface, VARIANT *vararg_start)
+{
+ FIXME("iface %p, vararg_start %p stub.\n", iface, vararg_start);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_group(IWineMSHTMLConsole *iface, VARIANT *label)
+{
+ FIXME("iface %p, label %p stub.\n", iface, label);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_group_collapsed(IWineMSHTMLConsole *iface, VARIANT *label)
+{
+ FIXME("iface %p, label %p stub.\n", iface, label);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_group_end(IWineMSHTMLConsole *iface)
+{
+ FIXME("iface %p, stub.\n", iface);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_info(IWineMSHTMLConsole *iface, VARIANT *vararg_start)
+{
+ FIXME("iface %p, vararg_start %p stub.\n", iface, vararg_start);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_log(IWineMSHTMLConsole *iface, VARIANT *vararg_start)
+{
+ FIXME("iface %p, vararg_start %p stub.\n", iface, vararg_start);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_time(IWineMSHTMLConsole *iface, VARIANT *label)
+{
+ FIXME("iface %p, label %p stub.\n", iface, label);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_time_end(IWineMSHTMLConsole *iface, VARIANT *label)
+{
+ FIXME("iface %p, label %p stub.\n", iface, label);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_trace(IWineMSHTMLConsole *iface, VARIANT *vararg_start)
+{
+ FIXME("iface %p, vararg_start %p stub.\n", iface, vararg_start);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI console_warn(IWineMSHTMLConsole *iface, VARIANT *vararg_start)
+{
+ FIXME("iface %p, vararg_start %p stub.\n", iface, vararg_start);
+
+ return S_OK;
+}
+
+static const IWineMSHTMLConsoleVtbl WineMSHTMLConsoleVtbl = {
+ console_QueryInterface,
+ console_AddRef,
+ console_Release,
+ console_GetTypeInfoCount,
+ console_GetTypeInfo,
+ console_GetIDsOfNames,
+ console_Invoke,
+ console_assert,
+ console_clear,
+ console_count,
+ console_debug,
+ console_dir,
+ console_dirxml,
+ console_error,
+ console_group,
+ console_group_collapsed,
+ console_group_end,
+ console_info,
+ console_log,
+ console_time,
+ console_time_end,
+ console_trace,
+ console_warn,
+};
+
+static const tid_t console_iface_tids[] = {
+ IWineMSHTMLConsole_tid,
+ 0
+};
+static dispex_static_data_t console_dispex = {
+ NULL,
+ IWineMSHTMLConsole_tid,
+ console_iface_tids
+};
+
+void create_console(IWineMSHTMLConsole **ret)
+{
+ struct console *obj;
+
+ obj = heap_alloc_zero(sizeof(*obj));
+ if(!obj)
+ {
+ ERR("No memory.\n");
+ return;
+ }
+
+ obj->IWineMSHTMLConsole_iface.lpVtbl = &WineMSHTMLConsoleVtbl;
+ obj->ref = 1;
+ init_dispatch(&obj->dispex, (IUnknown*)&obj->IWineMSHTMLConsole_iface, &console_dispex, COMPAT_MODE_NONE);
+
+ *ret = &obj->IWineMSHTMLConsole_iface;
+}
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index 6d248691d6b..9c517fec2c2 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -111,7 +111,7 @@ struct dispex_dynamic_data_t {
#define FDEX_VERSION_MASK 0xf0000000
-static ITypeLib *typelib;
+static ITypeLib *typelib, *typelib_private;
static ITypeInfo *typeinfos[LAST_tid];
static struct list dispex_data_list = LIST_INIT(dispex_data_list);
@@ -119,6 +119,8 @@ static REFIID tid_ids[] = {
#define XIID(iface) &IID_ ## iface,
#define XDIID(iface) &DIID_ ## iface,
TID_LIST
+ NULL,
+PRIVATE_TID_LIST
#undef XIID
#undef XDIID
};
@@ -136,7 +138,17 @@ static HRESULT load_typelib(void)
if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
ITypeLib_Release(tl);
- return hres;
+
+ hres = LoadRegTypeLib(&LIBID_MSHTML_private, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
+ if(FAILED(hres)) {
+ ERR("LoadRegTypeLib failed for private typelib: %08x\n", hres);
+ return hres;
+ }
+
+ if(InterlockedCompareExchangePointer((void**)&typelib_private, tl, NULL))
+ ITypeLib_Release(tl);
+
+ return S_OK;
}
static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
@@ -151,7 +163,7 @@ static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
if(!typeinfos[tid]) {
ITypeInfo *ti;
- hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
+ hres = ITypeLib_GetTypeInfoOfGuid(tid > LAST_public_tid ? typelib_private : typelib, tid_ids[tid], &ti);
if(FAILED(hres)) {
ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_mshtml_guid(tid_ids[tid]), hres);
return hres;
@@ -197,6 +209,7 @@ void release_typelib(void)
ITypeInfo_Release(typeinfos[i]);
ITypeLib_Release(typelib);
+ ITypeLib_Release(typelib_private);
DeleteCriticalSection(&cs_dispex_static_data);
}
@@ -210,6 +223,8 @@ HRESULT get_class_typeinfo(const CLSID *clsid, ITypeInfo **typeinfo)
return hres;
hres = ITypeLib_GetTypeInfoOfGuid(typelib, clsid, typeinfo);
+ if (FAILED(hres))
+ hres = ITypeLib_GetTypeInfoOfGuid(typelib_private, clsid, typeinfo);
if(FAILED(hres))
ERR("GetTypeInfoOfGuid failed: %08x\n", hres);
return hres;
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index 4196d1f45ad..3cec8d3a3c5 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -314,6 +314,9 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
+ if (This->console)
+ IWineMSHTMLConsole_Release(This->console);
+
if(is_outer_window(This))
release_outer_window(This->outer_window);
else
@@ -3178,6 +3181,8 @@ HRESULT search_window_props(HTMLInnerWindow *This, BSTR bstrName, DWORD grfdex,
/* DISPIDs not exposed by interfaces */
#define DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME 1300
+#define DISPID_IHTMLWINDOW_IE10_CONSOLE 1301
+
static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
@@ -3195,11 +3200,18 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName,
if(hres != DISP_E_UNKNOWNNAME)
return hres;
- if(dispex_compat_mode(&window->event_target.dispex) >= COMPAT_MODE_IE10 &&
- !wcscmp(bstrName, L"requestAnimationFrame")) {
- TRACE("requestAnimationFrame\n");
- *pid = DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME;
- return S_OK;
+ if(dispex_compat_mode(&window->event_target.dispex) >= COMPAT_MODE_IE10)
+ {
+ if (!wcscmp(bstrName, L"requestAnimationFrame")) {
+ TRACE("requestAnimationFrame\n");
+ *pid = DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME;
+ return S_OK;
+ }
+ if (!wcscmp(bstrName, L"console")) {
+ TRACE("console\n");
+ *pid = DISPID_IHTMLWINDOW_IE10_CONSOLE;
+ return S_OK;
+ }
}
if(This->outer_window) {
@@ -3307,6 +3319,18 @@ static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID
return hres;
}
+ case DISPID_IHTMLWINDOW_IE10_CONSOLE: {
+ if(!(wFlags & DISPATCH_PROPERTYGET)) {
+ FIXME("unsupported wFlags %#x\n", wFlags);
+ return E_INVALIDARG;
+ }
+
+ V_VT(pvarRes) = VT_DISPATCH;
+ V_DISPATCH(pvarRes) = (IDispatch *)window->base.console;
+ IWineMSHTMLConsole_AddRef(window->base.console);
+ return S_OK;
+ }
+
}
return IDispatchEx_InvokeEx(&window->event_target.dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
@@ -3629,6 +3653,8 @@ static void *alloc_window(size_t size)
window->IProvideMultipleClassInfo_iface.lpVtbl = &ProvideMultipleClassInfoVtbl;
window->ref = 1;
+ create_console(&window->console);
+
return window;
}
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index e3486aa3314..13b49696fb4 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -40,6 +40,8 @@
#include "nsiface.h"
+#include "wine/mshtml_private_iface.h"
+
#include <assert.h>
#define NS_ERROR_GENERATE_FAILURE(module,code) \
@@ -270,10 +272,16 @@ typedef struct EventTarget EventTarget;
XIID(ISVGTSpanElement) \
XIID(ISVGTextContentElement)
+#define PRIVATE_TID_LIST \
+ XDIID(DispWineMSHTMLConsole) \
+ XIID(IWineMSHTMLConsole)
+
typedef enum {
#define XIID(iface) iface ## _tid,
#define XDIID(iface) iface ## _tid,
TID_LIST
+ LAST_public_tid,
+PRIVATE_TID_LIST
#undef XIID
#undef XDIID
LAST_tid
@@ -484,6 +492,8 @@ struct HTMLWindow {
IObjectIdentity IObjectIdentity_iface;
IProvideMultipleClassInfo IProvideMultipleClassInfo_iface;
+ IWineMSHTMLConsole *console;
+
LONG ref;
HTMLInnerWindow *inner_window;
@@ -1399,3 +1409,4 @@ void set_statustext(HTMLDocumentObj*,INT,LPCWSTR) DECLSPEC_HIDDEN;
IInternetSecurityManager *get_security_manager(void) DECLSPEC_HIDDEN;
extern HINSTANCE hInst DECLSPEC_HIDDEN;
+void create_console(IWineMSHTMLConsole **ret) DECLSPEC_HIDDEN;
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index a520253569c..e57aed5ca35 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -1448,3 +1448,67 @@ sync_test("functions scope", function() {
ok(val == 8, "val != 8");
ok(w == 9, "w != 9");
});
+
+sync_test("console", function() {
+ var except
+
+ window.console.log('1', '2');
+ console.info('1', '2', '3');
+ console.info();
+ console.log();
+ console.trace();
+ console.warn();
+ console.debug();
+ console.error();
+
+ console.assert(false, '1');
+ console.assert(true, '1');
+ console.assert('1');
+
+ console.clear();
+ console.count('1');
+ console.count(1);
+
+
+ except = false;
+ try
+ {
+ console.countReset('1');
+ }
+ catch(e)
+ {
+ except = true;
+ }
+ ok(except, "console.countReset: expected exception");
+ console.dir(document);
+ console.dir();
+ console.dirxml(document);
+ console.group('1');
+ console.groupCollapsed('1');
+ console.groupEnd();
+
+ except = false;
+ try
+ {
+ console.table(['1', '2']);
+ }
+ catch(e)
+ {
+ except = true;
+ }
+ ok(except, "console.table: expected exception");
+
+ console.time('1');
+ console.timeEnd('1');
+
+ except = false;
+ try
+ {
+ console.timeLog('1');
+ }
+ catch(e)
+ {
+ except = true;
+ }
+ ok(except, "console.timeLog: expected exception");
+});
diff --git a/include/wine/mshtml_private_iface.idl b/include/wine/mshtml_private_iface.idl
index 52899f0f1a4..09a0401cdb8 100644
--- a/include/wine/mshtml_private_iface.idl
+++ b/include/wine/mshtml_private_iface.idl
@@ -27,4 +27,93 @@ import "dispex.idl";
]
library MSHTML_private
{
+
+importlib("stdole2.tlb");
+
+[
+ odl,
+ oleautomation,
+ dual,
+ uuid(fd55b4b6-2813-4fb4-829d-380099474ab1)
+]
+interface IWineMSHTMLConsole : IDispatch
+{
+ [id(1)]
+ HRESULT assert([in] VARIANT_BOOL *assertion,
+ [in, optional] VARIANT *varargStart);
+ [id(2)]
+ HRESULT clear();
+ [id(3)]
+ HRESULT count([in, optional] VARIANT *label);
+ [id(4)]
+ HRESULT debug([in, optional] VARIANT *varargStart);
+ [id(5)]
+ HRESULT dir([in, optional] VARIANT *object);
+ [id(6)]
+ HRESULT dirxml([in, optional] VARIANT *object);
+ [id(7)]
+ HRESULT error([in, optional] VARIANT *varargStart);
+ [id(8)]
+ HRESULT group([in, optional] VARIANT *label);
+ [id(9)]
+ HRESULT groupCollapsed([in, optional] VARIANT *label);
+ [id(10)]
+ HRESULT groupEnd();
+ [id(11)]
+ HRESULT info([in, optional] VARIANT *varargStart);
+ [id(12)]
+ HRESULT log([in, optional] VARIANT *varargStart);
+ [id(13)]
+ HRESULT time([in, optional] VARIANT *label);
+ [id(14)]
+ HRESULT timeEnd([in, optional] VARIANT *label);
+ [id(15)]
+ HRESULT trace([in, optional] VARIANT *varargStart);
+ [id(16)]
+ HRESULT warn([in, optional] VARIANT *varargStart);
+}
+
+[
+ hidden,
+ uuid(fd55b4b6-2813-4fb4-829d-380099474ab1)
+]
+dispinterface DispWineMSHTMLConsole
+{
+properties:
+methods:
+ [id(1)]
+ void assert([in] VARIANT_BOOL *assertion,
+ [in, optional] VARIANT *varargStart);
+ [id(2)]
+ void clear();
+ [id(3)]
+ void count([in, optional] VARIANT *label);
+ [id(4)]
+ void debug([in, optional] VARIANT *varargStart);
+ [id(5)]
+ void dir([in, optional] VARIANT *object);
+ [id(6)]
+ void dirxml([in, optional] VARIANT *object);
+ [id(7)]
+ void error([in, optional] VARIANT *varargStart);
+ [id(8)]
+ void group([in, optional] VARIANT *label);
+ [id(9)]
+ void groupCollapsed([in, optional] VARIANT *label);
+ [id(10)]
+ void groupEnd();
+ [id(11)]
+ void info([in, optional] VARIANT *varargStart);
+ [id(12)]
+ void log([in, optional] VARIANT *varargStart);
+ [id(13)]
+ void time([in, optional] VARIANT *label);
+ [id(14)]
+ void timeEnd([in, optional] VARIANT *label);
+ [id(15)]
+ void trace([in, optional] VARIANT *varargStart);
+ [id(16)]
+ void warn([in, optional] VARIANT *varargStart);
+}
+
} /* library MSHTML_private */
--
2.31.1
More information about the wine-devel
mailing list