[PATCH 1/4] windows.foundation.metadata: Add stub dll

Rémi Bernon rbernon at codeweavers.com
Mon Jan 31 04:04:44 CST 2022


Hi Fabian,

On 1/30/22 18:23, Fabian Maurer wrote:
> Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
> ---
>   configure                                     |   2 +
>   configure.ac                                  |   1 +
>   dlls/windows.foundation.metadata/Makefile.in  |   8 +
>   dlls/windows.foundation.metadata/classes.idl  |  23 +++
>   dlls/windows.foundation.metadata/main.c       | 157 ++++++++++++++++++
>   .../windows.foundation.metadata.spec          |   3 +
>   include/Makefile.in                           |   1 +
>   include/windows.foundation.metadata.idl       |  52 ++++++
>   8 files changed, 247 insertions(+)
>   create mode 100644 dlls/windows.foundation.metadata/Makefile.in
>   create mode 100644 dlls/windows.foundation.metadata/classes.idl
>   create mode 100644 dlls/windows.foundation.metadata/main.c
>   create mode 100644 dlls/windows.foundation.metadata/windows.foundation.metadata.spec
>   create mode 100644 include/windows.foundation.metadata.idl
> 
> diff --git a/configure b/configure
> index 425d267ec50..f7f8cb581ef 100755
> --- a/configure
> +++ b/configure
> @@ -1704,6 +1704,7 @@ enable_wiaservc
>   enable_wimgapi
>   enable_win32u
>   enable_windows_devices_enumeration
> +enable_windows_foundation_metadata
>   enable_windows_gaming_input
>   enable_windows_globalization
>   enable_windows_media_devices
> @@ -22470,6 +22471,7 @@ wine_fn_config_makefile dlls/win87em.dll16 enable_win16
>   wine_fn_config_makefile dlls/winaspi.dll16 enable_win16
>   wine_fn_config_makefile dlls/windebug.dll16 enable_win16
>   wine_fn_config_makefile dlls/windows.devices.enumeration enable_windows_devices_enumeration
> +wine_fn_config_makefile dlls/windows.foundation.metadata enable_windows_foundation_metadata
>   wine_fn_config_makefile dlls/windows.gaming.input enable_windows_gaming_input
>   wine_fn_config_makefile dlls/windows.gaming.input/tests enable_tests
>   wine_fn_config_makefile dlls/windows.globalization enable_windows_globalization

You don't need to include configure changes in your patches, they will 
be regenerated and added when patch is commited.

