mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-04 19:58:08 +00:00
windows.devices.geolocation.geolocator: Implement IWeakReference.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55126
This commit is contained in:
parent
f40c3f6323
commit
9617c784b9
|
@ -34,7 +34,9 @@ struct geolocator
|
||||||
{
|
{
|
||||||
IGeolocator IGeolocator_iface;
|
IGeolocator IGeolocator_iface;
|
||||||
IWeakReferenceSource IWeakReferenceSource_iface;
|
IWeakReferenceSource IWeakReferenceSource_iface;
|
||||||
LONG ref;
|
IWeakReference IWeakReference_iface;
|
||||||
|
LONG ref_public;
|
||||||
|
LONG ref_weak;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct geolocator *impl_from_IGeolocator(IGeolocator *iface)
|
static inline struct geolocator *impl_from_IGeolocator(IGeolocator *iface)
|
||||||
|
@ -73,16 +75,18 @@ static HRESULT WINAPI geolocator_QueryInterface(IGeolocator *iface, REFIID iid,
|
||||||
static ULONG WINAPI geolocator_AddRef(IGeolocator *iface)
|
static ULONG WINAPI geolocator_AddRef(IGeolocator *iface)
|
||||||
{
|
{
|
||||||
struct geolocator *impl = impl_from_IGeolocator(iface);
|
struct geolocator *impl = impl_from_IGeolocator(iface);
|
||||||
ULONG ref = InterlockedIncrement(&impl->ref);
|
ULONG ref = InterlockedIncrement(&impl->ref_public);
|
||||||
TRACE("iface %p increasing refcount to %lu.\n", iface, ref);
|
TRACE("iface %p increasing refcount to %lu.\n", iface, ref);
|
||||||
|
IWeakReference_AddRef(&impl->IWeakReference_iface);
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI geolocator_Release(IGeolocator *iface)
|
static ULONG WINAPI geolocator_Release(IGeolocator *iface)
|
||||||
{
|
{
|
||||||
struct geolocator *impl = impl_from_IGeolocator(iface);
|
struct geolocator *impl = impl_from_IGeolocator(iface);
|
||||||
ULONG ref = InterlockedDecrement(&impl->ref);
|
ULONG ref = InterlockedDecrement(&impl->ref_public);
|
||||||
TRACE("iface %p decreasing refcount to %lu.\n", iface, ref);
|
TRACE("iface %p decreasing refcount to %lu.\n", iface, ref);
|
||||||
|
IWeakReference_Release(&impl->IWeakReference_iface);
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +211,77 @@ static const struct IGeolocatorVtbl geolocator_vtbl =
|
||||||
geolocator_remove_StatusChanged,
|
geolocator_remove_StatusChanged,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline struct geolocator *impl_from_IWeakReference(IWeakReference *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct geolocator, IWeakReference_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI weak_reference_QueryInterface(IWeakReference *iface, REFIID iid, void **out)
|
||||||
|
{
|
||||||
|
struct geolocator *impl = impl_from_IWeakReference(iface);
|
||||||
|
|
||||||
|
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
|
||||||
|
|
||||||
|
if (IsEqualGUID(iid, &IID_IUnknown) ||
|
||||||
|
IsEqualGUID(iid, &IID_IWeakReference))
|
||||||
|
{
|
||||||
|
*out = &impl->IWeakReference_iface;
|
||||||
|
IInspectable_AddRef(*out);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
|
||||||
|
*out = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI weak_reference_AddRef(IWeakReference *iface)
|
||||||
|
{
|
||||||
|
struct geolocator *impl = impl_from_IWeakReference(iface);
|
||||||
|
ULONG ref = InterlockedIncrement(&impl->ref_weak);
|
||||||
|
TRACE("iface %p increasing refcount to %lu.\n", iface, ref);
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI weak_reference_Release(IWeakReference *iface)
|
||||||
|
{
|
||||||
|
struct geolocator *impl = impl_from_IWeakReference(iface);
|
||||||
|
ULONG ref = InterlockedDecrement(&impl->ref_weak);
|
||||||
|
if (!ref)
|
||||||
|
free(impl);
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI weak_reference_Resolve(IWeakReference *iface, REFIID iid, IInspectable **out)
|
||||||
|
{
|
||||||
|
struct geolocator *impl = impl_from_IWeakReference(iface);
|
||||||
|
HRESULT hr;
|
||||||
|
LONG ref;
|
||||||
|
|
||||||
|
TRACE("iface %p, iid %s, out %p stub.\n", iface, debugstr_guid(iid), out);
|
||||||
|
|
||||||
|
*out = NULL;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!(ref = ReadNoFence(&impl->ref_public)))
|
||||||
|
return S_OK;
|
||||||
|
} while (ref != InterlockedCompareExchange(&impl->ref_public, ref + 1, ref));
|
||||||
|
|
||||||
|
hr = IGeolocator_QueryInterface(&impl->IGeolocator_iface, iid, (void **)out);
|
||||||
|
InterlockedDecrement(&impl->ref_public);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct IWeakReferenceVtbl weak_reference_vtbl =
|
||||||
|
{
|
||||||
|
weak_reference_QueryInterface,
|
||||||
|
weak_reference_AddRef,
|
||||||
|
weak_reference_Release,
|
||||||
|
/* IWeakReference methods */
|
||||||
|
weak_reference_Resolve,
|
||||||
|
};
|
||||||
|
|
||||||
static inline struct geolocator *impl_from_IWeakReferenceSource(IWeakReferenceSource *iface)
|
static inline struct geolocator *impl_from_IWeakReferenceSource(IWeakReferenceSource *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, struct geolocator, IWeakReferenceSource_iface);
|
return CONTAINING_RECORD(iface, struct geolocator, IWeakReferenceSource_iface);
|
||||||
|
@ -232,8 +307,12 @@ static ULONG WINAPI weak_reference_source_Release(IWeakReferenceSource *iface)
|
||||||
|
|
||||||
static HRESULT WINAPI weak_reference_source_GetWeakReference(IWeakReferenceSource *iface, IWeakReference **ref)
|
static HRESULT WINAPI weak_reference_source_GetWeakReference(IWeakReferenceSource *iface, IWeakReference **ref)
|
||||||
{
|
{
|
||||||
FIXME("iface %p, ref %p stub.\n", iface, ref);
|
struct geolocator *impl = impl_from_IWeakReferenceSource(iface);
|
||||||
return E_NOTIMPL;
|
|
||||||
|
TRACE("iface %p, ref %p stub.\n", iface, ref);
|
||||||
|
*ref = &impl->IWeakReference_iface;
|
||||||
|
IWeakReference_AddRef(*ref);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct IWeakReferenceSourceVtbl weak_reference_source_vtbl =
|
static const struct IWeakReferenceSourceVtbl weak_reference_source_vtbl =
|
||||||
|
@ -321,7 +400,9 @@ static HRESULT WINAPI factory_ActivateInstance(IActivationFactory *iface, IInspe
|
||||||
|
|
||||||
impl->IGeolocator_iface.lpVtbl = &geolocator_vtbl;
|
impl->IGeolocator_iface.lpVtbl = &geolocator_vtbl;
|
||||||
impl->IWeakReferenceSource_iface.lpVtbl = &weak_reference_source_vtbl;
|
impl->IWeakReferenceSource_iface.lpVtbl = &weak_reference_source_vtbl;
|
||||||
impl->ref = 1;
|
impl->IWeakReference_iface.lpVtbl = &weak_reference_vtbl;
|
||||||
|
impl->ref_public = 1;
|
||||||
|
impl->ref_weak = 1;
|
||||||
|
|
||||||
*instance = (IInspectable *)&impl->IGeolocator_iface;
|
*instance = (IInspectable *)&impl->IGeolocator_iface;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
|
@ -54,7 +54,11 @@ void test_basic(void)
|
||||||
IActivationFactory *factory;
|
IActivationFactory *factory;
|
||||||
IInspectable *inspectable;
|
IInspectable *inspectable;
|
||||||
IGeolocator *geolocator;
|
IGeolocator *geolocator;
|
||||||
|
IGeolocator *geolocator2;
|
||||||
IWeakReferenceSource *weak_reference_source;
|
IWeakReferenceSource *weak_reference_source;
|
||||||
|
IWeakReference *weak_reference;
|
||||||
|
IUnknown* unknown;
|
||||||
|
void *dummy;
|
||||||
HSTRING str;
|
HSTRING str;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -91,9 +95,47 @@ void test_basic(void)
|
||||||
|
|
||||||
hr = IGeolocator_QueryInterface(geolocator, &IID_IWeakReferenceSource, (void **)&weak_reference_source);
|
hr = IGeolocator_QueryInterface(geolocator, &IID_IWeakReferenceSource, (void **)&weak_reference_source);
|
||||||
ok(hr == S_OK && weak_reference_source, "got hr %#lx.\n", hr);
|
ok(hr == S_OK && weak_reference_source, "got hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
hr = IWeakReferenceSource_GetWeakReference(weak_reference_source, &weak_reference);
|
||||||
|
ok(hr == S_OK && weak_reference, "got hr %#lx.\n", hr);
|
||||||
IWeakReferenceSource_Release(weak_reference_source);
|
IWeakReferenceSource_Release(weak_reference_source);
|
||||||
|
|
||||||
|
hr = IWeakReference_Resolve(weak_reference, &IID_IUnknown, (IInspectable **)&unknown);
|
||||||
|
ok(hr == S_OK && unknown, "got hr %#lx.\n", hr);
|
||||||
|
hr = IWeakReference_Resolve(weak_reference, &IID_IGeolocator, (IInspectable **)&geolocator2);
|
||||||
|
ok(hr == S_OK && geolocator2, "got hr %#lx.\n", hr);
|
||||||
|
hr = IWeakReference_Resolve(weak_reference, &IID_IInspectable, &inspectable);
|
||||||
|
ok(hr == S_OK && inspectable, "got hr %#lx.\n", hr);
|
||||||
|
ok((void *)inspectable == (void *)geolocator, "Interfaces are not the same\n");
|
||||||
|
ok((void *)unknown == (void *)geolocator, "Interfaces are not the same\n");
|
||||||
|
IUnknown_Release(unknown);
|
||||||
|
IGeolocator_Release(geolocator2);
|
||||||
|
geolocator2 = 0;
|
||||||
|
IInspectable_Release(inspectable);
|
||||||
|
inspectable = 0;
|
||||||
|
|
||||||
|
dummy = (void *)0xdeadbeef;
|
||||||
|
hr = IWeakReference_Resolve(weak_reference, &IID_IWeakReference, (IInspectable **)&dummy);
|
||||||
|
ok(hr == E_NOINTERFACE && !dummy, "got hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
check_interface(weak_reference, &IID_IUnknown);
|
||||||
|
check_interface(weak_reference, &IID_IWeakReference);
|
||||||
|
hr = IWeakReference_QueryInterface(weak_reference, &IID_IGeolocator, &dummy);
|
||||||
|
ok(hr == E_NOINTERFACE && !dummy, "got hr %#lx.\n", hr);
|
||||||
|
hr = IWeakReference_QueryInterface(weak_reference, &IID_IAgileObject, &dummy);
|
||||||
|
ok(hr == E_NOINTERFACE && !dummy, "got hr %#lx.\n", hr);
|
||||||
|
hr = IWeakReference_QueryInterface(weak_reference, &IID_IInspectable, &dummy);
|
||||||
|
ok(hr == E_NOINTERFACE && !dummy, "got hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
/* Free geolocator, weak reference should fail to resolve now */
|
||||||
IGeolocator_Release(geolocator);
|
IGeolocator_Release(geolocator);
|
||||||
|
|
||||||
|
hr = IWeakReference_Resolve(weak_reference, &IID_IGeolocator, (IInspectable **)&geolocator2);
|
||||||
|
ok(hr == S_OK && !geolocator2, "got hr %#lx.\n", hr);
|
||||||
|
hr = IWeakReference_Resolve(weak_reference, &IID_IWeakReference, (IInspectable **)&dummy);
|
||||||
|
ok(hr == S_OK && !dummy, "got hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
IWeakReference_Release(weak_reference);
|
||||||
IActivationFactory_Release(factory);
|
IActivationFactory_Release(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue