Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56914
This is also needed by Adobe Premiere Pro 2024.
-- v2: windows.web: Implement IJsonValueStatics::CreateStringValue(). windows.web/tests: Add IJsonValueStatics::CreateStringValue() tests. windows.web: Add IJsonValueStatics stub interface. include: Add IJsonValueStatics interface definition. windows.web: Implement IActivationFactory::ActivateInstance().
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/Makefile.in | 1 + include/windows.data.json.idl | 162 ++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 include/windows.data.json.idl
diff --git a/include/Makefile.in b/include/Makefile.in index d52afd06926..bbf28cfc87e 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -830,6 +830,7 @@ SOURCES = \ windows.applicationmodel.background.idl \ windows.applicationmodel.core.idl \ windows.applicationmodel.idl \ + windows.data.json.idl \ windows.devices.bluetooth.idl \ windows.devices.enumeration.idl \ windows.devices.geolocation.idl \ diff --git a/include/windows.data.json.idl b/include/windows.data.json.idl new file mode 100644 index 00000000000..483d8dce721 --- /dev/null +++ b/include/windows.data.json.idl @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2024 Mohamad Al-Jaf + * + * 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 + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "inspectable.idl"; +import "asyncinfo.idl"; +import "eventtoken.idl"; +import "windowscontracts.idl"; +import "windows.foundation.idl"; + +namespace Windows.Data.Json { + typedef enum JsonValueType JsonValueType; + + interface IJsonArray; + interface IJsonArrayStatics; + interface IJsonObject; + interface IJsonObjectStatics; + interface IJsonObjectWithDefaultValues; + interface IJsonValue; + interface IJsonValueStatics; + interface IJsonValueStatics2; + + runtimeclass JsonArray; + runtimeclass JsonObject; + runtimeclass JsonValue; + + declare { + interface Windows.Foundation.Collections.IKeyValuePair<HSTRING, Windows.Data.Json.IJsonValue *>; + interface Windows.Foundation.Collections.IIterable<Windows.Data.Json.IJsonValue *>; + interface Windows.Foundation.Collections.IIterable<Windows.Foundation.Collections.IKeyValuePair<HSTRING, Windows.Data.Json.IJsonValue *> *>; + interface Windows.Foundation.Collections.IIterator<Windows.Data.Json.IJsonValue *>; + interface Windows.Foundation.Collections.IIterator<Windows.Foundation.Collections.IKeyValuePair<HSTRING, Windows.Data.Json.IJsonValue *> *>; + interface Windows.Foundation.Collections.IMapView<HSTRING, Windows.Data.Json.IJsonValue *>; + interface Windows.Foundation.Collections.IMap<HSTRING, Windows.Data.Json.IJsonValue *>; + interface Windows.Foundation.Collections.IVectorView<Windows.Data.Json.IJsonValue *>; + interface Windows.Foundation.Collections.IVector<Windows.Data.Json.IJsonValue *>; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0) + ] + enum JsonValueType + { + Null = 0, + Boolean = 1, + Number = 2, + String = 3, + Array = 4, + Object = 5, + }; + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Data.Json.JsonArray), + uuid(08c1ddb6-0cbd-4a9a-b5d3-2f852dc37e81) + ] + interface IJsonArray : IInspectable + requires Windows.Data.Json.IJsonValue + { + HRESULT GetObjectAt([in] UINT32 index, [out, retval] Windows.Data.Json.JsonObject **value); + HRESULT GetArrayAt([in] UINT32 index, [out, retval] Windows.Data.Json.JsonArray **value); + HRESULT GetStringAt([in] UINT32 index, [out, retval] HSTRING *value); + HRESULT GetNumberAt([in] UINT32 index, [out, retval] DOUBLE *value); + HRESULT GetBooleanAt([in] UINT32 index, [out, retval] boolean *value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Data.Json.JsonObject), + uuid(064e24dd-29c2-4f83-9ac1-9ee11578beb3) + ] + interface IJsonObject : IInspectable + requires Windows.Data.Json.IJsonValue + { + HRESULT GetNamedValue([in] HSTRING name, [out, retval] Windows.Data.Json.JsonValue **value); + HRESULT SetNamedValue([in] HSTRING name, [in] Windows.Data.Json.IJsonValue *value); + HRESULT GetNamedObject([in] HSTRING name, [out, retval] Windows.Data.Json.JsonObject **value); + HRESULT GetNamedArray([in] HSTRING name, [out, retval] Windows.Data.Json.JsonArray **value); + HRESULT GetNamedString([in] HSTRING name, [out, retval] HSTRING *value); + HRESULT GetNamedNumber([in] HSTRING name, [out, retval] DOUBLE *value); + HRESULT GetNamedBoolean([in] HSTRING name, [out, retval] boolean *value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + uuid(a3219ecb-f0b3-4dcd-beee-19d48cd3ed1e) + ] + interface IJsonValue : IInspectable + { + [propget] HRESULT ValueType([out, retval] Windows.Data.Json.JsonValueType *value); + HRESULT Stringify([out, retval] HSTRING *value); + HRESULT GetString([out, retval] HSTRING *value); + HRESULT GetNumber([out, retval] DOUBLE *value); + HRESULT GetBoolean([out, retval] boolean *value); + HRESULT GetArray([out, retval] Windows.Data.Json.JsonArray **value); + HRESULT GetObject([out, retval] Windows.Data.Json.JsonObject **value); + } + + [ + activatable(Windows.Foundation.UniversalApiContract, 1.0), + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile), + static(Windows.Data.Json.IJsonArrayStatics, Windows.Foundation.UniversalApiContract, 1.0), + threading(both) + ] + runtimeclass JsonArray + { + [default] interface Windows.Data.Json.IJsonArray; + interface Windows.Data.Json.IJsonValue; + interface Windows.Foundation.Collections.IVector<Windows.Data.Json.IJsonValue *>; + interface Windows.Foundation.Collections.IIterable<Windows.Data.Json.IJsonValue *>; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Foundation.IStringable; + } + + [ + activatable(Windows.Foundation.UniversalApiContract, 1.0), + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile), + static(Windows.Data.Json.IJsonObjectStatics, Windows.Foundation.UniversalApiContract, 1.0), + threading(both) + ] + runtimeclass JsonObject + { + [default] interface Windows.Data.Json.IJsonObject; + interface Windows.Data.Json.IJsonValue; + interface Windows.Foundation.Collections.IMap<HSTRING, Windows.Data.Json.IJsonValue *>; + interface Windows.Foundation.Collections.IIterable<Windows.Foundation.Collections.IKeyValuePair<HSTRING, Windows.Data.Json.IJsonValue *> *>; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Data.Json.IJsonObjectWithDefaultValues; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Foundation.IStringable; + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile), + static(Windows.Data.Json.IJsonValueStatics, Windows.Foundation.UniversalApiContract, 1.0), + static(Windows.Data.Json.IJsonValueStatics2, Windows.Foundation.UniversalApiContract, 1.0), + threading(both) + ] + runtimeclass JsonValue + { + [default] interface Windows.Data.Json.IJsonValue; + [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Foundation.IStringable; + } +}
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 2 + dlls/windows.web/Makefile.in | 7 ++ dlls/windows.web/classes.idl | 23 ++++++ dlls/windows.web/json_object.c | 116 +++++++++++++++++++++++++++++ dlls/windows.web/main.c | 46 ++++++++++++ dlls/windows.web/private.h | 40 ++++++++++ dlls/windows.web/tests/Makefile.in | 5 ++ dlls/windows.web/tests/web.c | 90 ++++++++++++++++++++++ dlls/windows.web/windows.web.spec | 6 ++ 9 files changed, 335 insertions(+) create mode 100644 dlls/windows.web/Makefile.in create mode 100644 dlls/windows.web/classes.idl create mode 100644 dlls/windows.web/json_object.c create mode 100644 dlls/windows.web/main.c create mode 100644 dlls/windows.web/private.h create mode 100644 dlls/windows.web/tests/Makefile.in create mode 100644 dlls/windows.web/tests/web.c create mode 100644 dlls/windows.web/windows.web.spec
diff --git a/configure.ac b/configure.ac index 6f48132b22a..4448e781366 100644 --- a/configure.ac +++ b/configure.ac @@ -3267,6 +3267,8 @@ WINE_CONFIG_MAKEFILE(dlls/windows.system.profile.systemmanufacturers) WINE_CONFIG_MAKEFILE(dlls/windows.system.profile.systemmanufacturers/tests) WINE_CONFIG_MAKEFILE(dlls/windows.ui) WINE_CONFIG_MAKEFILE(dlls/windows.ui/tests) +WINE_CONFIG_MAKEFILE(dlls/windows.web) +WINE_CONFIG_MAKEFILE(dlls/windows.web/tests) WINE_CONFIG_MAKEFILE(dlls/windowscodecs) WINE_CONFIG_MAKEFILE(dlls/windowscodecs/tests) WINE_CONFIG_MAKEFILE(dlls/windowscodecsext) diff --git a/dlls/windows.web/Makefile.in b/dlls/windows.web/Makefile.in new file mode 100644 index 00000000000..75b6e0712e2 --- /dev/null +++ b/dlls/windows.web/Makefile.in @@ -0,0 +1,7 @@ +MODULE = windows.web.dll +IMPORTS = combase + +SOURCES = \ + classes.idl \ + json_object.c \ + main.c diff --git a/dlls/windows.web/classes.idl b/dlls/windows.web/classes.idl new file mode 100644 index 00000000000..4fca998e169 --- /dev/null +++ b/dlls/windows.web/classes.idl @@ -0,0 +1,23 @@ +/* + * Runtime Classes for windows.web.dll + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * 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 + */ + +#pragma makedep register + +#include "windows.data.json.idl" diff --git a/dlls/windows.web/json_object.c b/dlls/windows.web/json_object.c new file mode 100644 index 00000000000..b8d56d41052 --- /dev/null +++ b/dlls/windows.web/json_object.c @@ -0,0 +1,116 @@ +/* WinRT Windows.Data.Json.JsonObject Implementation + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * 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 + */ + +#include "private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(web); + +struct json_object_statics +{ + IActivationFactory IActivationFactory_iface; + LONG ref; +}; + +static inline struct json_object_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct json_object_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct json_object_statics *impl = impl_from_IActivationFactory( 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_IActivationFactory )) + { + *out = &impl->IActivationFactory_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 factory_AddRef( IActivationFactory *iface ) +{ + struct json_object_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct json_object_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *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 factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +static struct json_object_statics json_object_statics = +{ + {&factory_vtbl}, + 1, +}; + +IActivationFactory *json_object_factory = &json_object_statics.IActivationFactory_iface; diff --git a/dlls/windows.web/main.c b/dlls/windows.web/main.c new file mode 100644 index 00000000000..5c5013824e4 --- /dev/null +++ b/dlls/windows.web/main.c @@ -0,0 +1,46 @@ +/* WinRT Windows.Web Implementation + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * 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 + */ + +#include "initguid.h" +#include "private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(web); + +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID riid, void **out ) +{ + FIXME( "clsid %s, riid %s, out %p stub!\n", debugstr_guid( clsid ), debugstr_guid( riid ), out ); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **factory ) +{ + const WCHAR *buffer = WindowsGetStringRawBuffer( classid, NULL ); + + TRACE( "class %s, factory %p.\n", debugstr_hstring( classid ), factory ); + + *factory = NULL; + + if (!wcscmp( buffer, RuntimeClass_Windows_Data_Json_JsonObject )) + IActivationFactory_QueryInterface( json_object_factory, &IID_IActivationFactory, (void **)factory ); + + if (*factory) return S_OK; + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/windows.web/private.h b/dlls/windows.web/private.h new file mode 100644 index 00000000000..f9ebd94ad48 --- /dev/null +++ b/dlls/windows.web/private.h @@ -0,0 +1,40 @@ +/* WinRT Windows.Web Implementation + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * 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 + */ + +#ifndef __WINE_WINDOWS_WEB_PRIVATE_H +#define __WINE_WINDOWS_WEB_PRIVATE_H + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "activation.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Data_Json +#include "windows.data.json.h" + +extern IActivationFactory *json_object_factory; + +#endif diff --git a/dlls/windows.web/tests/Makefile.in b/dlls/windows.web/tests/Makefile.in new file mode 100644 index 00000000000..9329346e3c2 --- /dev/null +++ b/dlls/windows.web/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.web.dll +IMPORTS = combase + +SOURCES = \ + web.c diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c new file mode 100644 index 00000000000..ab63861132a --- /dev/null +++ b/dlls/windows.web/tests/web.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2024 Mohamad Al-Jaf + * + * 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 "initguid.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Data_Json +#include "windows.data.json.h" + +#include "wine/test.h" + +#define check_interface( obj, iid ) check_interface_( __LINE__, obj, iid ) +static void check_interface_( unsigned int line, void *obj, const IID *iid ) +{ + IUnknown *iface = obj; + IUnknown *unk; + HRESULT hr; + + hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + IUnknown_Release( unk ); +} + +static void test_JsonObjectStatics(void) +{ + static const WCHAR *json_object_name = L"Windows.Data.Json.JsonObject"; + IActivationFactory *factory = (void *)0xdeadbeef; + IJsonObject *json_object = (void *)0xdeadbeef; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( json_object_name, wcslen( json_object_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( json_object_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown ); + check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IAgileObject ); + + hr = IActivationFactory_QueryInterface( factory, &IID_IJsonObject, (void **)&json_object ); + ok( hr == E_NOINTERFACE, "got hr %#lx.\n", hr ); + + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + +START_TEST(web) +{ + HRESULT hr; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr ); + + test_JsonObjectStatics(); + + RoUninitialize(); +} diff --git a/dlls/windows.web/windows.web.spec b/dlls/windows.web/windows.web.spec new file mode 100644 index 00000000000..1eef8ba134d --- /dev/null +++ b/dlls/windows.web/windows.web.spec @@ -0,0 +1,6 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllMain(long long ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer()
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/json_object.c | 144 ++++++++++++++++++++++++++++++++- dlls/windows.web/tests/web.c | 15 +++- 2 files changed, 156 insertions(+), 3 deletions(-)
diff --git a/dlls/windows.web/json_object.c b/dlls/windows.web/json_object.c index b8d56d41052..38c899288b7 100644 --- a/dlls/windows.web/json_object.c +++ b/dlls/windows.web/json_object.c @@ -22,6 +22,136 @@
WINE_DEFAULT_DEBUG_CHANNEL(web);
+struct json_object +{ + IJsonObject IJsonObject_iface; + LONG ref; +}; + +static inline struct json_object *impl_from_IJsonObject( IJsonObject *iface ) +{ + return CONTAINING_RECORD( iface, struct json_object, IJsonObject_iface ); +} + +static HRESULT WINAPI json_object_statics_QueryInterface( IJsonObject *iface, REFIID iid, void **out ) +{ + struct json_object *impl = impl_from_IJsonObject( 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_IJsonObject )) + { + *out = &impl->IJsonObject_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 json_object_statics_AddRef( IJsonObject *iface ) +{ + struct json_object *impl = impl_from_IJsonObject( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI json_object_statics_Release( IJsonObject *iface ) +{ + struct json_object *impl = impl_from_IJsonObject( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p, ref %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI json_object_statics_GetIids( IJsonObject *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 json_object_statics_GetRuntimeClassName( IJsonObject *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_object_statics_GetTrustLevel( IJsonObject *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_object_statics_GetNamedValue( IJsonObject *iface, HSTRING name, IJsonValue **value ) +{ + FIXME( "iface %p, name %s, value %p stub!\n", iface, debugstr_hstring( name ), value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_object_statics_SetNamedValue( IJsonObject *iface, HSTRING name, IJsonValue *value ) +{ + FIXME( "iface %p, name %s, value %p stub!\n", iface, debugstr_hstring( name ), value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_object_statics_GetNamedObject( IJsonObject *iface, HSTRING name, IJsonObject **value ) +{ + FIXME( "iface %p, name %s, value %p stub!\n", iface, debugstr_hstring( name ), value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_object_statics_GetNamedArray( IJsonObject *iface, HSTRING name, IJsonArray **value ) +{ + FIXME( "iface %p, name %s, value %p stub!\n", iface, debugstr_hstring( name ), value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_object_statics_GetNamedString( IJsonObject *iface, HSTRING name, HSTRING *value ) +{ + FIXME( "iface %p, name %s, value %p stub!\n", iface, debugstr_hstring( name ), value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_object_statics_GetNamedNumber( IJsonObject *iface, HSTRING name, DOUBLE *value ) +{ + FIXME( "iface %p, name %s, value %p stub!\n", iface, debugstr_hstring( name ), value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_object_statics_GetNamedBoolean( IJsonObject *iface, HSTRING name, boolean *value ) +{ + FIXME( "iface %p, name %s, value %p stub!\n", iface, debugstr_hstring( name ), value ); + return E_NOTIMPL; +} + +static const struct IJsonObjectVtbl json_object_statics_vtbl = +{ + json_object_statics_QueryInterface, + json_object_statics_AddRef, + json_object_statics_Release, + /* IInspectable methods */ + json_object_statics_GetIids, + json_object_statics_GetRuntimeClassName, + json_object_statics_GetTrustLevel, + /* IJsonObject methods */ + json_object_statics_GetNamedValue, + json_object_statics_SetNamedValue, + json_object_statics_GetNamedObject, + json_object_statics_GetNamedArray, + json_object_statics_GetNamedString, + json_object_statics_GetNamedNumber, + json_object_statics_GetNamedBoolean, +}; + struct json_object_statics { IActivationFactory IActivationFactory_iface; @@ -90,8 +220,18 @@ static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLev
static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) { - FIXME( "iface %p, instance %p stub!\n", iface, instance ); - return E_NOTIMPL; + struct json_object *impl; + + TRACE( "iface %p, instance %p.\n", iface, instance ); + + *instance = NULL; + if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY; + + impl->IJsonObject_iface.lpVtbl = &json_object_statics_vtbl; + impl->ref = 1; + + *instance = (IInspectable *)&impl->IJsonObject_iface; + return S_OK; }
static const struct IActivationFactoryVtbl factory_vtbl = diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index ab63861132a..4d876b52669 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -49,6 +49,7 @@ static void test_JsonObjectStatics(void) { static const WCHAR *json_object_name = L"Windows.Data.Json.JsonObject"; IActivationFactory *factory = (void *)0xdeadbeef; + IInspectable *inspectable = (void *)0xdeadbeef; IJsonObject *json_object = (void *)0xdeadbeef; HSTRING str; HRESULT hr; @@ -56,7 +57,6 @@ static void test_JsonObjectStatics(void)
hr = WindowsCreateString( json_object_name, wcslen( json_object_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 ); @@ -73,6 +73,19 @@ static void test_JsonObjectStatics(void) hr = IActivationFactory_QueryInterface( factory, &IID_IJsonObject, (void **)&json_object ); ok( hr == E_NOINTERFACE, "got hr %#lx.\n", hr );
+ hr = WindowsCreateString( json_object_name, wcslen( json_object_name ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + hr = RoActivateInstance( str, &inspectable ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + WindowsDeleteString( str ); + + hr = IInspectable_QueryInterface( inspectable, &IID_IJsonObject, (void **)&json_object ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + check_interface( inspectable, &IID_IAgileObject ); + + IJsonObject_Release( json_object ); + IInspectable_Release( inspectable ); ref = IActivationFactory_Release( factory ); ok( ref == 1, "got ref %ld.\n", ref ); }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/windows.data.json.idl | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/include/windows.data.json.idl b/include/windows.data.json.idl index 483d8dce721..c37c0a59b88 100644 --- a/include/windows.data.json.idl +++ b/include/windows.data.json.idl @@ -114,6 +114,20 @@ namespace Windows.Data.Json { HRESULT GetObject([out, retval] Windows.Data.Json.JsonObject **value); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Data.Json.JsonValue), + uuid(5f6b544a-2f53-48e1-91a3-f78b50a6345c) + ] + interface IJsonValueStatics : IInspectable + { + HRESULT Parse([in] HSTRING input, [out, retval] Windows.Data.Json.JsonValue **value); + HRESULT TryParse([in] HSTRING input, [out] Windows.Data.Json.JsonValue **result, [out, retval] boolean *succeeded); + HRESULT CreateBooleanValue([in] boolean input, [out, retval] Windows.Data.Json.JsonValue **value); + HRESULT CreateNumberValue([in] DOUBLE input, [out, retval] Windows.Data.Json.JsonValue **value); + HRESULT CreateStringValue([in] HSTRING input, [out, retval] Windows.Data.Json.JsonValue **value); + } + [ activatable(Windows.Foundation.UniversalApiContract, 1.0), contract(Windows.Foundation.UniversalApiContract, 1.0),
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/Makefile.in | 1 + dlls/windows.web/json_value.c | 174 ++++++++++++++++++++++++++++++++++ dlls/windows.web/main.c | 2 + dlls/windows.web/private.h | 39 ++++++++ dlls/windows.web/tests/web.c | 35 +++++++ 5 files changed, 251 insertions(+) create mode 100644 dlls/windows.web/json_value.c
diff --git a/dlls/windows.web/Makefile.in b/dlls/windows.web/Makefile.in index 75b6e0712e2..ebcf7bbc2f3 100644 --- a/dlls/windows.web/Makefile.in +++ b/dlls/windows.web/Makefile.in @@ -4,4 +4,5 @@ IMPORTS = combase SOURCES = \ classes.idl \ json_object.c \ + json_value.c \ main.c diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c new file mode 100644 index 00000000000..98d41d2c7cf --- /dev/null +++ b/dlls/windows.web/json_value.c @@ -0,0 +1,174 @@ +/* WinRT Windows.Data.Json.JsonValue Implementation + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * 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 + */ + +#include "private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(web); + +struct json_value_statics +{ + IActivationFactory IActivationFactory_iface; + IJsonValueStatics IJsonValueStatics_iface; + LONG ref; +}; + +static inline struct json_value_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct json_value_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct json_value_statics *impl = impl_from_IActivationFactory( 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_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + if (IsEqualGUID( iid, &IID_IJsonValueStatics )) + { + *out = &impl->IJsonValueStatics_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 factory_AddRef( IActivationFactory *iface ) +{ + struct json_value_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct json_value_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *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 factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +DEFINE_IINSPECTABLE( json_value_statics, IJsonValueStatics, struct json_value_statics, IActivationFactory_iface ) + +static HRESULT WINAPI json_value_statics_Parse( IJsonValueStatics *iface, HSTRING input, IJsonValue **value ) +{ + FIXME( "iface %p, input %s, value %p stub!\n", iface, debugstr_hstring( input ), value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_statics_TryParse( IJsonValueStatics *iface, HSTRING input, IJsonValue **result, boolean *succeeded ) +{ + FIXME( "iface %p, input %s, result %p, succeeded %p stub!\n", iface, debugstr_hstring( input ), result, succeeded ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_statics_CreateBooleanValue( IJsonValueStatics *iface, boolean input, IJsonValue **value ) +{ + FIXME( "iface %p, input %d, value %p stub!\n", iface, input, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_statics_CreateNumberValue( IJsonValueStatics *iface, DOUBLE input, IJsonValue **value ) +{ + FIXME( "iface %p, input %f, value %p stub!\n", iface, input, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_statics_CreateStringValue( IJsonValueStatics *iface, HSTRING input, IJsonValue **value ) +{ + FIXME( "iface %p, input %s, value %p stub!\n", iface, debugstr_hstring( input ), value ); + return E_NOTIMPL; +} + +static const struct IJsonValueStaticsVtbl json_value_statics_vtbl = +{ + json_value_statics_QueryInterface, + json_value_statics_AddRef, + json_value_statics_Release, + /* IInspectable methods */ + json_value_statics_GetIids, + json_value_statics_GetRuntimeClassName, + json_value_statics_GetTrustLevel, + /* IJsonValueStatics methods */ + json_value_statics_Parse, + json_value_statics_TryParse, + json_value_statics_CreateBooleanValue, + json_value_statics_CreateNumberValue, + json_value_statics_CreateStringValue, +}; + +static struct json_value_statics json_value_statics = +{ + {&factory_vtbl}, + {&json_value_statics_vtbl}, + 1, +}; + +IActivationFactory *json_value_factory = &json_value_statics.IActivationFactory_iface; diff --git a/dlls/windows.web/main.c b/dlls/windows.web/main.c index 5c5013824e4..60e95fdba0c 100644 --- a/dlls/windows.web/main.c +++ b/dlls/windows.web/main.c @@ -40,6 +40,8 @@ HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **fa
if (!wcscmp( buffer, RuntimeClass_Windows_Data_Json_JsonObject )) IActivationFactory_QueryInterface( json_object_factory, &IID_IActivationFactory, (void **)factory ); + if (!wcscmp( buffer, RuntimeClass_Windows_Data_Json_JsonValue )) + IActivationFactory_QueryInterface( json_value_factory, &IID_IActivationFactory, (void **)factory );
if (*factory) return S_OK; return CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/windows.web/private.h b/dlls/windows.web/private.h index f9ebd94ad48..393affd61e1 100644 --- a/dlls/windows.web/private.h +++ b/dlls/windows.web/private.h @@ -36,5 +36,44 @@ #include "windows.data.json.h"
extern IActivationFactory *json_object_factory; +extern IActivationFactory *json_value_factory; + +#define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ + static inline impl_type *impl_from( iface_type *iface ) \ + { \ + return CONTAINING_RECORD( iface, impl_type, iface_mem ); \ + } \ + static HRESULT WINAPI pfx##_QueryInterface( iface_type *iface, REFIID iid, void **out ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_QueryInterface( (IInspectable *)(expr), iid, out ); \ + } \ + static ULONG WINAPI pfx##_AddRef( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_AddRef( (IInspectable *)(expr) ); \ + } \ + static ULONG WINAPI pfx##_Release( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_Release( (IInspectable *)(expr) ); \ + } \ + static HRESULT WINAPI pfx##_GetIids( iface_type *iface, ULONG *iid_count, IID **iids ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetIids( (IInspectable *)(expr), iid_count, iids ); \ + } \ + static HRESULT WINAPI pfx##_GetRuntimeClassName( iface_type *iface, HSTRING *class_name ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetRuntimeClassName( (IInspectable *)(expr), class_name ); \ + } \ + static HRESULT WINAPI pfx##_GetTrustLevel( iface_type *iface, TrustLevel *trust_level ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetTrustLevel( (IInspectable *)(expr), trust_level ); \ + } +#define DEFINE_IINSPECTABLE( pfx, iface_type, impl_type, base_iface ) \ + DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface )
#endif diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index 4d876b52669..15d0d3c8b35 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -90,6 +90,40 @@ static void test_JsonObjectStatics(void) ok( ref == 1, "got ref %ld.\n", ref ); }
+static void test_JsonValueStatics(void) +{ + static const WCHAR *json_value_statics_name = L"Windows.Data.Json.JsonValue"; + IJsonValueStatics *json_value_statics = (void *)0xdeadbeef; + IActivationFactory *factory = (void *)0xdeadbeef; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( json_value_statics_name, wcslen( json_value_statics_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( json_value_statics_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown ); + check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IAgileObject ); + + hr = IActivationFactory_QueryInterface( factory, &IID_IJsonValueStatics, (void **)&json_value_statics ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + ref = IJsonValueStatics_Release( json_value_statics ); + ok( ref == 2, "got ref %ld.\n", ref ); + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + START_TEST(web) { HRESULT hr; @@ -98,6 +132,7 @@ START_TEST(web) ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr );
test_JsonObjectStatics(); + test_JsonValueStatics();
RoUninitialize(); }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/tests/web.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index 15d0d3c8b35..5bb81d44d13 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -95,6 +95,7 @@ static void test_JsonValueStatics(void) static const WCHAR *json_value_statics_name = L"Windows.Data.Json.JsonValue"; IJsonValueStatics *json_value_statics = (void *)0xdeadbeef; IActivationFactory *factory = (void *)0xdeadbeef; + IJsonValue *json_value = (void *)0xdeadbeef; HSTRING str; HRESULT hr; LONG ref; @@ -118,6 +119,21 @@ static void test_JsonValueStatics(void) hr = IActivationFactory_QueryInterface( factory, &IID_IJsonValueStatics, (void **)&json_value_statics ); ok( hr == S_OK, "got hr %#lx.\n", hr );
+ hr = IJsonValueStatics_CreateStringValue( json_value_statics, NULL, (IJsonValue **)&json_value ); + todo_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); + if (hr == S_OK) IJsonValue_Release( json_value ); + hr = WindowsCreateString( L"Wine", wcslen( L"Wine" ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, NULL ); + todo_wine + ok( hr == E_POINTER, "got hr %#lx.\n", hr ); + hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, (IJsonValue **)&json_value ); + todo_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); + if (hr == S_OK) IJsonValue_Release( json_value ); + WindowsDeleteString( str ); + ref = IJsonValueStatics_Release( json_value_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56914 --- dlls/windows.web/json_value.c | 157 +++++++++++++++++++++++++++++++++- dlls/windows.web/tests/web.c | 6 +- 2 files changed, 157 insertions(+), 6 deletions(-)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index 98d41d2c7cf..87b3365f199 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -115,6 +115,142 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+struct json_value +{ + IJsonValue IJsonValue_iface; + LONG ref; + + HSTRING string_value; +}; + +static inline struct json_value *impl_from_IJsonValue( IJsonValue *iface ) +{ + return CONTAINING_RECORD( iface, struct json_value, IJsonValue_iface ); +} + +static HRESULT WINAPI json_value_QueryInterface( IJsonValue *iface, REFIID iid, void **out ) +{ + struct json_value *impl = impl_from_IJsonValue( 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_IJsonValue )) + { + *out = &impl->IJsonValue_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 json_value_AddRef( IJsonValue *iface ) +{ + struct json_value *impl = impl_from_IJsonValue( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI json_value_Release( IJsonValue *iface ) +{ + struct json_value *impl = impl_from_IJsonValue( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + + if (!ref) + { + WindowsDeleteString( impl->string_value ); + free( impl ); + } + return ref; +} + +static HRESULT WINAPI json_value_GetIids( IJsonValue *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 json_value_GetRuntimeClassName( IJsonValue *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_GetTrustLevel( IJsonValue *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_get_ValueType( IJsonValue *iface, JsonValueType *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_Stringify( IJsonValue *iface, HSTRING *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_GetString( IJsonValue *iface, HSTRING *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_GetNumber( IJsonValue *iface, DOUBLE *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_GetBoolean( IJsonValue *iface, boolean *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_GetArray( IJsonValue *iface, IJsonArray **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI json_value_GetObject( IJsonValue *iface, IJsonObject **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct IJsonValueVtbl json_value_vtbl = +{ + json_value_QueryInterface, + json_value_AddRef, + json_value_Release, + /* IInspectable methods */ + json_value_GetIids, + json_value_GetRuntimeClassName, + json_value_GetTrustLevel, + /* IJsonValue methods */ + json_value_get_ValueType, + json_value_Stringify, + json_value_GetString, + json_value_GetNumber, + json_value_GetBoolean, + json_value_GetArray, + json_value_GetObject, +}; + DEFINE_IINSPECTABLE( json_value_statics, IJsonValueStatics, struct json_value_statics, IActivationFactory_iface )
static HRESULT WINAPI json_value_statics_Parse( IJsonValueStatics *iface, HSTRING input, IJsonValue **value ) @@ -143,8 +279,25 @@ static HRESULT WINAPI json_value_statics_CreateNumberValue( IJsonValueStatics *i
static HRESULT WINAPI json_value_statics_CreateStringValue( IJsonValueStatics *iface, HSTRING input, IJsonValue **value ) { - FIXME( "iface %p, input %s, value %p stub!\n", iface, debugstr_hstring( input ), value ); - return E_NOTIMPL; + struct json_value *impl; + HRESULT hr; + + TRACE( "iface %p, input %s, value %p\n", iface, debugstr_hstring( input ), value ); + + if (!value) return E_POINTER; + if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY; + + impl->IJsonValue_iface.lpVtbl = &json_value_vtbl; + impl->ref = 1; + if (FAILED(hr = WindowsDuplicateString( input, &impl->string_value ))) + { + free( impl ); + return hr; + } + + *value = &impl->IJsonValue_iface; + TRACE( "created IJsonValue %p.\n", *value ); + return S_OK; }
static const struct IJsonValueStaticsVtbl json_value_statics_vtbl = diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index 5bb81d44d13..649a1b066ed 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -120,20 +120,18 @@ static void test_JsonValueStatics(void) ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IJsonValueStatics_CreateStringValue( json_value_statics, NULL, (IJsonValue **)&json_value ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); if (hr == S_OK) IJsonValue_Release( json_value ); hr = WindowsCreateString( L"Wine", wcslen( L"Wine" ), &str ); ok( hr == S_OK, "got hr %#lx.\n", hr ); hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, NULL ); - todo_wine ok( hr == E_POINTER, "got hr %#lx.\n", hr ); hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, (IJsonValue **)&json_value ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); - if (hr == S_OK) IJsonValue_Release( json_value ); WindowsDeleteString( str );
+ ref = IJsonValue_Release( json_value ); + ok( ref == 0, "got ref %ld.\n", ref ); ref = IJsonValueStatics_Release( json_value_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146831
Your paranoid android.
=== build (build log) ===
Task: Patch failed to apply
=== debian11 (build log) ===
Task: Patch failed to apply
=== debian11b (build log) ===
Task: Patch failed to apply
On Fri Jul 5 04:37:23 2024 +0000, Rémi Bernon wrote:
hr = WindowsCreateString( json_object_name, wcslen( json_object_name ), &str ); ok( hr == S_OK, "got hr %#lx.\n", hr ); hr = RoActivateInstance( str, &inspectable );
I'd suggest to keep the `WindowsDeleteString( str );` above and duplicate the string creation. Makes the cleanup easier to track (because right now you're leaking the string if the class isn't present).
Good catch, updated.
This merge request was approved by Rémi Bernon.