> diff --git a/configure.ac b/configure.ac
> index fed12f61036..c66c6fd462f 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -3366,6 +3366,7 @@ WINE_CONFIG_MAKEFILE(dlls/win87em.dll16,enable_win16)
>   WINE_CONFIG_MAKEFILE(dlls/winaspi.dll16,enable_win16)
>   WINE_CONFIG_MAKEFILE(dlls/windebug.dll16,enable_win16)
>   WINE_CONFIG_MAKEFILE(dlls/windows.devices.enumeration)
> +WINE_CONFIG_MAKEFILE(dlls/windows.foundation.metadata)
>   WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input)
>   WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input/tests)
>   WINE_CONFIG_MAKEFILE(dlls/windows.globalization)
> diff --git a/dlls/windows.foundation.metadata/Makefile.in b/dlls/windows.foundation.metadata/Makefile.in
> new file mode 100644
> index 00000000000..311cfb0a845
> --- /dev/null
> +++ b/dlls/windows.foundation.metadata/Makefile.in
> @@ -0,0 +1,8 @@
> +EXTRADEFS = -DWINE_NO_LONG_TYPES
> +MODULE = windows.foundation.metadata.dll
> +IMPORTS = combase uuid
> +
> +C_SRCS = \
> +	main.c
> +
> +IDL_SRCS = classes.idl
> diff --git a/dlls/windows.foundation.metadata/classes.idl b/dlls/windows.foundation.metadata/classes.idl
> new file mode 100644
> index 00000000000..405fa9f1133
> --- /dev/null
> +++ b/dlls/windows.foundation.metadata/classes.idl
> @@ -0,0 +1,23 @@
> +/*
> + * Runtime Classes for windows.foundation.metadata.dll
> + *
> + * Copyright 2022 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
> + */
> +
> +#pragma makedep register
> +
> +#include "windows.foundation.metadata.idl"
> diff --git a/dlls/windows.foundation.metadata/main.c b/dlls/windows.foundation.metadata/main.c
> new file mode 100644
> index 00000000000..18a19ad1bca
> --- /dev/null
> +++ b/dlls/windows.foundation.metadata/main.c
> @@ -0,0 +1,157 @@
> +/* WinRT Windows.Foundation.Metadata implementation
> + *
> + * Copyright 2022 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
> + */
> +
> +#include <stdarg.h>
> +
> +#define COBJMACROS
> +#include "windef.h"
> +#include "winbase.h"
> +#include "winstring.h"
> +#include "wine/debug.h"
> +#include "objbase.h"
> +
> +#include "initguid.h"
> +#include "activation.h"
> +
> +#define WIDL_using_Windows_Foundation
> +#define WIDL_using_Windows_Foundation_Collections
> +#include "windows.foundation.h"
> +#define WIDL_using_Windows_Foundation_Metadata
> +#include "windows.foundation.metadata.h"
> +
> +WINE_DEFAULT_DEBUG_CHANNEL(metadata);
> +
> +static const char *debugstr_hstring(HSTRING hstr)
> +{
> +    const WCHAR *str;
> +    UINT32 len;
> +    if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)";
> +    str = WindowsGetStringRawBuffer(hstr, &len);
> +    return wine_dbgstr_wn(str, len);
> +}
> +
> +struct windows_foundation_metadata
> +{
> +    IActivationFactory IActivationFactory_iface;
> +    LONG ref;
> +};
> +
> +static inline struct windows_foundation_metadata *impl_from_IActivationFactory(IActivationFactory *iface)
> +{
> +    return CONTAINING_RECORD(iface, struct windows_foundation_metadata, IActivationFactory_iface);
> +}
> +
> +static HRESULT STDMETHODCALLTYPE windows_foundation_metadata_QueryInterface(
> +        IActivationFactory *iface, REFIID iid, void **out)
> +{
> +    TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out);
> +
> +    if (IsEqualGUID(iid, &IID_IUnknown) ||
> +        IsEqualGUID(iid, &IID_IInspectable) ||
> +        IsEqualGUID(iid, &IID_IAgileObject) ||
> +        IsEqualGUID(iid, &IID_IActivationFactory))
> +    {
> +        IUnknown_AddRef(iface);
> +        *out = iface;
> +        return S_OK;
> +    }
> +
> +    FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
> +    *out = NULL;
> +    return E_NOINTERFACE;
> +}
> +
> +static ULONG STDMETHODCALLTYPE windows_foundation_metadata_AddRef(
> +        IActivationFactory *iface)
> +{
> +    struct windows_foundation_metadata *impl = impl_from_IActivationFactory(iface);
> +    ULONG ref = InterlockedIncrement(&impl->ref);
> +    TRACE("iface %p, ref %u.\n", iface, ref);
> +    return ref;
> +}
> +
> +static ULONG STDMETHODCALLTYPE windows_foundation_metadata_Release(
> +        IActivationFactory *iface)
> +{
> +    struct windows_foundation_metadata *impl = impl_from_IActivationFactory(iface);
> +    ULONG ref = InterlockedDecrement(&impl->ref);
> +    TRACE("iface %p, ref %u.\n", iface, ref);
> +    return ref;
> +}
> +
> +static HRESULT STDMETHODCALLTYPE windows_foundation_metadata_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 STDMETHODCALLTYPE windows_foundation_metadata_GetRuntimeClassName(
> +        IActivationFactory *iface, HSTRING *class_name)
> +{
> +    FIXME("iface %p, class_name %p stub!\n", iface, class_name);
> +    return E_NOTIMPL;
> +}
> +
> +static HRESULT STDMETHODCALLTYPE windows_foundation_metadata_GetTrustLevel(
> +        IActivationFactory *iface, TrustLevel *trust_level)
> +{
> +    FIXME("iface %p, trust_level %p stub!\n", iface, trust_level);
> +    return E_NOTIMPL;
> +}
> +
> +static HRESULT STDMETHODCALLTYPE windows_foundation_metadata_ActivateInstance(
> +        IActivationFactory *iface, IInspectable **instance)
> +{
> +    FIXME("iface %p, instance %p stub!\n", iface, instance);
> +    return E_NOTIMPL;
> +}
> +
> +static const struct IActivationFactoryVtbl activation_factory_vtbl =
> +{
> +    windows_foundation_metadata_QueryInterface,
> +    windows_foundation_metadata_AddRef,
> +    windows_foundation_metadata_Release,
> +    /* IInspectable methods */
> +    windows_foundation_metadata_GetIids,
> +    windows_foundation_metadata_GetRuntimeClassName,
> +    windows_foundation_metadata_GetTrustLevel,
> +    /* IActivationFactory methods */
> +    windows_foundation_metadata_ActivateInstance,
> +};
> +
> +static struct windows_foundation_metadata windows_foundation_metadata =
> +{
> +    {&activation_factory_vtbl},
> +    1
> +};
> +
> +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)
> +{
> +    TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory);
> +    *factory = &windows_foundation_metadata.IActivationFactory_iface;
> +    IUnknown_AddRef(*factory);
> +    return S_OK;
> +}

