From: Fabian Maurer dark.shadow4@web.de
--- .../main.c | 205 +++++++++++++++++- .../tests/geolocator.c | 18 ++ .../tests/geolocator.c.orig | 124 +++++++++++ 3 files changed, 338 insertions(+), 9 deletions(-) create mode 100644 dlls/windows.devices.geolocation.geolocator/tests/geolocator.c.orig
diff --git a/dlls/windows.devices.geolocation.geolocator/main.c b/dlls/windows.devices.geolocation.geolocator/main.c index 290a63a992e..0c4c01e78dd 100644 --- a/dlls/windows.devices.geolocation.geolocator/main.c +++ b/dlls/windows.devices.geolocation.geolocator/main.c @@ -33,20 +33,192 @@ static const char *debugstr_hstring(HSTRING hstr) return wine_dbgstr_wn(str, len); }
-struct geolocator +struct geolocator_factory { IActivationFactory IActivationFactory_iface; LONG ref; };
-static inline struct geolocator *impl_from_IActivationFactory(IActivationFactory *iface) +struct geolocator +{ + IGeolocator IGeolocator_iface; + LONG ref; +}; + +static inline struct geolocator *impl_from_IGeolocator(IGeolocator *iface) +{ + return CONTAINING_RECORD(iface, struct geolocator, IGeolocator_iface); +} + +static HRESULT WINAPI geolocator_QueryInterface(IGeolocator *iface, REFIID iid, void **out) +{ + struct geolocator *impl = impl_from_IGeolocator(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || + IsEqualGUID(iid, &IID_IGeolocator)) + { + *out = &impl->IGeolocator_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 geolocator_AddRef(IGeolocator *iface) +{ + struct geolocator *impl = impl_from_IGeolocator(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p increasing refcount to %lu.\n", iface, ref); + return ref; +} + +static ULONG WINAPI geolocator_Release(IGeolocator *iface) +{ + struct geolocator *impl = impl_from_IGeolocator(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p decreasing refcount to %lu.\n", iface, ref); + return ref; +} + +static HRESULT WINAPI geolocator_GetIids(IGeolocator *iface, ULONG *iid_count, IID **iids) +{ + FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids); + return E_NOTIMPL; +} + +static HRESULT WINAPI geolocator_GetRuntimeClassName(IGeolocator *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT WINAPI geolocator_GetTrustLevel(IGeolocator *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_get_DesiredAccuracy(IGeolocator *iface, PositionAccuracy *value) +{ + FIXME("iface %p, value %p stub.\n", iface, value); + *value = 0; + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_set_DesiredAccuracy(IGeolocator *iface, PositionAccuracy value) +{ + FIXME("iface %p, value %d stub.\n", iface, value); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_get_MovementThreshold(IGeolocator *iface, DOUBLE *value) +{ + FIXME("iface %p, value %p stub.\n", iface, value); + *value = 0; + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_set_MovementThreshold(IGeolocator *iface, DOUBLE value) +{ + FIXME("iface %p, value %f stub.\n", iface, value); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_get_ReportInterval(IGeolocator *iface, UINT32 *value) +{ + FIXME("iface %p, value %p stub.\n", iface, value); + *value = 0; + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_set_ReportInterval(IGeolocator *iface, UINT32 value) +{ + FIXME("iface %p, value %u stub.\n", iface, value); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_LocationStatus(IGeolocator *iface, PositionStatus *value) +{ + FIXME("iface %p, value %p stub.\n", iface, value); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_GetGeopositionAsync(IGeolocator *iface, IAsyncOperation_Geoposition **value) +{ + FIXME("iface %p, value %p stub.\n", iface, value); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_GetGeopositionAsyncWithAgeAndTimeout(IGeolocator *iface, TimeSpan maximum_age, TimeSpan timeout, IAsyncOperation_Geoposition **value) +{ + FIXME("iface %p, maximum_age %#I64x, timeout %#I64x, value %p stub.\n", iface, maximum_age.Duration, timeout.Duration, value); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_add_PositionChanged(IGeolocator *iface, ITypedEventHandler_Geolocator_PositionChangedEventArgs *handler, EventRegistrationToken *token) +{ + FIXME("iface %p, handler %p, token %p stub.\n", iface, handler, token); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_remove_PositionChanged(IGeolocator *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub.\n", iface, token.value); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_add_StatusChanged(IGeolocator *iface, ITypedEventHandler_Geolocator_StatusChangedEventArgs *handler, EventRegistrationToken *token) +{ + FIXME("iface %p, handler %p, token %p stub.\n", iface, handler, token); + return E_NOTIMPL; +} + +HRESULT WINAPI geolocator_remove_StatusChanged(IGeolocator *iface, EventRegistrationToken token) +{ + FIXME("iface %p, token %#I64x stub.\n", iface, token.value); + return E_NOTIMPL; +} + +static const struct IGeolocatorVtbl geolocator_vtbl = +{ + geolocator_QueryInterface, + geolocator_AddRef, + geolocator_Release, + /* IInspectable methods */ + geolocator_GetIids, + geolocator_GetRuntimeClassName, + geolocator_GetTrustLevel, + /* IGeolocator methods */ + geolocator_get_DesiredAccuracy, + geolocator_set_DesiredAccuracy, + geolocator_get_MovementThreshold, + geolocator_set_MovementThreshold, + geolocator_get_ReportInterval, + geolocator_set_ReportInterval, + geolocator_LocationStatus, + geolocator_GetGeopositionAsync, + geolocator_GetGeopositionAsyncWithAgeAndTimeout, + geolocator_add_PositionChanged, + geolocator_remove_PositionChanged, + geolocator_add_StatusChanged, + geolocator_remove_StatusChanged, +}; + +static inline struct geolocator_factory *impl_from_IActivationFactory(IActivationFactory *iface) { - return CONTAINING_RECORD(iface, struct geolocator, IActivationFactory_iface); + return CONTAINING_RECORD(iface, struct geolocator_factory, IActivationFactory_iface); }
static HRESULT WINAPI factory_QueryInterface(IActivationFactory *iface, REFIID iid, void **out) { - struct geolocator *impl = impl_from_IActivationFactory(iface); + struct geolocator_factory *impl = impl_from_IActivationFactory(iface);
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
@@ -67,7 +239,7 @@ static HRESULT WINAPI factory_QueryInterface(IActivationFactory *iface, REFIID i
static ULONG WINAPI factory_AddRef(IActivationFactory *iface) { - struct geolocator *impl = impl_from_IActivationFactory(iface); + struct geolocator_factory *impl = impl_from_IActivationFactory(iface); ULONG ref = InterlockedIncrement(&impl->ref); TRACE("iface %p increasing refcount to %lu.\n", iface, ref); return ref; @@ -75,7 +247,7 @@ static ULONG WINAPI factory_AddRef(IActivationFactory *iface)
static ULONG WINAPI factory_Release(IActivationFactory *iface) { - struct geolocator *impl = impl_from_IActivationFactory(iface); + struct geolocator_factory *impl = impl_from_IActivationFactory(iface); ULONG ref = InterlockedDecrement(&impl->ref); TRACE("iface %p decreasing refcount to %lu.\n", iface, ref); return ref; @@ -99,10 +271,25 @@ static HRESULT WINAPI factory_GetTrustLevel(IActivationFactory *iface, TrustLeve return E_NOTIMPL; }
+static const struct IActivationFactoryVtbl factory_vtbl; + static HRESULT WINAPI factory_ActivateInstance(IActivationFactory *iface, IInspectable **instance) { - FIXME("iface %p, instance %p stub!\n", iface, instance); - return E_NOTIMPL; + struct geolocator *impl; + + TRACE("iface %p, instance %p.\n", iface, instance); + + if (!(impl = calloc(1, sizeof(*impl)))) + { + *instance = NULL; + return E_OUTOFMEMORY; + } + + impl->IGeolocator_iface.lpVtbl = &geolocator_vtbl; + impl->ref = 1; + + *instance = (IInspectable *)&impl->IGeolocator_iface; + return S_OK; }
static const struct IActivationFactoryVtbl factory_vtbl = @@ -118,7 +305,7 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
-static struct geolocator geolocator_statics = +static struct geolocator_factory geolocator_statics = { {&factory_vtbl}, 1, diff --git a/dlls/windows.devices.geolocation.geolocator/tests/geolocator.c b/dlls/windows.devices.geolocation.geolocator/tests/geolocator.c index eb22407c74a..046eacd9c84 100644 --- a/dlls/windows.devices.geolocation.geolocator/tests/geolocator.c +++ b/dlls/windows.devices.geolocation.geolocator/tests/geolocator.c @@ -51,6 +51,8 @@ void test_basic(void) { static const WCHAR *geolocator_name = L"Windows.Devices.Geolocation.Geolocator"; IActivationFactory *factory; + IInspectable *inspectable; + IGeolocator *geolocator; HSTRING str; HRESULT hr;
@@ -70,6 +72,22 @@ void test_basic(void) check_interface(factory, &IID_IInspectable, FALSE); check_interface(factory, &IID_IAgileObject, TRUE); check_interface(factory, &IID_IActivationFactory, FALSE); + + hr = IActivationFactory_ActivateInstance(factory, &inspectable); + ok(hr == S_OK && inspectable, "got hr %#lx.\n", hr); + + check_interface(inspectable, &IID_IUnknown, FALSE); + check_interface(inspectable, &IID_IInspectable, FALSE); + check_interface(inspectable, &IID_IAgileObject, FALSE); + + hr = IInspectable_QueryInterface(inspectable, &IID_IGeolocator, (void **)&geolocator); + ok(hr == S_OK && geolocator, "got hr %#lx.\n", hr); + ok((void*)inspectable == (void*)geolocator, "Interfaces are not the same\n"); + + IInspectable_Release(inspectable); + inspectable = 0; + + IGeolocator_Release(geolocator); }
START_TEST(geolocator) diff --git a/dlls/windows.devices.geolocation.geolocator/tests/geolocator.c.orig b/dlls/windows.devices.geolocation.geolocator/tests/geolocator.c.orig new file mode 100644 index 00000000000..7fb110a0169 --- /dev/null +++ b/dlls/windows.devices.geolocation.geolocator/tests/geolocator.c.orig @@ -0,0 +1,124 @@ +/* + * Copyright 2023 Fabian Maurer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winstring.h" + +#include "initguid.h" +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Devices_Geolocation +#include "windows.devices.geolocation.h" + +#include "wine/test.h" + +#define check_interface(obj, iid, broken_win8) check_interface_(__LINE__, obj, iid, broken_win8) +static void check_interface_(unsigned int line, void *obj, const IID *iid, BOOL broken_win8) +{ + IUnknown *iface = obj; + IUnknown *unk; + HRESULT hr; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == S_OK || (broken_win8 && broken(hr == E_NOINTERFACE)), "got hr %#lx.\n", hr); + if (hr == S_OK) + IUnknown_Release(unk); +} + +void test_basic(void) +{ + static const WCHAR *geolocator_name = L"Windows.Devices.Geolocation.Geolocator"; + IActivationFactory *factory; + HSTRING str; + HRESULT hr; + + hr = WindowsCreateString(geolocator_name, wcslen(geolocator_name), &str); + ok(hr == S_OK, "got hr %#lx.\n", hr); + + hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + WindowsDeleteString(str); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "got hr %#lx.\n", hr); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip("%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w(geolocator_name)); + return; + } + +<<<<<<< HEAD + check_interface(factory, &IID_IUnknown); + check_interface(factory, &IID_IInspectable); + check_interface(factory, &IID_IAgileObject); + check_interface(factory, &IID_IActivationFactory); +======= + check_interface(factory, &IID_IUnknown, FALSE); + check_interface(factory, &IID_IInspectable, FALSE); + check_interface(factory, &IID_IAgileObject, TRUE); + check_interface(factory, &IID_IActivationFactory, FALSE); + + hr = IActivationFactory_ActivateInstance(factory, &inspectable); + ok(hr == S_OK && inspectable, "got hr %#lx.\n", hr); + + check_interface(inspectable, &IID_IUnknown, FALSE); + check_interface(inspectable, &IID_IInspectable, FALSE); + check_interface(inspectable, &IID_IAgileObject, FALSE); + + hr = IInspectable_QueryInterface(inspectable, &IID_IGeolocator, (void **)&geolocator); + ok(hr == S_OK && geolocator, "got hr %#lx.\n", hr); + ok((void*)inspectable == (void*)geolocator, "Interfaces are not the same\n"); + + IInspectable_Release(inspectable); + inspectable = 0; + + hr = IGeolocator_QueryInterface(geolocator, &IID_IWeakReferenceSource, (void **)&weak_reference_source); + 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); + + hr = IWeakReference_Resolve(weak_reference, &IID_IGeolocator, (IInspectable**)&geolocator2); + ok(hr == S_OK && geolocator2, "got hr %#lx.\n", hr); + IGeolocator_Release(geolocator2); + + IGeolocator_Release(geolocator); + + hr = IWeakReference_Resolve(weak_reference, &IID_IGeolocator, (IInspectable**)&geolocator2); + ok(hr == S_OK && !geolocator2, "got hr %#lx.\n", hr); + + IWeakReference_Release(weak_reference); +>>>>>>> b549d61cbeb (f) +} + +START_TEST(geolocator) +{ + HRESULT hr; + + hr = RoInitialize(RO_INIT_MULTITHREADED); + ok(hr == S_OK, "RoInitialize failed, hr %#lx\n", hr); + + test_basic(); + + RoUninitialize(); +}