diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index ff709ddef62..825851c948e 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -8241,6 +8241,83 @@ static void test_DeleteImplType(void) DeleteFileW(filenameW); } +static void test_DeleteFuncDesc(void) +{ + OLECHAR interface1W[] = L"interface1"; + WCHAR filenameW[MAX_PATH], temp_path[MAX_PATH]; + ICreateTypeInfo2 *createti2; + ICreateTypeInfo *createti; + ICreateTypeLib2 *createtl; + FUNCDESC funcdesc; + TYPEATTR *typeattr; + ITypeInfo *ti; + ITypeLib *tl; + HRESULT hr; + + GetTempPathW(ARRAY_SIZE(temp_path), temp_path); + GetTempFileNameW(temp_path, L"tlb", 0, filenameW); + + hr = CreateTypeLib2(SYS_WIN32, filenameW, &createtl); + ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr); + + hr = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti); + ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr); + hr = ICreateTypeInfo_QueryInterface(createti, &IID_ICreateTypeInfo2, (void **)&createti2); + ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr); + ICreateTypeInfo_Release(createti); + + hr = ICreateTypeInfo2_QueryInterface(createti2, &IID_ITypeInfo, (void **)&ti); + ok(hr == S_OK, "Failed to get typeinfo, hr %#x.\n", hr); + + memset(&funcdesc, 0, sizeof(FUNCDESC)); + funcdesc.funckind = FUNC_PUREVIRTUAL; + funcdesc.invkind = INVOKE_PROPERTYGET; + funcdesc.callconv = CC_STDCALL; + funcdesc.elemdescFunc.tdesc.vt = VT_BSTR; + U(funcdesc.elemdescFunc).idldesc.wIDLFlags = IDLFLAG_NONE; + + hr = ICreateTypeInfo2_AddFuncDesc(createti2, 0, &funcdesc); + ok(hr == S_OK, "Failed to add a funcdesc, hr %#x.\n", hr); + + hr = ITypeInfo_GetTypeAttr(ti, &typeattr); + ok(hr == S_OK, "Failed to get type attr, hr %#x.\n", hr); + ok(typeattr->cFuncs == 1, "Unexpected cFuncs %u.\n", typeattr->cFuncs); + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + + hr = ICreateTypeInfo2_DeleteFuncDesc(createti2, 1); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "Unexpected hr %#x.\n", hr); + + hr = ICreateTypeInfo2_DeleteFuncDesc(createti2, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = ITypeInfo_GetTypeAttr(ti, &typeattr); + ok(hr == S_OK, "Failed to get type attr, hr %#x.\n", hr); + ok(!typeattr->cFuncs, "Unexpected cFuncs %u.\n", typeattr->cFuncs); + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + + hr = ICreateTypeLib2_SaveAllChanges(createtl); + ok(hr == S_OK, "Failed to save changes, hr %#x.\n", hr); + ICreateTypeLib2_Release(createtl); + ITypeInfo_Release(ti); + ICreateTypeInfo2_Release(createti2); + + /* Load and check typeinfo. */ + hr = LoadTypeLibEx(filenameW, REGKIND_NONE, &tl); + ok(hr == S_OK, "Failed to load typelib, hr %#x.\n", hr); + + hr = ITypeLib_GetTypeInfo(tl, 0, &ti); + ok(hr == S_OK, "Failed to get typeinfo, hr %#x.\n", hr); + hr = ITypeInfo_GetTypeAttr(ti, &typeattr); + ok(hr == S_OK, "Failed to get type attr, hr %#x.\n", hr); + ok(!typeattr->cFuncs, "Unexpected cFuncs value.\n"); + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + ITypeInfo_Release(ti); + + ITypeLib_Release(tl); + + DeleteFileW(filenameW); +} + START_TEST(typelib) { const WCHAR *filename; @@ -8282,4 +8359,5 @@ START_TEST(typelib) test_stub(); test_dep(); test_DeleteImplType(); + test_DeleteFuncDesc(); } diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 65d29734800..4669b03d5fc 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -5587,6 +5587,22 @@ static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface) return ref; } +static void typeinfo_release_funcdesc(TLBFuncDesc *func) +{ + unsigned int i; + + for (i = 0; i < func->funcdesc.cParams; ++i) + { + ELEMDESC *elemdesc = &func->funcdesc.lprgelemdescParam[i]; + if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) + VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue); + TLB_FreeCustData(&func->pParamDesc[i].custdata_list); + } + heap_free(func->funcdesc.lprgelemdescParam); + heap_free(func->pParamDesc); + TLB_FreeCustData(&func->custdata_list); +} + static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This) { UINT i; @@ -5595,18 +5611,7 @@ static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This) for (i = 0; i < This->typeattr.cFuncs; ++i) { - int j; - TLBFuncDesc *pFInfo = &This->funcdescs[i]; - for(j = 0; j < pFInfo->funcdesc.cParams; j++) - { - ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[j]; - if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) - VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue); - TLB_FreeCustData(&pFInfo->pParamDesc[j].custdata_list); - } - heap_free(pFInfo->funcdesc.lprgelemdescParam); - heap_free(pFInfo->pParamDesc); - TLB_FreeCustData(&pFInfo->custdata_list); + typeinfo_release_funcdesc(&This->funcdescs[i]); } heap_free(This->funcdescs); @@ -11373,8 +11378,27 @@ static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(ICreateTypeInfo2 *iface, UINT index) { ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); - FIXME("%p %u - stub\n", This, index); - return E_NOTIMPL; + unsigned int i; + + TRACE("%p %u\n", This, index); + + if (index >= This->typeattr.cFuncs) + return TYPE_E_ELEMENTNOTFOUND; + + typeinfo_release_funcdesc(&This->funcdescs[index]); + + --This->typeattr.cFuncs; + if (index != This->typeattr.cFuncs) + { + memmove(This->funcdescs + index, This->funcdescs + index + 1, + sizeof(*This->funcdescs) * (This->typeattr.cFuncs - index)); + for (i = index; i < This->typeattr.cFuncs; ++i) + TLB_relink_custdata(&This->funcdescs[i].custdata_list); + } + + This->needs_layout = TRUE; + + return S_OK; } static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(ICreateTypeInfo2 *iface,