As far as I understand from Bernhard Kölbl work on windows.media.speech, 
each runtimeclass probably has its own activation factory (although it's 
just my assumption and it would need to be confirmed with tests).

Although for a stub with only one runtimeclass it probably doesn't 
matter much, maybe you can already have the factory here named and 
organised accordingly? Like for instance it would be named 
api_information_factory, and the file api_information.c maybe.

I know it's not done in existing Wine WinRT libs, but probably it will 
have to be changed in the future.

> diff --git a/dlls/windows.foundation.metadata/windows.foundation.metadata.spec b/dlls/windows.foundation.metadata/windows.foundation.metadata.spec
> new file mode 100644
> index 00000000000..20a8bfa98ea
> --- /dev/null
> +++ b/dlls/windows.foundation.metadata/windows.foundation.metadata.spec
> @@ -0,0 +1,3 @@
> +@ stdcall -private DllCanUnloadNow()
> +@ stdcall -private DllGetActivationFactory(ptr ptr)
> +@ stdcall -private DllGetClassObject(ptr ptr ptr)
> diff --git a/include/Makefile.in b/include/Makefile.in
> index 7fcf5f0ba7b..24c2b3fb448 100644
> --- a/include/Makefile.in
> +++ b/include/Makefile.in
> @@ -777,6 +777,7 @@ SOURCES = \
>   	windows.devices.enumeration.idl \
>   	windows.foundation.collections.idl \
>   	windows.foundation.idl \
> +	windows.foundation.metadata.idl \
>   	windows.gaming.input.forcefeedback.idl \
>   	windows.gaming.input.idl \
>   	windows.globalization.idl \
> diff --git a/include/windows.foundation.metadata.idl b/include/windows.foundation.metadata.idl
> new file mode 100644
> index 00000000000..7673777e658
> --- /dev/null
> +++ b/include/windows.foundation.metadata.idl
> @@ -0,0 +1,52 @@
> +/*
> + * Copyright 2022 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
> + */
> +
> +#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 {
> +    namespace Foundation {
> +        namespace Metadata {
> +            interface IApiInformationStatics;
> +            runtimeclass ApiInformation;
> +        }
> +    }
> +}
> +
> +namespace Windows {
> +    namespace Foundation {
> +        namespace Metadata {
> +            [
> +                contract(Windows.Foundation.UniversalApiContract, 1.0),
> +                marshaling_behavior(agile),
> +                static(Windows.Foundation.Metadata.IApiInformationStatics, Windows.Foundation.UniversalApiContract, 1.0),
> +                threading(both)
> +            ]
> +            runtimeclass ApiInformation
> +            {
> +            }
> +        }
> +    }
> +}
> --

I think include changes are nice to add in a separate, earlier, patch. 
Same for the IApiInformationStatics definition.

It would also be nice to already have a few tests to check the factory 
creation, its interfaces and the few functions you are stubbing too, a 
bit like it's already done in windows.gaming.input or other WinRT stubs.

Cheers,
-- 
Rémi Bernon <rbernon at codeweavers.com>



More information about the wine-devel mailing list