Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 85 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 6cc6df5..9e33737 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -625,6 +625,44 @@ typedef struct { jsdisp_t *jsdisp; } ScriptTypeInfo;
+static struct typeinfo_func *get_func_from_memid(const ScriptTypeInfo *typeinfo, MEMBERID memid) +{ + UINT a = 0, b = typeinfo->num_funcs; + + while (a < b) + { + UINT i = (a + b - 1) / 2; + MEMBERID func_memid = prop_to_id(typeinfo->jsdisp, typeinfo->funcs[i].prop); + + if (memid == func_memid) + return &typeinfo->funcs[i]; + else if (memid < func_memid) + b = i; + else + a = i + 1; + } + return NULL; +} + +static dispex_prop_t *get_var_from_memid(const ScriptTypeInfo *typeinfo, MEMBERID memid) +{ + UINT a = 0, b = typeinfo->num_vars; + + while (a < b) + { + UINT i = (a + b - 1) / 2; + MEMBERID var_memid = prop_to_id(typeinfo->jsdisp, typeinfo->vars[i]); + + if (memid == var_memid) + return typeinfo->vars[i]; + else if (memid < var_memid) + b = i; + else + a = i + 1; + } + return NULL; +} + static inline ScriptTypeInfo *ScriptTypeInfo_from_ITypeInfo(ITypeInfo *iface) { return CONTAINING_RECORD(iface, ScriptTypeInfo, ITypeInfo_iface); @@ -786,10 +824,53 @@ static HRESULT WINAPI ScriptTypeInfo_GetNames(ITypeInfo *iface, MEMBERID memid, UINT cMaxNames, UINT *pcNames) { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface); + struct typeinfo_func *func; + ITypeInfo *disp_typeinfo; + dispex_prop_t *var; + HRESULT hr; + UINT i = 0;
- FIXME("(%p)->(%d %p %u %p)\n", This, memid, rgBstrNames, cMaxNames, pcNames); + TRACE("(%p)->(%d %p %u %p)\n", This, memid, rgBstrNames, cMaxNames, pcNames);
- return E_NOTIMPL; + if (!rgBstrNames || !pcNames) return E_INVALIDARG; + if (memid <= 0) return TYPE_E_ELEMENTNOTFOUND; + + func = get_func_from_memid(This, memid); + if (!func) + { + var = get_var_from_memid(This, memid); + if (!var) + { + hr = get_dispatch_typeinfo(&disp_typeinfo); + if (FAILED(hr)) return hr; + + return ITypeInfo_GetNames(disp_typeinfo, memid, rgBstrNames, cMaxNames, pcNames); + } + } + + *pcNames = 0; + if (!cMaxNames) return S_OK; + + rgBstrNames[0] = SysAllocString(func ? func->prop->name : var->name); + if (!rgBstrNames[0]) return E_OUTOFMEMORY; + i++; + + if (func) + { + unsigned num = min(cMaxNames, func->code->param_cnt + 1); + + for (; i < num; i++) + { + if (!(rgBstrNames[i] = SysAllocString(func->code->params[i - 1]))) + { + do SysFreeString(rgBstrNames[--i]); while (i); + return E_OUTOFMEMORY; + } + } + } + + *pcNames = i; + return S_OK; }
static HRESULT WINAPI ScriptTypeInfo_GetRefTypeOfImplType(ITypeInfo *iface, UINT index, HREFTYPE *pRefType)
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 9e33737..f132e2e 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -877,9 +877,14 @@ static HRESULT WINAPI ScriptTypeInfo_GetRefTypeOfImplType(ITypeInfo *iface, UINT { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%u %p)\n", This, index, pRefType); + TRACE("(%p)->(%u %p)\n", This, index, pRefType);
- return E_NOTIMPL; + /* We only inherit from IDispatch */ + if (!pRefType) return E_INVALIDARG; + if (index != 0) return TYPE_E_ELEMENTNOTFOUND; + + *pRefType = 1; + return S_OK; }
static HRESULT WINAPI ScriptTypeInfo_GetImplTypeFlags(ITypeInfo *iface, UINT index, INT *pImplTypeFlags)
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index f132e2e..63c1edb 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -983,10 +983,23 @@ static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memi static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo) { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface); + HRESULT hr;
- FIXME("(%p)->(%x %p)\n", This, hRefType, ppTInfo); + TRACE("(%p)->(%x %p)\n", This, hRefType, ppTInfo);
- return E_NOTIMPL; + if (!ppTInfo || (INT)hRefType < 0) return E_INVALIDARG; + + if (hRefType & ~3) return E_FAIL; + if (hRefType & 1) + { + hr = get_dispatch_typeinfo(ppTInfo); + if (FAILED(hr)) return hr; + } + else + *ppTInfo = iface; + + ITypeInfo_AddRef(*ppTInfo); + return S_OK; }
static HRESULT WINAPI ScriptTypeInfo_AddressOfMember(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 63c1edb..acfe00f 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -891,9 +891,13 @@ static HRESULT WINAPI ScriptTypeInfo_GetImplTypeFlags(ITypeInfo *iface, UINT ind { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%u %p)\n", This, index, pImplTypeFlags); + TRACE("(%p)->(%u %p)\n", This, index, pImplTypeFlags);
- return E_NOTIMPL; + if (!pImplTypeFlags) return E_INVALIDARG; + if (index != 0) return TYPE_E_ELEMENTNOTFOUND; + + *pImplTypeFlags = 0; + return S_OK; }
static HRESULT WINAPI ScriptTypeInfo_GetIDsOfNames(ITypeInfo *iface, LPOLESTR *rgszNames, UINT cNames,
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index acfe00f..6f13c6b 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -957,11 +957,33 @@ static HRESULT WINAPI ScriptTypeInfo_Invoke(ITypeInfo *iface, PVOID pvInstance, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface); + ITypeInfo *disp_typeinfo; + IDispatch *disp; + HRESULT hr;
- FIXME("(%p)->(%p %d %d %p %p %p %p)\n", This, pvInstance, memid, wFlags, + TRACE("(%p)->(%p %d %d %p %p %p %p)\n", This, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
- return E_NOTIMPL; + if (!pvInstance) return E_INVALIDARG; + if (memid <= 0) return TYPE_E_ELEMENTNOTFOUND; + + if (!get_func_from_memid(This, memid) && !get_var_from_memid(This, memid)) + { + hr = get_dispatch_typeinfo(&disp_typeinfo); + if (FAILED(hr)) return hr; + + return ITypeInfo_Invoke(disp_typeinfo, pvInstance, memid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); + } + + hr = IUnknown_QueryInterface((IUnknown*)pvInstance, &IID_IDispatch, (void**)&disp); + if (FAILED(hr)) return hr; + + hr = IDispatch_Invoke(disp, memid, &IID_NULL, LOCALE_USER_DEFAULT, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); + IDispatch_Release(disp); + + return hr; }
static HRESULT WINAPI ScriptTypeInfo_GetDocumentation(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrName,
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 47 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 6f13c6b..dd1fcc7 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -990,10 +990,53 @@ static HRESULT WINAPI ScriptTypeInfo_GetDocumentation(ITypeInfo *iface, MEMBERID BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile) { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface); + struct typeinfo_func *func; + ITypeInfo *disp_typeinfo; + dispex_prop_t *var; + HRESULT hr;
- FIXME("(%p)->(%d %p %p %p %p)\n", This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); + TRACE("(%p)->(%d %p %p %p %p)\n", This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
- return E_NOTIMPL; + if (pBstrDocString) *pBstrDocString = NULL; + if (pdwHelpContext) *pdwHelpContext = 0; + if (pBstrHelpFile) *pBstrHelpFile = NULL; + + if (memid == MEMBERID_NIL) + { + if (pBstrName && !(*pBstrName = SysAllocString(L"JScriptTypeInfo"))) + return E_OUTOFMEMORY; + if (pBstrDocString && + !(*pBstrDocString = SysAllocString(L"JScript Type Info"))) + { + if (pBstrName) SysFreeString(*pBstrName); + return E_OUTOFMEMORY; + } + return S_OK; + } + if (memid <= 0) return TYPE_E_ELEMENTNOTFOUND; + + func = get_func_from_memid(This, memid); + if (!func) + { + var = get_var_from_memid(This, memid); + if (!var) + { + hr = get_dispatch_typeinfo(&disp_typeinfo); + if (FAILED(hr)) return hr; + + return ITypeInfo_GetDocumentation(disp_typeinfo, memid, pBstrName, pBstrDocString, + pdwHelpContext, pBstrHelpFile); + } + } + + if (pBstrName) + { + *pBstrName = SysAllocString(func ? func->prop->name : var->name); + + if (!*pBstrName) + return E_OUTOFMEMORY; + } + return S_OK; }
static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind,
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index dd1fcc7..0c47051 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1043,10 +1043,23 @@ static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memi BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal) { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface); + ITypeInfo *disp_typeinfo; + HRESULT hr;
- FIXME("(%p)->(%d %d %p %p %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal); + TRACE("(%p)->(%d %d %p %p %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
- return E_NOTIMPL; + if (pBstrDllName) *pBstrDllName = NULL; + if (pBstrName) *pBstrName = NULL; + if (pwOrdinal) *pwOrdinal = 0; + + if (!get_func_from_memid(This, memid) && !get_var_from_memid(This, memid)) + { + hr = get_dispatch_typeinfo(&disp_typeinfo); + if (FAILED(hr)) return hr; + + return ITypeInfo_GetDllEntry(disp_typeinfo, memid, invKind, pBstrDllName, pBstrName, pwOrdinal); + } + return TYPE_E_BADMODULEKIND; }
static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo)
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 0c47051..f5f545c 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1087,10 +1087,22 @@ static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE h static HRESULT WINAPI ScriptTypeInfo_AddressOfMember(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv) { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface); + ITypeInfo *disp_typeinfo; + HRESULT hr;
- FIXME("(%p)->(%d %d %p)\n", This, memid, invKind, ppv); + TRACE("(%p)->(%d %d %p)\n", This, memid, invKind, ppv);
- return E_NOTIMPL; + if (!ppv) return E_INVALIDARG; + *ppv = NULL; + + if (!get_func_from_memid(This, memid) && !get_var_from_memid(This, memid)) + { + hr = get_dispatch_typeinfo(&disp_typeinfo); + if (FAILED(hr)) return hr; + + return ITypeInfo_AddressOfMember(disp_typeinfo, memid, invKind, ppv); + } + return TYPE_E_BADMODULEKIND; }
static HRESULT WINAPI ScriptTypeInfo_CreateInstance(ITypeInfo *iface, IUnknown *pUnkOuter, REFIID riid, PVOID *ppvObj)
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index f5f545c..b754a17 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1109,9 +1109,12 @@ static HRESULT WINAPI ScriptTypeInfo_CreateInstance(ITypeInfo *iface, IUnknown * { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%p %s %p)\n", This, pUnkOuter, debugstr_guid(riid), ppvObj); + TRACE("(%p)->(%p %s %p)\n", This, pUnkOuter, debugstr_guid(riid), ppvObj);
- return E_NOTIMPL; + if (!ppvObj) return E_INVALIDARG; + + *ppvObj = NULL; + return TYPE_E_BADMODULEKIND; }
static HRESULT WINAPI ScriptTypeInfo_GetMops(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrMops)
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index b754a17..6f9a0eb 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1120,10 +1120,23 @@ static HRESULT WINAPI ScriptTypeInfo_CreateInstance(ITypeInfo *iface, IUnknown * static HRESULT WINAPI ScriptTypeInfo_GetMops(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrMops) { ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface); + ITypeInfo *disp_typeinfo; + HRESULT hr;
- FIXME("(%p)->(%d %p)\n", This, memid, pBstrMops); + TRACE("(%p)->(%d %p)\n", This, memid, pBstrMops);
- return E_NOTIMPL; + if (!pBstrMops) return E_INVALIDARG; + + if (!get_func_from_memid(This, memid) && !get_var_from_memid(This, memid)) + { + hr = get_dispatch_typeinfo(&disp_typeinfo); + if (FAILED(hr)) return hr; + + return ITypeInfo_GetMops(disp_typeinfo, memid, pBstrMops); + } + + *pBstrMops = NULL; + return S_OK; }
static HRESULT WINAPI ScriptTypeInfo_GetContainingTypeLib(ITypeInfo *iface, ITypeLib **ppTLib, UINT *pIndex)
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/tests/jscript.c | 117 ++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c index e608367..84805b1 100644 --- a/dlls/jscript/tests/jscript.c +++ b/dlls/jscript/tests/jscript.c @@ -986,12 +986,16 @@ static void test_typeinfo(const WCHAR *parse_func_name) VARDESC *vardesc; IDispatchEx *disp; DESCKIND desckind; + INT implTypeFlags; + UINT count, index; + HREFTYPE reftype; BINDPTR bindptr; MEMBERID memid; TYPEATTR *attr; - UINT index; HRESULT hr; WCHAR str[64], *names = str; + BSTR bstr, bstrs[5]; + void *obj; int i;
if (parse_func_name) @@ -1053,6 +1057,20 @@ static void test_typeinfo(const WCHAR *parse_func_name) ok(typeinfo != typeinfo2, "TypeInfo was not supposed to be shared.\n"); ITypeInfo_Release(typeinfo2);
+ obj = (void*)0xdeadbeef; + hr = ITypeInfo_CreateInstance(typeinfo, NULL, NULL, NULL); + ok(hr == E_INVALIDARG, "CreateInstance returned: %08x\n", hr); + hr = ITypeInfo_CreateInstance(typeinfo, NULL, NULL, &obj); + ok(hr == TYPE_E_BADMODULEKIND, "CreateInstance returned: %08x\n", hr); + hr = ITypeInfo_CreateInstance(typeinfo, NULL, &IID_IDispatch, &obj); + ok(hr == TYPE_E_BADMODULEKIND, "CreateInstance returned: %08x\n", hr); + ok(!obj, "Unexpected non-null obj %p.\n", obj); + + hr = ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &bstr, NULL, NULL, NULL); + ok(hr == S_OK, "GetDocumentation(MEMBERID_NIL) failed: %08x\n", hr); + ok(!lstrcmpW(bstr, L"JScriptTypeInfo"), "Unexpected TypeInfo name %s\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + hr = ITypeInfo_GetTypeAttr(typeinfo, &attr); ok(hr == S_OK, "GetTypeAttr failed: %08x\n", hr); ok(IsEqualGUID(&attr->guid, &IID_IScriptTypeInfo), "Unexpected GUID %s\n", wine_dbgstr_guid(&attr->guid)); @@ -1071,6 +1089,45 @@ static void test_typeinfo(const WCHAR *parse_func_name) ok(attr->idldescType.wIDLFlags == IDLFLAG_NONE, "Unexpected idldescType.wIDLFlags 0x%x\n", attr->idldescType.wIDLFlags); ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
+ /* The type inherits from IDispatch */ + hr = ITypeInfo_GetImplTypeFlags(typeinfo, 0, NULL); + ok(hr == E_INVALIDARG, "GetImplTypeFlags returned: %08x\n", hr); + hr = ITypeInfo_GetImplTypeFlags(typeinfo, 1, &implTypeFlags); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetImplTypeFlags returned: %08x\n", hr); + hr = ITypeInfo_GetImplTypeFlags(typeinfo, -1, &implTypeFlags); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetImplTypeFlags returned: %08x\n", hr); + hr = ITypeInfo_GetImplTypeFlags(typeinfo, 0, &implTypeFlags); + ok(hr == S_OK, "GetImplTypeFlags failed: %08x\n", hr); + ok(implTypeFlags == 0, "Unexpected implTypeFlags 0x%x\n", implTypeFlags); + + hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, 0, NULL); + ok(hr == E_INVALIDARG, "GetRefTypeOfImplType returned: %08x\n", hr); + hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, 1, &reftype); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetRefTypeOfImplType returned: %08x\n", hr); + hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, -1, &reftype); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetRefTypeOfImplType failed: %08x\n", hr); + hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, 0, &reftype); + ok(hr == S_OK, "GetRefTypeOfImplType failed: %08x\n", hr); + ok(reftype == 1, "Unexpected reftype %d\n", reftype); + + hr = ITypeInfo_GetRefTypeInfo(typeinfo, reftype, NULL); + ok(hr == E_INVALIDARG, "GetRefTypeInfo returned: %08x\n", hr); + hr = ITypeInfo_GetRefTypeInfo(typeinfo, -1, &typeinfo2); + ok(hr == E_INVALIDARG, "GetRefTypeInfo returned: %08x\n", hr); + hr = ITypeInfo_GetRefTypeInfo(typeinfo, 4, &typeinfo2); + ok(hr == E_FAIL, "GetRefTypeInfo returned: %08x\n", hr); + hr = ITypeInfo_GetRefTypeInfo(typeinfo, 0, &typeinfo2); + ok(hr == S_OK, "GetRefTypeInfo failed: %08x\n", hr); + ok(typeinfo == typeinfo2, "Unexpected TypeInfo %p (expected %p)\n", typeinfo2, typeinfo); + ITypeInfo_Release(typeinfo2); + hr = ITypeInfo_GetRefTypeInfo(typeinfo, reftype, &typeinfo2); + ok(hr == S_OK, "GetRefTypeInfo failed: %08x\n", hr); + hr = ITypeInfo_GetDocumentation(typeinfo2, MEMBERID_NIL, &bstr, NULL, NULL, NULL); + ok(hr == S_OK, "GetDocumentation(MEMBERID_NIL) failed: %08x\n", hr); + ok(!lstrcmpW(bstr, L"IDispatch"), "Unexpected TypeInfo name %s\n", wine_dbgstr_w(bstr)); + ITypeInfo_Release(typeinfo2); + SysFreeString(bstr); + /* GetIDsOfNames looks into the inherited types as well */ wcscpy(str, L"queryinterface"); hr = ITypeInfo_GetIDsOfNames(typeinfo, NULL, 1, &memid); @@ -1088,6 +1145,52 @@ static void test_typeinfo(const WCHAR *parse_func_name) hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, &memid); ok(hr == S_OK, "GetIDsOfNames failed: %08x\n", hr); ok(!lstrcmpW(str, L"Math"), "Unexpected string %s\n", wine_dbgstr_w(str)); + hr = ITypeInfo_GetNames(typeinfo, memid, NULL, 1, &count); + ok(hr == E_INVALIDARG, "GetNames returned: %08x\n", hr); + hr = ITypeInfo_GetNames(typeinfo, memid, bstrs, 1, NULL); + ok(hr == E_INVALIDARG, "GetNames returned: %08x\n", hr); + hr = ITypeInfo_GetNames(typeinfo, memid, bstrs, 0, &count); + ok(hr == S_OK, "GetNames failed: %08x\n", hr); + ok(count == 0, "Unexpected count %u\n", count); + hr = ITypeInfo_GetNames(typeinfo, memid, bstrs, ARRAY_SIZE(bstrs), &count); + ok(hr == S_OK, "GetNames failed: %08x\n", hr); + ok(count == 3, "Unexpected count %u\n", count); + ok(!lstrcmpW(bstrs[0], L"math"), "Unexpected function name %s\n", wine_dbgstr_w(bstrs[0])); + ok(!lstrcmpW(bstrs[1], L"x"), "Unexpected function first param name %s\n", wine_dbgstr_w(bstrs[1])); + ok(!lstrcmpW(bstrs[2], L"y"), "Unexpected function second param name %s\n", wine_dbgstr_w(bstrs[2])); + for (i = 0; i < count; i++) SysFreeString(bstrs[i]); + + hr = ITypeInfo_GetMops(typeinfo, memid, NULL); + ok(hr == E_INVALIDARG, "GetMops returned: %08x\n", hr); + hr = ITypeInfo_GetMops(typeinfo, memid, &bstr); + ok(hr == S_OK, "GetMops failed: %08x\n", hr); + ok(!bstr, "Unexpected non-null string %s\n", wine_dbgstr_w(bstr)); + hr = ITypeInfo_GetMops(typeinfo, MEMBERID_NIL, &bstr); + ok(hr == S_OK, "GetMops failed: %08x\n", hr); + ok(!bstr, "Unexpected non-null string %s\n", wine_dbgstr_w(bstr)); + + /* These always fail */ + obj = (void*)0xdeadbeef; + hr = ITypeInfo_AddressOfMember(typeinfo, memid, INVOKE_FUNC, NULL); + ok(hr == E_INVALIDARG, "AddressOfMember returned: %08x\n", hr); + hr = ITypeInfo_AddressOfMember(typeinfo, memid, INVOKE_FUNC, &obj); + ok(hr == TYPE_E_BADMODULEKIND, "AddressOfMember returned: %08x\n", hr); + ok(!obj, "Unexpected non-null obj %p.\n", obj); + bstr = (BSTR)0xdeadbeef; + hr = ITypeInfo_GetDllEntry(typeinfo, memid, INVOKE_FUNC, &bstr, NULL, NULL); + ok(hr == TYPE_E_BADMODULEKIND, "GetDllEntry returned: %08x\n", hr); + ok(!bstr, "Unexpected non-null str %p.\n", bstr); + wcscpy(str, L"Invoke"); + hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, &memid); + ok(hr == S_OK, "GetIDsOfNames failed: %08x\n", hr); + obj = (void*)0xdeadbeef; + hr = ITypeInfo_AddressOfMember(typeinfo, memid, INVOKE_FUNC, &obj); + ok(hr == TYPE_E_BADMODULEKIND, "AddressOfMember returned: %08x\n", hr); + ok(!obj, "Unexpected non-null obj %p.\n", obj); + bstr = (BSTR)0xdeadbeef; + hr = ITypeInfo_GetDllEntry(typeinfo, memid, INVOKE_FUNC, &bstr, NULL, NULL); + ok(hr == TYPE_E_BADMODULEKIND, "GetDllEntry returned: %08x\n", hr); + ok(!bstr, "Unexpected non-null str %p.\n", bstr); }
/* Check variable descriptions */ @@ -1099,6 +1202,12 @@ static void test_typeinfo(const WCHAR *parse_func_name) { hr = ITypeInfo_GetVarDesc(typeinfo, i, &vardesc); ok(hr == S_OK, "GetVarDesc(%u) failed: %08x\n", i, hr); + hr = ITypeInfo_GetDocumentation(typeinfo, vardesc->memid, &bstr, &bstrs[0], NULL, NULL); + ok(hr == S_OK, "[%u] GetDocumentation failed: %08x\n", i, hr); + ok(!lstrcmpW(bstr, var[i].name), "[%u] Unexpected variable name %s (expected %s)\n", + i, wine_dbgstr_w(bstr), wine_dbgstr_w(var[i].name)); + ok(!bstrs[0], "[%u] Unexpected doc string %s\n", i, wine_dbgstr_w(bstrs[0])); + SysFreeString(bstr); ok(vardesc->memid <= 0xFFFF, "[%u] Unexpected memid 0x%x\n", i, vardesc->memid); ok(vardesc->lpstrSchema == NULL, "[%u] Unexpected lpstrSchema %p\n", i, vardesc->lpstrSchema); ok(vardesc->oInst == 0, "[%u] Unexpected oInst %u\n", i, vardesc->oInst); @@ -1122,6 +1231,12 @@ static void test_typeinfo(const WCHAR *parse_func_name) { hr = ITypeInfo_GetFuncDesc(typeinfo, i, &funcdesc); ok(hr == S_OK, "GetFuncDesc(%u) failed: %08x\n", i, hr); + hr = ITypeInfo_GetDocumentation(typeinfo, funcdesc->memid, &bstr, &bstrs[0], NULL, NULL); + ok(hr == S_OK, "[%u] GetDocumentation failed: %08x\n", i, hr); + ok(!lstrcmpW(bstr, func[i].name), "[%u] Unexpected function name %s (expected %s)\n", + i, wine_dbgstr_w(bstr), wine_dbgstr_w(func[i].name)); + ok(!bstrs[0], "[%u] Unexpected doc string %s\n", i, wine_dbgstr_w(bstrs[0])); + SysFreeString(bstr); ok(funcdesc->memid <= 0xFFFF, "[%u] Unexpected memid 0x%x\n", i, funcdesc->memid); ok(funcdesc->lprgscode == NULL, "[%u] Unexpected lprgscode %p\n", i, funcdesc->lprgscode); ok(func[i].num_args ? (funcdesc->lprgelemdescParam != NULL) : (funcdesc->lprgelemdescParam == NULL),
Signed-off-by: Jacek Caban jacek@codeweavers.com