Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/oleaut32/typelib.c | 45 +++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 27 deletions(-)
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 1971a41570..6d96cc5fbe 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -1871,6 +1871,18 @@ static HRESULT TLB_set_custdata(struct list *custdata_list, TLBGuid *tlbguid, VA return VariantCopy(&cust_data->data, var); }
+/* Used to update list pointers after list itself was moved. */ +static void TLB_relink_custdata(struct list *custdata_list) +{ + if (custdata_list->prev == custdata_list->next) + list_init(custdata_list); + else + { + custdata_list->prev->next = custdata_list; + custdata_list->next->prev = custdata_list; + } +} + static TLBString *TLB_append_str(struct list *string_list, BSTR new_str) { TLBString *str; @@ -10806,15 +10818,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface,
/* move custdata lists to the new memory location */ for(i = 0; i < This->typeattr.cFuncs + 1; ++i){ - if(index != i){ - TLBFuncDesc *fd = &This->funcdescs[i]; - if(fd->custdata_list.prev == fd->custdata_list.next) - list_init(&fd->custdata_list); - else{ - fd->custdata_list.prev->next = &fd->custdata_list; - fd->custdata_list.next->prev = &fd->custdata_list; - } - } + if(index != i) + TLB_relink_custdata(&This->funcdescs[i].custdata_list); } } else func_desc = This->funcdescs = heap_alloc(sizeof(TLBFuncDesc)); @@ -10875,15 +10880,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface,
/* move custdata lists to the new memory location */ for(i = 0; i < This->typeattr.cImplTypes + 1; ++i){ - if(index != i){ - TLBImplType *it = &This->impltypes[i]; - if(it->custdata_list.prev == it->custdata_list.next) - list_init(&it->custdata_list); - else{ - it->custdata_list.prev->next = &it->custdata_list; - it->custdata_list.next->prev = &it->custdata_list; - } - } + if(index != i) + TLB_relink_custdata(&This->impltypes[i].custdata_list); } } else impl_type = This->impltypes = heap_alloc(sizeof(TLBImplType)); @@ -10975,15 +10973,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(ICreateTypeInfo2 *iface,
/* move custdata lists to the new memory location */ for(i = 0; i < This->typeattr.cVars + 1; ++i){ - if(index != i){ - TLBVarDesc *var = &This->vardescs[i]; - if(var->custdata_list.prev == var->custdata_list.next) - list_init(&var->custdata_list); - else{ - var->custdata_list.prev->next = &var->custdata_list; - var->custdata_list.next->prev = &var->custdata_list; - } - } + if(index != i) + TLB_relink_custdata(&This->vardescs[i].custdata_list); } } else var_desc = This->vardescs = heap_alloc_zero(sizeof(TLBVarDesc));
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/oleaut32/tests/typelib.c | 98 +++++++++++++++++++++++++++++++++++ dlls/oleaut32/typelib.c | 21 +++++++- 2 files changed, 117 insertions(+), 2 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index 47faad7763..053011d4be 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -6446,6 +6446,103 @@ static void test_dep(void) { DeleteFileW(filenameW); }
+static void test_DeleteImplType(void) +{ + static OLECHAR interface1W[] = L"interface1"; + HREFTYPE hreftype, hreftype2; + ICreateTypeInfo2 *createti2; + ICreateTypeInfo *createti; + ICreateTypeLib2 *createtl; + WCHAR filenameW[MAX_PATH]; + ITypeInfo *dispti, *ti; + ITypeLib *stdole, *tl; + TYPEATTR *typeattr; + HRESULT hr; + int flags; + + hr = LoadTypeLib(L"stdole2.tlb", &stdole); + ok(hr == S_OK, "Failed to load stdole2, hr %#x.\n", hr); + + hr = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispti); + ok(hr == S_OK, "Failed to get IDispatch typeinfo, hr %#x.\n", hr); + + GetTempFileNameW(L".", 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_AddRefTypeInfo(createti2, dispti, &hreftype); + ok(hr == S_OK, "Failed to add referenced typeinfo, hr %#x.\n", hr); + + hr = ICreateTypeInfo2_QueryInterface(createti2, &IID_ITypeInfo, (void **)&ti); + ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr); + + hr = ITypeInfo_GetTypeAttr(ti, &typeattr); + ok(hr == S_OK, "Failed to get type attr, hr %#x.\n", hr); + ok(!(typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE), "Unexpected type flags %#x.\n", typeattr->wTypeFlags); + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + + hr = ICreateTypeInfo2_AddImplType(createti2, 0, hreftype); + ok(hr == S_OK, "Failed to add impl type, hr %#x.\n", hr); + + hr = ITypeInfo_GetTypeAttr(ti, &typeattr); + ok(hr == S_OK, "Failed to get type attr, hr %#x.\n", hr); + ok(typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE, "Unexpected type flags %#x.\n", typeattr->wTypeFlags); + ok(typeattr->cImplTypes == 1, "Unexpected cImplTypes value.\n"); + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + + /* Delete impltype, check flags. */ + hr = ICreateTypeInfo2_DeleteImplType(createti2, 0); + ok(hr == S_OK, "Failed to delete impl type, hr %#x.\n", hr); + + hr = ICreateTypeInfo2_DeleteImplType(createti2, 0); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "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->wTypeFlags & TYPEFLAG_FDISPATCHABLE, "Unexpected type flags %#x.\n", typeattr->wTypeFlags); + ok(!typeattr->cImplTypes, "Unexpected cImplTypes value.\n"); + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + + hr = ITypeInfo_GetImplTypeFlags(ti, 0, &flags); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "Unexpected hr %#x.\n", hr); + + hr = ITypeInfo_GetRefTypeOfImplType(ti, 0, &hreftype2); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "Unexpected hr %#x.\n", hr); + + 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->wTypeFlags & TYPEFLAG_FDISPATCHABLE, "Unexpected type flags %#x.\n", typeattr->wTypeFlags); + ok(!typeattr->cImplTypes, "Unexpected cImplTypes value.\n"); + ITypeInfo_ReleaseTypeAttr(ti, typeattr); + ITypeInfo_Release(ti); + + ITypeLib_Release(tl); + + ITypeLib_Release(stdole); + ITypeInfo_Release(dispti); + + DeleteFileW(filenameW); +} + START_TEST(typelib) { const char *filename; @@ -6486,4 +6583,5 @@ START_TEST(typelib) test_GetLibAttr(); test_stub(); test_dep(); + test_DeleteImplType(); } diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 6d96cc5fbe..e629ed51d5 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -11356,8 +11356,25 @@ static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(ICreateTypeInfo2 *iface, UINT index) { ITypeInfoImpl *This = info_impl_from_ICreateTypeInfo2(iface); - FIXME("%p %u - stub\n", This, index); - return E_NOTIMPL; + int i; + + TRACE("%p %u\n", This, index); + + if (index >= This->typeattr.cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; + + TLB_FreeCustData(&This->impltypes[index].custdata_list); + --This->typeattr.cImplTypes; + + if (index < This->typeattr.cImplTypes) + { + memmove(This->impltypes + index, This->impltypes + index + 1, (This->typeattr.cImplTypes - index) * + sizeof(*This->impltypes)); + for (i = index; i < This->typeattr.cImplTypes; ++i) + TLB_relink_custdata(&This->impltypes[i].custdata_list); + } + + return S_OK; }
static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(ICreateTypeInfo2 *iface,