From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/vccorlib140/tests/vccorlib.c | 57 +++++++++++++++++++++++++++++-- dlls/vccorlib140/vccorlib.c | 12 +++++-- dlls/vccorlib140/vccorlib140.spec | 4 +-- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/dlls/vccorlib140/tests/vccorlib.c b/dlls/vccorlib140/tests/vccorlib.c index a88c6c228f0..a9fb81a5f63 100644 --- a/dlls/vccorlib140/tests/vccorlib.c +++ b/dlls/vccorlib140/tests/vccorlib.c @@ -131,6 +131,7 @@ static HSTRING (__cdecl *p_platform_type_ToString)(void *); static HSTRING (__cdecl *p_platform_type_get_FullName)(void *); static void *(WINAPI *pCreateValue)(int type, const void *); static void *(__cdecl *pAllocateException)(size_t); +static void *(__cdecl *pAllocateExceptionWithWeakRef)(ptrdiff_t, size_t); static void (__cdecl *pFreeException)(void *); static void *(__cdecl *p__RTtypeid)(const void *); @@ -176,6 +177,8 @@ static BOOL init(void) p_platform_type_get_FullName = (void *)GetProcAddress(hmod, "?get(a)FullName@Type(a)Platform@@Q$AAAP$AAVString(a)3@XZ"); pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue(a)Details@Platform@@YAP$AAVObject(a)2@W4TypeCode(a)2@PBX(a)Z"); pAllocateException = (void *)GetProcAddress(hmod, "?AllocateException(a)Heap@Details(a)Platform@@SAPAXI(a)Z"); + pAllocateExceptionWithWeakRef = (void *)GetProcAddress(hmod, + "?AllocateException(a)Heap@Details(a)Platform@@SAPAXII(a)Z"); pFreeException = (void *)GetProcAddress(hmod, "?FreeException(a)Heap@Details(a)Platform@@SAXPAX(a)Z"); p_type_info_name = (void *)GetProcAddress(msvcrt, "?name(a)type_info@@QBAPBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name(a)type_info@@QBAPBDXZ"); @@ -203,6 +206,8 @@ static BOOL init(void) pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue(a)Details@Platform@@YAPE$AAVObject(a)2@W4TypeCode(a)2@PEBX(a)Z"); pAllocateException = (void *)GetProcAddress(hmod, "?AllocateException(a)Heap@Details(a)Platform@@SAPEAX_K(a)Z"); + pAllocateExceptionWithWeakRef = (void *)GetProcAddress(hmod, + "?AllocateException(a)Heap@Details(a)Platform@@SAPEAX_K0(a)Z"); pFreeException = (void *)GetProcAddress(hmod, "?FreeException(a)Heap@Details(a)Platform@@SAXPEAX(a)Z"); p_type_info_name = (void *)GetProcAddress(msvcrt, "?name(a)type_info@@QEBAPEBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name(a)type_info@@QEBAPEBDXZ"); @@ -229,6 +234,8 @@ static BOOL init(void) pCreateValue = (void *)GetProcAddress(hmod, "?CreateValue(a)Details@Platform@@YGP$AAVObject(a)2@W4TypeCode(a)2@PBX(a)Z"); pAllocateException = (void *)GetProcAddress(hmod, "?AllocateException(a)Heap@Details(a)Platform@@SAPAXI(a)Z"); + pAllocateExceptionWithWeakRef = (void *)GetProcAddress(hmod, + "?AllocateException(a)Heap@Details(a)Platform@@SAPAXII(a)Z"); pFreeException = (void *)GetProcAddress(hmod, "?FreeException(a)Heap@Details(a)Platform@@SAXPAX(a)Z"); p_type_info_name = (void *)GetProcAddress(msvcrt, "?name(a)type_info@@QBEPBDXZ"); p_type_info_raw_name = (void *)GetProcAddress(msvcrt, "?raw_name(a)type_info@@QBEPBDXZ"); @@ -249,6 +256,7 @@ static BOOL init(void) ok(p_platform_type_get_FullName != NULL, "Platform::Type::FullName not available\n"); ok(pCreateValue != NULL, "CreateValue not available\n"); ok(pAllocateException != NULL, "AllocateException not available\n"); + ok(pAllocateExceptionWithWeakRef != NULL, "AllocateExceptionWithWeakRef not available.\n"); ok(pFreeException != NULL, "FreeException not available\n"); ok(p_type_info_name != NULL, "type_info::name not available\n"); @@ -512,9 +520,10 @@ struct control_block LONG ref_strong; IUnknown *object; bool is_inline; - UINT16 unknown; + bool unknown; + bool is_exception; #ifdef _WIN32 - char _padding[4]; + char _padding[5]; #endif }; @@ -646,6 +655,7 @@ static void test_AllocateWithWeakRef_inline(void) ok(object->weakref->object == &object->IUnknown_iface, "got object %p != %p\n", object->weakref->object, &object->IUnknown_iface); ok(object->weakref->unknown == 0, "got unknown %d\n", object->weakref->unknown); + ok(!object->weakref->is_exception, "got is_exception %d\n", object->weakref->is_exception); /* The object is allocate within the weakref. */ ok((char *)object->weakref == ((char *)object - sizeof(struct control_block)), "got %p != %p\n", object->weakref, (char *)object - sizeof(struct control_block)); @@ -703,6 +713,49 @@ static void test_AllocateWithWeakRef(void) ok(object->weakref->object == &object->IUnknown_iface, "got object %p != %p\n", object->weakref->object, &object->IUnknown_iface); ok(object->weakref->unknown == 0, "got unknown %d\n", object->weakref->unknown); + ok(!object->weakref->is_exception, "got is_exception %d\n", object->weakref->is_exception); + + hr = IWeakReference_Resolve(weakref, &IID_IAgileObject, (IInspectable **)&out); + ok(hr == S_OK, "got hr %#lx\n", hr); + test_refcount(&object->IUnknown_iface, 2); + IUnknown_Release(out); + + call_func1(pReleaseTarget, object->weakref); + hr = IWeakReference_Resolve(weakref, &IID_IAgileObject, (IInspectable **)&out); + ok(hr == S_OK, "got hr %#lx\n", hr); + test_refcount(&object->IUnknown_iface, 2); + IUnknown_Release(out); + + count = IWeakReference_AddRef(weakref); + ok(count == 2, "got count %lu\n", count); + + count = IUnknown_Release(&object->IUnknown_iface); + ok(count == 0, "got count %lu\n", count); + test_refcount(weakref, 1); + out = (IUnknown *)0xdeadbeef; + hr = IWeakReference_Resolve(weakref, &IID_IAgileObject, (IInspectable **)&out); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(out == (IUnknown *)0xdeadbeef, "got out %p\n", out); + count = IWeakReference_Release(weakref); + ok(count == 0, "got count %lu\n", count); + + /* AllocateExceptionWithWeakRef will not store the control block inline, regardless of the size. */ + object = pAllocateExceptionWithWeakRef(offsetof(struct unknown_impl, weakref), sizeof(struct unknown_impl)); + todo_wine ok(object != NULL, "got object %p\n", object); + if (!object) return; + + object->strong_ref_free_val = -100; + ok(object->weakref != NULL, "got weakref %p\n", object->weakref); + object->IUnknown_iface.lpVtbl = &unknown_impl_vtbl; + weakref = &object->weakref->IWeakReference_iface; + + test_refcount(weakref, 1); + ok(!object->weakref->is_inline, "got is_inline %d\n", object->weakref->is_inline); + ok(object->weakref->ref_strong == 1, "got ref_strong %lu\n", object->weakref->ref_strong); + ok(object->weakref->object == &object->IUnknown_iface, "got object %p != %p\n", object->weakref->object, + &object->IUnknown_iface); + ok(object->weakref->unknown == 0, "got unknown %d\n", object->weakref->unknown); + ok(object->weakref->is_exception, "got is_exception %d\n", object->weakref->is_exception); hr = IWeakReference_Resolve(weakref, &IID_IAgileObject, (IInspectable **)&out); ok(hr == S_OK, "got hr %#lx\n", hr); diff --git a/dlls/vccorlib140/vccorlib.c b/dlls/vccorlib140/vccorlib.c index e642f7b8d27..22ac7e5c2d8 100644 --- a/dlls/vccorlib140/vccorlib.c +++ b/dlls/vccorlib140/vccorlib.c @@ -126,9 +126,10 @@ struct control_block LONG ref_strong; IUnknown *object; bool is_inline; - UINT16 unknown; + bool unknown; + bool is_exception; #ifdef _WIN32 - char _padding[4]; + char _padding[5]; #endif }; @@ -228,10 +229,17 @@ void *__cdecl AllocateWithWeakRef(ptrdiff_t offset, size_t size) weakref->object = object; weakref->ref_strong = weakref->ref_weak = 1; weakref->unknown = 0; + weakref->is_exception = FALSE; return weakref->object; } +void *__cdecl AllocateExceptionWithWeakRef(ptrdiff_t offset, size_t size) +{ + FIXME("(%Iu, %Iu): stub!\n", offset, size); + return NULL; +} + DEFINE_THISCALL_WRAPPER(control_block_ReleaseTarget, 4) void __thiscall control_block_ReleaseTarget(struct control_block *weakref) { diff --git a/dlls/vccorlib140/vccorlib140.spec b/dlls/vccorlib140/vccorlib140.spec index 36ed8606ad4..a77ac7d414e 100644 --- a/dlls/vccorlib140/vccorlib140.spec +++ b/dlls/vccorlib140/vccorlib140.spec @@ -508,8 +508,8 @@ @ cdecl -arch=win32 ?Allocate(a)Heap@Details(a)Platform@@SAPAXII(a)Z(long long) AllocateWithWeakRef @ cdecl -arch=win64 ?Allocate(a)Heap@Details(a)Platform@@SAPEAX_K0(a)Z(long long) AllocateWithWeakRef @ cdecl -arch=win32 ?AllocateException(a)Heap@Details(a)Platform@@SAPAXI(a)Z(long) AllocateException -@ stub -arch=win64 ?AllocateException(a)Heap@Details(a)Platform@@SAPEAX_K0(a)Z -@ stub -arch=win32 ?AllocateException(a)Heap@Details(a)Platform@@SAPAXII(a)Z +@ cdecl -arch=win64 ?AllocateException(a)Heap@Details(a)Platform@@SAPEAX_K0(a)Z(long long) AllocateExceptionWithWeakRef +@ cdecl -arch=win32 ?AllocateException(a)Heap@Details(a)Platform@@SAPAXII(a)Z(long long) AllocateExceptionWithWeakRef @ cdecl -arch=win64 ?AllocateException(a)Heap@Details(a)Platform@@SAPEAX_K(a)Z(long) AllocateException @ stub ?Compare(a)Duration@Xaml(a)UI@Windows@@SAHV1234(a)0@Z @ stub -arch=win32 ??0COMException(a)Platform@@Q$AAA(a)HP$AAVString(a)1@@Z -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9300