From d9b955f1d36e9356fdf4d069ca2c48269ba3fd9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Tue, 13 Oct 2020 18:20:27 +0200 Subject: [PATCH] windows.globalization: Implement IGlobalizationPreferencesStatics::Languages semi-stub. Returning system default language in a 1-element HSTRING vector. --- .../windows.globalization_main.c | 177 +++++++++++++++++- 1 file changed, 175 insertions(+), 2 deletions(-) diff --git a/dlls/windows.globalization.dll/windows.globalization_main.c b/dlls/windows.globalization.dll/windows.globalization_main.c index 83e269bead6..0d7a1bd6dcf 100644 --- a/dlls/windows.globalization.dll/windows.globalization_main.c +++ b/dlls/windows.globalization.dll/windows.globalization_main.c @@ -29,6 +29,165 @@ 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[0]; +}; + +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 *This = impl_from_IVectorView_HSTRING(iface); + + FIXME("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out); + + if (!out) return E_INVALIDARG; + + *out = NULL; + if (!IsEqualIID(&IID_IUnknown, iid) && + !IsEqualIID(&IID_IInspectable, iid) && + !IsEqualIID(&IID_IVectorView_HSTRING, iid)) + { + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + *out = &This->IVectorView_HSTRING_iface; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE hstring_vector_AddRef( + IVectorView_HSTRING *iface) +{ + struct hstring_vector *This = impl_from_IVectorView_HSTRING(iface); + ULONG ref = InterlockedIncrement(&This->ref); + FIXME("iface %p -> ref %u.\n", iface, ref); + return ref; +} + +static ULONG STDMETHODCALLTYPE hstring_vector_Release( + IVectorView_HSTRING *iface) +{ + struct hstring_vector *This = impl_from_IVectorView_HSTRING(iface); + ULONG ref = InterlockedDecrement(&This->ref); + FIXME("iface %p -> ref %u.\n", iface, ref); + if (ref == 0) + { + while (This->count--) WindowsDeleteString(This->values[This->count]); + HeapFree(GetProcessHeap(), 0, This); + } + 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 *This = impl_from_IVectorView_HSTRING(iface); + + FIXME("iface %p, index %#x, value %p stub!\n", iface, index, value); + + if (index >= This->count) return E_BOUNDS; + return WindowsDuplicateString(This->values[index], value); +} + +static HRESULT STDMETHODCALLTYPE hstring_vector_get_Size( + IVectorView_HSTRING *iface, ULONG *value) +{ + struct hstring_vector *This = impl_from_IVectorView_HSTRING(iface); + + FIXME("iface %p, value %p stub!\n", iface, value); + + *value = This->count; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE hstring_vector_IndexOf( + IVectorView_HSTRING *iface, HSTRING element, ULONG *index, BOOLEAN *value) +{ + FIXME("iface %p, element %p, index %p, value %p stub!\n", iface, element, index, value); + *value = FALSE; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE hstring_vector_GetMany( + IVectorView_HSTRING *iface, ULONG start_index, HSTRING *items, UINT *count) +{ + struct hstring_vector *This = impl_from_IVectorView_HSTRING(iface); + HRESULT hr; + ULONG i; + + FIXME("iface %p, start_index %#x, items %p, count %p stub!\n", iface, start_index, items, count); + + for (i = start_index; i < This->count; ++i) + if (FAILED(hr = WindowsDuplicateString(This->values[i], items + i - start_index))) + return hr; + *count = This->count - start_index; + + return S_OK; +} + +static const struct IVectorView_HSTRINGVtbl hstring_vector_vtbl = +{ + hstring_vector_QueryInterface, + hstring_vector_AddRef, + hstring_vector_Release, + /* IInspectable methods */ + hstring_vector_GetIids, + hstring_vector_GetRuntimeClassName, + hstring_vector_GetTrustLevel, + /* IVectorView methods */ + hstring_vector_GetAt, + hstring_vector_get_Size, + hstring_vector_IndexOf, + hstring_vector_GetMany, +}; + +static HRESULT hstring_vector_create(HSTRING *values, SIZE_T count, IVectorView_HSTRING **out) +{ + struct hstring_vector *This; + + if (!(This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This) + count * sizeof(HSTRING)))) return E_OUTOFMEMORY; + This->ref = 1; + + This->IVectorView_HSTRING_iface.lpVtbl = &hstring_vector_vtbl; + This->count = count; + memcpy(This->values, values, count * sizeof(HSTRING)); + + *out = &This->IVectorView_HSTRING_iface; + return S_OK; +} + struct windows_globalization { IActivationFactory IActivationFactory_iface; @@ -126,8 +285,22 @@ static HRESULT STDMETHODCALLTYPE globalization_preferences_get_Currencies(IGloba static HRESULT STDMETHODCALLTYPE globalization_preferences_get_Languages(IGlobalizationPreferencesStatics *iface, IVectorView_HSTRING **value) { - FIXME("iface %p, value %p stub!\n", iface, value); - return E_NOTIMPL; + HSTRING hstring; + UINT32 length; + WCHAR locale_w[LOCALE_NAME_MAX_LENGTH], *tmp; + + FIXME("iface %p, value %p semi-stub!\n", iface, value); + + GetSystemDefaultLocaleName(locale_w, LOCALE_NAME_MAX_LENGTH); + + if ((tmp = wcsrchr(locale_w, '_'))) *tmp = 0; + if ((tmp = wcschr(locale_w, '-')) && (wcslen(tmp) <= 3 || (tmp = wcschr(tmp + 1, '-')))) *tmp = 0; + length = wcslen(locale_w); + + FIXME("returning language %s\n", debugstr_w(locale_w)); + + WindowsCreateString(locale_w, length, &hstring); + return hstring_vector_create(&hstring, 1, value); } static HRESULT STDMETHODCALLTYPE globalization_preferences_get_HomeGeographicRegion(IGlobalizationPreferencesStatics *iface, -- 2.20.1