1 /* WinRT Windows.Globalization implementation
3 * Copyright 2021 RĂ©mi Bernon for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "winstring.h"
26 #include "wine/debug.h"
30 #include "activation.h"
32 #define WIDL_using_Windows_Foundation
33 #define WIDL_using_Windows_Foundation_Collections
34 #include "windows.foundation.h"
35 #define WIDL_using_Windows_Globalization
36 #include "windows.globalization.h"
37 #define WIDL_using_Windows_System_UserProfile
38 #include "windows.system.userprofile.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(locale
);
42 static const char *debugstr_hstring(HSTRING hstr
)
46 if (hstr
&& !((ULONG_PTR
)hstr
>> 16)) return "(invalid)";
47 str
= WindowsGetStringRawBuffer(hstr
, &len
);
48 return wine_dbgstr_wn(str
, len
);
53 IVectorView_HSTRING IVectorView_HSTRING_iface
;
60 static inline struct hstring_vector
*impl_from_IVectorView_HSTRING(IVectorView_HSTRING
*iface
)
62 return CONTAINING_RECORD(iface
, struct hstring_vector
, IVectorView_HSTRING_iface
);
65 static HRESULT STDMETHODCALLTYPE
hstring_vector_QueryInterface(IVectorView_HSTRING
*iface
,
66 REFIID iid
, void **out
)
68 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
69 TRACE("iface %p, iid %s, out %p stub!\n", iface
, debugstr_guid(iid
), out
);
71 if (IsEqualGUID(iid
, &IID_IUnknown
) ||
72 IsEqualGUID(iid
, &IID_IInspectable
) ||
73 IsEqualGUID(iid
, &IID_IAgileObject
) ||
74 IsEqualGUID(iid
, &IID_IVectorView_HSTRING
))
76 IUnknown_AddRef(iface
);
77 *out
= &impl
->IVectorView_HSTRING_iface
;
81 FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
86 static ULONG STDMETHODCALLTYPE
hstring_vector_AddRef(IVectorView_HSTRING
*iface
)
88 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
89 ULONG ref
= InterlockedIncrement(&impl
->ref
);
90 TRACE("iface %p, ref %u.\n", iface
, ref
);
94 static ULONG STDMETHODCALLTYPE
hstring_vector_Release(IVectorView_HSTRING
*iface
)
96 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
97 ULONG ref
= InterlockedDecrement(&impl
->ref
);
98 TRACE("iface %p, ref %u.\n", iface
, ref
);
101 while (impl
->count
--) WindowsDeleteString(impl
->values
[impl
->count
]);
107 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetIids(IVectorView_HSTRING
*iface
,
108 ULONG
*iid_count
, IID
**iids
)
110 FIXME("iface %p, iid_count %p, iids %p stub!\n", iface
, iid_count
, iids
);
114 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetRuntimeClassName(IVectorView_HSTRING
*iface
,
117 FIXME("iface %p, class_name %p stub!\n", iface
, class_name
);
121 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetTrustLevel(IVectorView_HSTRING
*iface
,
122 TrustLevel
*trust_level
)
124 FIXME("iface %p, trust_level %p stub!\n", iface
, trust_level
);
128 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetAt(IVectorView_HSTRING
*iface
,
129 ULONG index
, HSTRING
*value
)
131 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
133 TRACE("iface %p, index %#x, value %p.\n", iface
, index
, value
);
136 if (index
>= impl
->count
) return E_BOUNDS
;
137 return WindowsDuplicateString(impl
->values
[index
], value
);
140 static HRESULT STDMETHODCALLTYPE
hstring_vector_get_Size(IVectorView_HSTRING
*iface
,
143 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
145 TRACE("iface %p, value %p.\n", iface
, value
);
147 *value
= impl
->count
;
151 static HRESULT STDMETHODCALLTYPE
hstring_vector_IndexOf(IVectorView_HSTRING
*iface
,
152 HSTRING element
, ULONG
*index
, BOOLEAN
*found
)
154 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
157 TRACE("iface %p, element %p, index %p, found %p.\n", iface
, element
, index
, found
);
159 for (i
= 0; i
< impl
->count
; ++i
)
160 if (SUCCEEDED(WindowsCompareStringOrdinal(impl
->values
[i
], element
, &order
)) && order
== 0)
177 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetMany(IVectorView_HSTRING
*iface
,
178 ULONG start_index
, ULONG items_size
, HSTRING
*items
, UINT
*count
)
180 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
184 TRACE("iface %p, start_index %#x, items %p, count %p.\n", iface
, start_index
, items
, count
);
186 memset(items
, 0, items_size
* sizeof(HSTRING
*));
188 for (i
= start_index
; i
< impl
->count
&& i
< start_index
+ items_size
; ++i
)
189 if (FAILED(hr
= WindowsDuplicateString(impl
->values
[i
], items
+ i
- start_index
)))
192 if (FAILED(hr
)) while (i
-- > start_index
) WindowsDeleteString(items
[i
- start_index
]);
193 *count
= i
- start_index
;
197 static const struct IVectorView_HSTRINGVtbl hstring_vector_vtbl
=
199 hstring_vector_QueryInterface
,
200 hstring_vector_AddRef
,
201 hstring_vector_Release
,
202 /* IInspectable methods */
203 hstring_vector_GetIids
,
204 hstring_vector_GetRuntimeClassName
,
205 hstring_vector_GetTrustLevel
,
206 /* IVectorView<HSTRING> methods */
207 hstring_vector_GetAt
,
208 hstring_vector_get_Size
,
209 hstring_vector_IndexOf
,
210 hstring_vector_GetMany
,
213 static HRESULT
hstring_vector_create(HSTRING
*values
, SIZE_T count
, IVectorView_HSTRING
**out
)
215 struct hstring_vector
*impl
;
217 if (!(impl
= malloc(offsetof(struct hstring_vector
, values
[count
])))) return E_OUTOFMEMORY
;
220 impl
->IVectorView_HSTRING_iface
.lpVtbl
= &hstring_vector_vtbl
;
222 memcpy(impl
->values
, values
, count
* sizeof(HSTRING
));
224 *out
= &impl
->IVectorView_HSTRING_iface
;
228 struct windows_globalization
230 IActivationFactory IActivationFactory_iface
;
231 IGlobalizationPreferencesStatics IGlobalizationPreferencesStatics_iface
;
235 static inline struct windows_globalization
*impl_from_IActivationFactory(IActivationFactory
*iface
)
237 return CONTAINING_RECORD(iface
, struct windows_globalization
, IActivationFactory_iface
);
240 static inline struct windows_globalization
*impl_from_IGlobalizationPreferencesStatics(IGlobalizationPreferencesStatics
*iface
)
242 return CONTAINING_RECORD(iface
, struct windows_globalization
, IGlobalizationPreferencesStatics_iface
);
245 static HRESULT STDMETHODCALLTYPE
windows_globalization_QueryInterface(
246 IActivationFactory
*iface
, REFIID iid
, void **out
)
248 struct windows_globalization
*impl
= impl_from_IActivationFactory(iface
);
249 TRACE("iface %p, iid %s, out %p stub!\n", iface
, debugstr_guid(iid
), out
);
251 if (IsEqualGUID(iid
, &IID_IUnknown
) ||
252 IsEqualGUID(iid
, &IID_IInspectable
) ||
253 IsEqualGUID(iid
, &IID_IAgileObject
) ||
254 IsEqualGUID(iid
, &IID_IActivationFactory
))
256 IUnknown_AddRef(iface
);
257 *out
= &impl
->IActivationFactory_iface
;
261 if (IsEqualGUID(iid
, &IID_IGlobalizationPreferencesStatics
))
263 IUnknown_AddRef(iface
);
264 *out
= &impl
->IGlobalizationPreferencesStatics_iface
;
268 FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
270 return E_NOINTERFACE
;
273 static ULONG STDMETHODCALLTYPE
windows_globalization_AddRef(
274 IActivationFactory
*iface
)
276 struct windows_globalization
*impl
= impl_from_IActivationFactory(iface
);
277 ULONG ref
= InterlockedIncrement(&impl
->ref
);
278 TRACE("iface %p, ref %u.\n", iface
, ref
);
282 static ULONG STDMETHODCALLTYPE
windows_globalization_Release(
283 IActivationFactory
*iface
)
285 struct windows_globalization
*impl
= impl_from_IActivationFactory(iface
);
286 ULONG ref
= InterlockedDecrement(&impl
->ref
);
287 TRACE("iface %p, ref %u.\n", iface
, ref
);
291 static HRESULT STDMETHODCALLTYPE
windows_globalization_GetIids(
292 IActivationFactory
*iface
, ULONG
*iid_count
, IID
**iids
)
294 FIXME("iface %p, iid_count %p, iids %p stub!\n", iface
, iid_count
, iids
);
298 static HRESULT STDMETHODCALLTYPE
windows_globalization_GetRuntimeClassName(
299 IActivationFactory
*iface
, HSTRING
*class_name
)
301 FIXME("iface %p, class_name %p stub!\n", iface
, class_name
);
305 static HRESULT STDMETHODCALLTYPE
windows_globalization_GetTrustLevel(
306 IActivationFactory
*iface
, TrustLevel
*trust_level
)
308 FIXME("iface %p, trust_level %p stub!\n", iface
, trust_level
);
312 static HRESULT STDMETHODCALLTYPE
windows_globalization_ActivateInstance(
313 IActivationFactory
*iface
, IInspectable
**instance
)
315 FIXME("iface %p, instance %p stub!\n", iface
, instance
);
319 static const struct IActivationFactoryVtbl activation_factory_vtbl
=
321 windows_globalization_QueryInterface
,
322 windows_globalization_AddRef
,
323 windows_globalization_Release
,
324 /* IInspectable methods */
325 windows_globalization_GetIids
,
326 windows_globalization_GetRuntimeClassName
,
327 windows_globalization_GetTrustLevel
,
328 /* IActivationFactory methods */
329 windows_globalization_ActivateInstance
,
332 static HRESULT STDMETHODCALLTYPE
globalization_preferences_QueryInterface(
333 IGlobalizationPreferencesStatics
*iface
, REFIID iid
, void **object
)
335 struct windows_globalization
*impl
= impl_from_IGlobalizationPreferencesStatics(iface
);
336 return windows_globalization_QueryInterface(&impl
->IActivationFactory_iface
, iid
, object
);
339 static ULONG STDMETHODCALLTYPE
globalization_preferences_AddRef(
340 IGlobalizationPreferencesStatics
*iface
)
342 struct windows_globalization
*impl
= impl_from_IGlobalizationPreferencesStatics(iface
);
343 return windows_globalization_AddRef(&impl
->IActivationFactory_iface
);
346 static ULONG STDMETHODCALLTYPE
globalization_preferences_Release(
347 IGlobalizationPreferencesStatics
*iface
)
349 struct windows_globalization
*impl
= impl_from_IGlobalizationPreferencesStatics(iface
);
350 return windows_globalization_Release(&impl
->IActivationFactory_iface
);
353 static HRESULT STDMETHODCALLTYPE
globalization_preferences_GetIids(
354 IGlobalizationPreferencesStatics
*iface
, ULONG
*iid_count
, IID
**iids
)
356 FIXME("iface %p, iid_count %p, iids %p stub!\n", iface
, iid_count
, iids
);
360 static HRESULT STDMETHODCALLTYPE
globalization_preferences_GetRuntimeClassName(
361 IGlobalizationPreferencesStatics
*iface
, HSTRING
*class_name
)
363 FIXME("iface %p, class_name %p stub!\n", iface
, class_name
);
367 static HRESULT STDMETHODCALLTYPE
globalization_preferences_GetTrustLevel(
368 IGlobalizationPreferencesStatics
*iface
, TrustLevel
*trust_level
)
370 FIXME("iface %p, trust_level %p stub!\n", iface
, trust_level
);
374 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_Calendars(
375 IGlobalizationPreferencesStatics
*iface
, IVectorView_HSTRING
**out
)
377 FIXME("iface %p, out %p stub!\n", iface
, out
);
378 return hstring_vector_create(NULL
, 0, out
);
381 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_Clocks(
382 IGlobalizationPreferencesStatics
*iface
, IVectorView_HSTRING
**out
)
384 FIXME("iface %p, out %p stub!\n", iface
, out
);
385 return hstring_vector_create(NULL
, 0, out
);
388 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_Currencies(
389 IGlobalizationPreferencesStatics
*iface
, IVectorView_HSTRING
**out
)
391 FIXME("iface %p, out %p stub!\n", iface
, out
);
392 return hstring_vector_create(NULL
, 0, out
);
395 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_Languages(
396 IGlobalizationPreferencesStatics
*iface
, IVectorView_HSTRING
**out
)
400 WCHAR locale
[LOCALE_NAME_MAX_LENGTH
];
402 TRACE("iface %p, out %p.\n", iface
, out
);
404 if (!GetUserDefaultLocaleName(locale
, LOCALE_NAME_MAX_LENGTH
))
407 TRACE("returning language %s\n", debugstr_w(locale
));
409 if (FAILED(hr
= WindowsCreateString(locale
, wcslen(locale
), &hstring
)))
412 return hstring_vector_create(&hstring
, 1, out
);
415 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_HomeGeographicRegion(
416 IGlobalizationPreferencesStatics
*iface
, HSTRING
* out
)
420 TRACE("iface %p, out %p.\n", iface
, out
);
422 if (!GetUserDefaultGeoName(country
, 16))
425 TRACE("returning country %s\n", debugstr_w(country
));
427 return WindowsCreateString(country
, wcslen(country
), out
);
430 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_WeekStartsOn(
431 IGlobalizationPreferencesStatics
*iface
, enum DayOfWeek
* out
)
433 FIXME("iface %p, out %p stub!\n", iface
, out
);
437 static const struct IGlobalizationPreferencesStaticsVtbl globalization_preferences_vtbl
=
439 globalization_preferences_QueryInterface
,
440 globalization_preferences_AddRef
,
441 globalization_preferences_Release
,
442 /* IInspectable methods */
443 globalization_preferences_GetIids
,
444 globalization_preferences_GetRuntimeClassName
,
445 globalization_preferences_GetTrustLevel
,
446 /* IGlobalizationPreferencesStatics methods */
447 globalization_preferences_get_Calendars
,
448 globalization_preferences_get_Clocks
,
449 globalization_preferences_get_Currencies
,
450 globalization_preferences_get_Languages
,
451 globalization_preferences_get_HomeGeographicRegion
,
452 globalization_preferences_get_WeekStartsOn
,
455 static struct windows_globalization windows_globalization
=
457 {&activation_factory_vtbl
},
458 {&globalization_preferences_vtbl
},
462 HRESULT WINAPI
DllCanUnloadNow(void)
467 HRESULT WINAPI
DllGetClassObject(REFCLSID clsid
, REFIID riid
, void **out
)
469 FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid
), debugstr_guid(riid
), out
);
470 return CLASS_E_CLASSNOTAVAILABLE
;
473 HRESULT WINAPI
DllGetActivationFactory(HSTRING classid
, IActivationFactory
**factory
)
475 TRACE("classid %s, factory %p.\n", debugstr_hstring(classid
), factory
);
476 *factory
= &windows_globalization
.IActivationFactory_iface
;
477 IUnknown_AddRef(*factory
);