[PATCH v3 2/3] windows.globalization: Implement IGlobalizationPreferencesStatics::Languages.

Rémi Bernon rbernon at codeweavers.com
Fri Mar 26 04:20:08 CDT 2021


On 3/26/21 10:18 AM, Rémi Bernon wrote:
> Returning user default language in a 1-element HSTRING vector.
> 
> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
> ---
>   dlls/windows.globalization/main.c             | 194 +++++++++++++++++-
>   .../tests/globalization.c                     |  33 ++-
>   2 files changed, 222 insertions(+), 5 deletions(-)
> 
> diff --git a/dlls/windows.globalization/main.c b/dlls/windows.globalization/main.c
> index 84813152047..0b60add92f4 100644
> --- a/dlls/windows.globalization/main.c
> +++ b/dlls/windows.globalization/main.c
> @@ -48,6 +48,183 @@ static const char *debugstr_hstring(HSTRING hstr)
>       return wine_dbgstr_wn(str, len);
>   }
>   
> +struct hstring_vector
> +{
> +    IVectorView_HSTRING IVectorView_HSTRING_iface;
> +    LONG ref;
> +
> +    ULONG count;
> +    HSTRING values[1];
> +};
> +
> +static inline struct hstring_vector *impl_from_IVectorView_HSTRING(IVectorView_HSTRING *iface)
> +{
> +    return CONTAINING_RECORD(iface, struct hstring_vector, IVectorView_HSTRING_iface);
> +}
> +
> +static HRESULT STDMETHODCALLTYPE hstring_vector_QueryInterface(IVectorView_HSTRING *iface,
> +        REFIID iid, void **out)
> +{
> +    struct hstring_vector *impl = impl_from_IVectorView_HSTRING(iface);
> +    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_IVectorView_HSTRING))
> +    {
> +        IUnknown_AddRef(iface);
> +        *out = &impl->IVectorView_HSTRING_iface;
> +        return S_OK;
> +    }
> +
> +    FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
> +    *out = NULL;
> +    return E_NOINTERFACE;
> +}
> +
> +static ULONG STDMETHODCALLTYPE hstring_vector_AddRef(IVectorView_HSTRING *iface)
> +{
> +    struct hstring_vector *impl = impl_from_IVectorView_HSTRING(iface);
> +    ULONG ref = InterlockedIncrement(&impl->ref);
> +    TRACE("iface %p, ref %u.\n", iface, ref);
> +    return ref;
> +}
> +
> +static ULONG STDMETHODCALLTYPE hstring_vector_Release(IVectorView_HSTRING *iface)
> +{
> +    struct hstring_vector *impl = impl_from_IVectorView_HSTRING(iface);
> +    ULONG ref = InterlockedDecrement(&impl->ref);
> +    TRACE("iface %p, ref %u.\n", iface, ref);
> +    if (ref == 0)
> +    {
> +        while (impl->count--) WindowsDeleteString(impl->values[impl->count]);
> +        free(impl);
> +    }
> +    return ref;
> +}
> +
> +static HRESULT STDMETHODCALLTYPE hstring_vector_GetIids(IVectorView_HSTRING *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 hstring_vector_GetRuntimeClassName(IVectorView_HSTRING *iface,
> +        HSTRING *class_name)
> +{
> +    FIXME("iface %p, class_name %p stub!\n", iface, class_name);
> +    return E_NOTIMPL;
> +}
> +
> +static HRESULT STDMETHODCALLTYPE hstring_vector_GetTrustLevel(IVectorView_HSTRING *iface,
> +        TrustLevel *trust_level)
> +{
> +    FIXME("iface %p, trust_level %p stub!\n", iface, trust_level);
> +    return E_NOTIMPL;
> +}
> +
> +static HRESULT STDMETHODCALLTYPE hstring_vector_GetAt(IVectorView_HSTRING *iface,
> +        ULONG index, HSTRING *value)
> +{
> +    struct hstring_vector *impl = impl_from_IVectorView_HSTRING(iface);
> +
> +    TRACE("iface %p, index %#x, value %p.\n", iface, index, value);
> +
> +    *value = NULL;
> +    if (index >= impl->count) return E_BOUNDS;
> +    return WindowsDuplicateString(impl->values[index], value);
> +}
> +
> +static HRESULT STDMETHODCALLTYPE hstring_vector_get_Size(IVectorView_HSTRING *iface,
> +        ULONG *value)
> +{
> +    struct hstring_vector *impl = impl_from_IVectorView_HSTRING(iface);
> +
> +    TRACE("iface %p, value %p.\n", iface, value);
> +
> +    *value = impl->count;
> +    return S_OK;
> +}
> +
> +static HRESULT STDMETHODCALLTYPE hstring_vector_IndexOf(IVectorView_HSTRING *iface,
> +        HSTRING element, ULONG *index, BOOLEAN *found)
> +{
> +    struct hstring_vector *impl = impl_from_IVectorView_HSTRING(iface);
> +    INT32 i, order;
> +
> +    TRACE("iface %p, element %p, index %p, found %p.\n", iface, element, index, found);
> +
> +    for (i = 0; i < impl->count; ++i)
> +        if (SUCCEEDED(WindowsCompareStringOrdinal(impl->values[i], element, &order)) && order == 0)
> +            break;
> +
> +    if (i < impl->count)
> +    {
> +        *found = TRUE;
> +        *index = i;
> +    }
> +    else
> +    {
> +        *found = FALSE;
> +        *index = 0;
> +    }
> +
> +    return S_OK;
> +}
> +
> +static HRESULT STDMETHODCALLTYPE hstring_vector_GetMany(IVectorView_HSTRING *iface,
> +        ULONG start_index, ULONG items_size, HSTRING *items, UINT *count)
> +{
> +    struct hstring_vector *impl = impl_from_IVectorView_HSTRING(iface);
> +    HRESULT hr = S_OK;
> +    ULONG i;
> +
> +    TRACE("iface %p, start_index %#x, items %p, count %p.\n", iface, start_index, items, count);
> +
> +    memset(items, 0, items_size * sizeof(HSTRING *));
> +
> +    for (i = start_index; i < impl->count && i < start_index + items_size; ++i)
> +        if (FAILED(hr = WindowsDuplicateString(impl->values[i], items + i - start_index)))
> +            break;
> +
> +    if (FAILED(hr)) while (i-- > start_index) WindowsDeleteString(impl->values[i]);

Sorry I'm stupid, please ignore this it should be deleting items here.
-- 
Rémi Bernon <rbernon at codeweavers.com>



More information about the wine-devel mailing list