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 C_ASSERT(sizeof(struct hstring_vector
) == offsetof(struct hstring_vector
, values
[0]));
62 static inline struct hstring_vector
*impl_from_IVectorView_HSTRING(IVectorView_HSTRING
*iface
)
64 return CONTAINING_RECORD(iface
, struct hstring_vector
, IVectorView_HSTRING_iface
);
67 static HRESULT STDMETHODCALLTYPE
hstring_vector_QueryInterface(IVectorView_HSTRING
*iface
,
68 REFIID iid
, void **out
)
70 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
71 TRACE("iface %p, iid %s, out %p stub!\n", iface
, debugstr_guid(iid
), out
);
73 if (IsEqualGUID(iid
, &IID_IUnknown
) ||
74 IsEqualGUID(iid
, &IID_IInspectable
) ||
75 IsEqualGUID(iid
, &IID_IAgileObject
) ||
76 IsEqualGUID(iid
, &IID_IVectorView_HSTRING
))
78 IUnknown_AddRef(iface
);
79 *out
= &impl
->IVectorView_HSTRING_iface
;
83 FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
88 static ULONG STDMETHODCALLTYPE
hstring_vector_AddRef(IVectorView_HSTRING
*iface
)
90 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
91 ULONG ref
= InterlockedIncrement(&impl
->ref
);
92 TRACE("iface %p, ref %lu.\n", iface
, ref
);
96 static ULONG STDMETHODCALLTYPE
hstring_vector_Release(IVectorView_HSTRING
*iface
)
98 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
99 ULONG ref
= InterlockedDecrement(&impl
->ref
);
100 TRACE("iface %p, ref %lu.\n", iface
, ref
);
103 while (impl
->count
--) WindowsDeleteString(impl
->values
[impl
->count
]);
109 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetIids(IVectorView_HSTRING
*iface
,
110 ULONG
*iid_count
, IID
**iids
)
112 FIXME("iface %p, iid_count %p, iids %p stub!\n", iface
, iid_count
, iids
);
116 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetRuntimeClassName(IVectorView_HSTRING
*iface
,
119 FIXME("iface %p, class_name %p stub!\n", iface
, class_name
);
123 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetTrustLevel(IVectorView_HSTRING
*iface
,
124 TrustLevel
*trust_level
)
126 FIXME("iface %p, trust_level %p stub!\n", iface
, trust_level
);
130 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetAt(IVectorView_HSTRING
*iface
,
131 UINT32 index
, HSTRING
*value
)
133 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
135 TRACE("iface %p, index %#x, value %p.\n", iface
, index
, value
);
138 if (index
>= impl
->count
) return E_BOUNDS
;
139 return WindowsDuplicateString(impl
->values
[index
], value
);
142 static HRESULT STDMETHODCALLTYPE
hstring_vector_get_Size(IVectorView_HSTRING
*iface
,
145 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
147 TRACE("iface %p, value %p.\n", iface
, value
);
149 *value
= impl
->count
;
153 static HRESULT STDMETHODCALLTYPE
hstring_vector_IndexOf(IVectorView_HSTRING
*iface
,
154 HSTRING element
, UINT32
*index
, BOOLEAN
*found
)
156 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
159 TRACE("iface %p, element %p, index %p, found %p.\n", iface
, element
, index
, found
);
161 for (i
= 0; i
< impl
->count
; ++i
)
162 if (SUCCEEDED(WindowsCompareStringOrdinal(impl
->values
[i
], element
, &order
)) && order
== 0)
179 static HRESULT STDMETHODCALLTYPE
hstring_vector_GetMany(IVectorView_HSTRING
*iface
,
180 UINT32 start_index
, UINT32 items_size
, HSTRING
*items
, UINT
*count
)
182 struct hstring_vector
*impl
= impl_from_IVectorView_HSTRING(iface
);
186 TRACE("iface %p, start_index %#x, items %p, count %p.\n", iface
, start_index
, items
, count
);
188 memset(items
, 0, items_size
* sizeof(*items
));
190 for (i
= start_index
; i
< impl
->count
&& i
< start_index
+ items_size
; ++i
)
191 if (FAILED(hr
= WindowsDuplicateString(impl
->values
[i
], items
+ i
- start_index
)))
194 if (FAILED(hr
)) while (i
-- > start_index
) WindowsDeleteString(items
[i
- start_index
]);
195 *count
= i
- start_index
;
199 static const struct IVectorView_HSTRINGVtbl hstring_vector_vtbl
=
201 hstring_vector_QueryInterface
,
202 hstring_vector_AddRef
,
203 hstring_vector_Release
,
204 /* IInspectable methods */
205 hstring_vector_GetIids
,
206 hstring_vector_GetRuntimeClassName
,
207 hstring_vector_GetTrustLevel
,
208 /* IVectorView<HSTRING> methods */
209 hstring_vector_GetAt
,
210 hstring_vector_get_Size
,
211 hstring_vector_IndexOf
,
212 hstring_vector_GetMany
,
215 static HRESULT
hstring_vector_create(HSTRING
*values
, SIZE_T count
, IVectorView_HSTRING
**out
)
217 struct hstring_vector
*impl
;
219 if (!(impl
= malloc(offsetof(struct hstring_vector
, values
[count
])))) return E_OUTOFMEMORY
;
222 impl
->IVectorView_HSTRING_iface
.lpVtbl
= &hstring_vector_vtbl
;
224 memcpy(impl
->values
, values
, count
* sizeof(HSTRING
));
226 *out
= &impl
->IVectorView_HSTRING_iface
;
230 struct windows_globalization
232 IActivationFactory IActivationFactory_iface
;
233 IGlobalizationPreferencesStatics IGlobalizationPreferencesStatics_iface
;
237 static inline struct windows_globalization
*impl_from_IActivationFactory(IActivationFactory
*iface
)
239 return CONTAINING_RECORD(iface
, struct windows_globalization
, IActivationFactory_iface
);
242 static inline struct windows_globalization
*impl_from_IGlobalizationPreferencesStatics(IGlobalizationPreferencesStatics
*iface
)
244 return CONTAINING_RECORD(iface
, struct windows_globalization
, IGlobalizationPreferencesStatics_iface
);
247 static HRESULT STDMETHODCALLTYPE
windows_globalization_QueryInterface(
248 IActivationFactory
*iface
, REFIID iid
, void **out
)
250 struct windows_globalization
*impl
= impl_from_IActivationFactory(iface
);
251 TRACE("iface %p, iid %s, out %p stub!\n", iface
, debugstr_guid(iid
), out
);
253 if (IsEqualGUID(iid
, &IID_IUnknown
) ||
254 IsEqualGUID(iid
, &IID_IInspectable
) ||
255 IsEqualGUID(iid
, &IID_IAgileObject
) ||
256 IsEqualGUID(iid
, &IID_IActivationFactory
))
258 IUnknown_AddRef(iface
);
259 *out
= &impl
->IActivationFactory_iface
;
263 if (IsEqualGUID(iid
, &IID_IGlobalizationPreferencesStatics
))
265 IUnknown_AddRef(iface
);
266 *out
= &impl
->IGlobalizationPreferencesStatics_iface
;
270 FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
272 return E_NOINTERFACE
;
275 static ULONG STDMETHODCALLTYPE
windows_globalization_AddRef(
276 IActivationFactory
*iface
)
278 struct windows_globalization
*impl
= impl_from_IActivationFactory(iface
);
279 ULONG ref
= InterlockedIncrement(&impl
->ref
);
280 TRACE("iface %p, ref %lu.\n", iface
, ref
);
284 static ULONG STDMETHODCALLTYPE
windows_globalization_Release(
285 IActivationFactory
*iface
)
287 struct windows_globalization
*impl
= impl_from_IActivationFactory(iface
);
288 ULONG ref
= InterlockedDecrement(&impl
->ref
);
289 TRACE("iface %p, ref %lu.\n", iface
, ref
);
293 static HRESULT STDMETHODCALLTYPE
windows_globalization_GetIids(
294 IActivationFactory
*iface
, ULONG
*iid_count
, IID
**iids
)
296 FIXME("iface %p, iid_count %p, iids %p stub!\n", iface
, iid_count
, iids
);
300 static HRESULT STDMETHODCALLTYPE
windows_globalization_GetRuntimeClassName(
301 IActivationFactory
*iface
, HSTRING
*class_name
)
303 FIXME("iface %p, class_name %p stub!\n", iface
, class_name
);
307 static HRESULT STDMETHODCALLTYPE
windows_globalization_GetTrustLevel(
308 IActivationFactory
*iface
, TrustLevel
*trust_level
)
310 FIXME("iface %p, trust_level %p stub!\n", iface
, trust_level
);
314 static HRESULT STDMETHODCALLTYPE
windows_globalization_ActivateInstance(
315 IActivationFactory
*iface
, IInspectable
**instance
)
317 FIXME("iface %p, instance %p stub!\n", iface
, instance
);
321 static const struct IActivationFactoryVtbl activation_factory_vtbl
=
323 windows_globalization_QueryInterface
,
324 windows_globalization_AddRef
,
325 windows_globalization_Release
,
326 /* IInspectable methods */
327 windows_globalization_GetIids
,
328 windows_globalization_GetRuntimeClassName
,
329 windows_globalization_GetTrustLevel
,
330 /* IActivationFactory methods */
331 windows_globalization_ActivateInstance
,
334 static HRESULT STDMETHODCALLTYPE
globalization_preferences_QueryInterface(
335 IGlobalizationPreferencesStatics
*iface
, REFIID iid
, void **object
)
337 struct windows_globalization
*impl
= impl_from_IGlobalizationPreferencesStatics(iface
);
338 return windows_globalization_QueryInterface(&impl
->IActivationFactory_iface
, iid
, object
);
341 static ULONG STDMETHODCALLTYPE
globalization_preferences_AddRef(
342 IGlobalizationPreferencesStatics
*iface
)
344 struct windows_globalization
*impl
= impl_from_IGlobalizationPreferencesStatics(iface
);
345 return windows_globalization_AddRef(&impl
->IActivationFactory_iface
);
348 static ULONG STDMETHODCALLTYPE
globalization_preferences_Release(
349 IGlobalizationPreferencesStatics
*iface
)
351 struct windows_globalization
*impl
= impl_from_IGlobalizationPreferencesStatics(iface
);
352 return windows_globalization_Release(&impl
->IActivationFactory_iface
);
355 static HRESULT STDMETHODCALLTYPE
globalization_preferences_GetIids(
356 IGlobalizationPreferencesStatics
*iface
, ULONG
*iid_count
, IID
**iids
)
358 FIXME("iface %p, iid_count %p, iids %p stub!\n", iface
, iid_count
, iids
);
362 static HRESULT STDMETHODCALLTYPE
globalization_preferences_GetRuntimeClassName(
363 IGlobalizationPreferencesStatics
*iface
, HSTRING
*class_name
)
365 FIXME("iface %p, class_name %p stub!\n", iface
, class_name
);
369 static HRESULT STDMETHODCALLTYPE
globalization_preferences_GetTrustLevel(
370 IGlobalizationPreferencesStatics
*iface
, TrustLevel
*trust_level
)
372 FIXME("iface %p, trust_level %p stub!\n", iface
, trust_level
);
376 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_Calendars(
377 IGlobalizationPreferencesStatics
*iface
, IVectorView_HSTRING
**out
)
379 FIXME("iface %p, out %p stub!\n", iface
, out
);
380 return hstring_vector_create(NULL
, 0, out
);
383 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_Clocks(
384 IGlobalizationPreferencesStatics
*iface
, IVectorView_HSTRING
**out
)
386 FIXME("iface %p, out %p stub!\n", iface
, out
);
387 return hstring_vector_create(NULL
, 0, out
);
390 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_Currencies(
391 IGlobalizationPreferencesStatics
*iface
, IVectorView_HSTRING
**out
)
393 FIXME("iface %p, out %p stub!\n", iface
, out
);
394 return hstring_vector_create(NULL
, 0, out
);
397 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_Languages(
398 IGlobalizationPreferencesStatics
*iface
, IVectorView_HSTRING
**out
)
402 WCHAR locale
[LOCALE_NAME_MAX_LENGTH
];
404 TRACE("iface %p, out %p.\n", iface
, out
);
406 if (!GetUserDefaultLocaleName(locale
, LOCALE_NAME_MAX_LENGTH
))
409 TRACE("returning language %s\n", debugstr_w(locale
));
411 if (FAILED(hr
= WindowsCreateString(locale
, wcslen(locale
), &hstring
)))
414 return hstring_vector_create(&hstring
, 1, out
);
417 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_HomeGeographicRegion(
418 IGlobalizationPreferencesStatics
*iface
, HSTRING
* out
)
422 TRACE("iface %p, out %p.\n", iface
, out
);
424 if (!GetUserDefaultGeoName(country
, 16))
427 TRACE("returning country %s\n", debugstr_w(country
));
429 return WindowsCreateString(country
, wcslen(country
), out
);
432 static HRESULT STDMETHODCALLTYPE
globalization_preferences_get_WeekStartsOn(
433 IGlobalizationPreferencesStatics
*iface
, enum DayOfWeek
* out
)
435 FIXME("iface %p, out %p stub!\n", iface
, out
);
439 static const struct IGlobalizationPreferencesStaticsVtbl globalization_preferences_vtbl
=
441 globalization_preferences_QueryInterface
,
442 globalization_preferences_AddRef
,
443 globalization_preferences_Release
,
444 /* IInspectable methods */
445 globalization_preferences_GetIids
,
446 globalization_preferences_GetRuntimeClassName
,
447 globalization_preferences_GetTrustLevel
,
448 /* IGlobalizationPreferencesStatics methods */
449 globalization_preferences_get_Calendars
,
450 globalization_preferences_get_Clocks
,
451 globalization_preferences_get_Currencies
,
452 globalization_preferences_get_Languages
,
453 globalization_preferences_get_HomeGeographicRegion
,
454 globalization_preferences_get_WeekStartsOn
,
457 static struct windows_globalization windows_globalization
=
459 {&activation_factory_vtbl
},
460 {&globalization_preferences_vtbl
},
464 HRESULT WINAPI
DllGetClassObject(REFCLSID clsid
, REFIID riid
, void **out
)
466 FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid
), debugstr_guid(riid
), out
);
467 return CLASS_E_CLASSNOTAVAILABLE
;
470 HRESULT WINAPI
DllGetActivationFactory(HSTRING classid
, IActivationFactory
**factory
)
472 TRACE("classid %s, factory %p.\n", debugstr_hstring(classid
), factory
);
473 *factory
= &windows_globalization
.IActivationFactory_iface
;
474 IUnknown_AddRef(*factory
);