ReactOS 0.4.16-dev-715-ga1a169f
winapi_thunks.cpp
Go to the documentation of this file.
1//
2// winapi_thunks.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Definitions of wrappers for Windows API functions that cannot be called
7// directly because they are not available on all supported operating systems.
8//
9
10#include <nt.h>
11#include <ntrtl.h>
12#include <nturtl.h>
13#include <ntsecapi.h>
14#include <corecrt_internal.h>
15#include <appmodel.h>
16#include <roapi.h>
17
18// This is simlar to msvcrt.
19#if _M_AMD64 || _M_ARM || _M_ARM64 || _M_HYBRID
20#define FLS_ALWAYS_AVAILABLE 1
21#endif
22
24 _Success_(return > 0 && return < BufferLength)
25 DWORD
26 WINAPI
27 GetTempPath2W(
30 );
31
32// The XState APIs are declared by the Windows headers only when building for
33// x86 and x64. We declare them here unconditionally so that we can share the
34// same code for all architectures (we simply avoid use of these functions on
35// other architectures).
37
41 _Out_ PDWORD64 feature_mask
42 );
43
44_Success_(return != NULL)
45extern "C" WINBASEAPI PVOID WINAPI LocateXStateFeature(
49 );
50
51#define _ACRT_APPLY_TO_LATE_BOUND_MODULES_0 \
52 _APPLY(api_ms_win_core_datetime_l1_1_1, "api-ms-win-core-datetime-l1-1-1" ) \
53 _APPLY(api_ms_win_core_file_l1_2_4, "api-ms-win-core-file-l1-2-4" ) \
54 _APPLY(api_ms_win_core_file_l1_2_2, "api-ms-win-core-file-l1-2-2" ) \
55 _APPLY(api_ms_win_core_localization_l1_2_1, "api-ms-win-core-localization-l1-2-1" ) \
56 _APPLY(api_ms_win_core_localization_obsolete_l1_2_0, "api-ms-win-core-localization-obsolete-l1-2-0") \
57 _APPLY(api_ms_win_core_processthreads_l1_1_2, "api-ms-win-core-processthreads-l1-1-2" ) \
58 _APPLY(api_ms_win_core_string_l1_1_0, "api-ms-win-core-string-l1-1-0" ) \
59 _APPLY(api_ms_win_core_synch_l1_2_0, "api-ms-win-core-synch-l1-2-0" ) \
60 _APPLY(api_ms_win_core_sysinfo_l1_2_1, "api-ms-win-core-sysinfo-l1-2-1" ) \
61 _APPLY(api_ms_win_core_winrt_l1_1_0, "api-ms-win-core-winrt-l1-1-0" ) \
62 _APPLY(api_ms_win_core_xstate_l2_1_0, "api-ms-win-core-xstate-l2-1-0" ) \
63 _APPLY(api_ms_win_rtcore_ntuser_window_l1_1_0, "api-ms-win-rtcore-ntuser-window-l1-1-0" ) \
64 _APPLY(api_ms_win_security_systemfunctions_l1_1_0, "api-ms-win-security-systemfunctions-l1-1-0" ) \
65 _APPLY(ext_ms_win_ntuser_dialogbox_l1_1_0, "ext-ms-win-ntuser-dialogbox-l1-1-0" ) \
66 _APPLY(ext_ms_win_ntuser_windowstation_l1_1_0, "ext-ms-win-ntuser-windowstation-l1-1-0" ) \
67 _APPLY(advapi32, "advapi32" ) \
68 _APPLY(kernel32, "kernel32" ) \
69 _APPLY(kernelbase, "kernelbase" ) \
70 _APPLY(ntdll, "ntdll" ) \
71 _APPLY(api_ms_win_appmodel_runtime_l1_1_2, "api-ms-win-appmodel-runtime-l1-1-2" ) \
72 _APPLY(user32, "user32" )
73
74#if FLS_ALWAYS_AVAILABLE
75
76#define _ACRT_APPLY_TO_LATE_BOUND_MODULES_1 /* nothing */
77
78#else
79
80#define _ACRT_APPLY_TO_LATE_BOUND_MODULES_1 \
81 _APPLY(api_ms_win_core_fibers_l1_1_0, "api-ms-win-core-fibers-l1-1-0" )
82
83#endif
84
85#define _ACRT_APPLY_TO_LATE_BOUND_MODULES \
86 _ACRT_APPLY_TO_LATE_BOUND_MODULES_0 \
87 _ACRT_APPLY_TO_LATE_BOUND_MODULES_1 \
88
89#define _ACRT_APPLY_TO_LATE_BOUND_FUNCTIONS_0 \
90 _APPLY(AreFileApisANSI, ({ /* api_ms_win_core_file_l1_2_2, */ kernel32 })) \
91 _APPLY(CompareStringEx, ({ api_ms_win_core_string_l1_1_0, kernel32 })) \
92 _APPLY(EnumSystemLocalesEx, ({ api_ms_win_core_localization_l1_2_1, kernel32 })) \
93 _APPLY(GetActiveWindow, ({ api_ms_win_rtcore_ntuser_window_l1_1_0, user32 })) \
94 _APPLY(GetDateFormatEx, ({ api_ms_win_core_datetime_l1_1_1, kernel32 })) \
95 _APPLY(GetTempPath2W, ({ api_ms_win_core_file_l1_2_4, kernelbase })) \
96 _APPLY(GetEnabledXStateFeatures, ({ api_ms_win_core_xstate_l2_1_0, kernel32 })) \
97 _APPLY(GetLastActivePopup, ({ ext_ms_win_ntuser_dialogbox_l1_1_0, user32 })) \
98 _APPLY(GetLocaleInfoEx, ({ api_ms_win_core_localization_l1_2_1, kernel32 })) \
99 _APPLY(GetProcessWindowStation, ({ ext_ms_win_ntuser_windowstation_l1_1_0, user32 })) \
100 _APPLY(GetSystemTimePreciseAsFileTime, ({ api_ms_win_core_sysinfo_l1_2_1 })) \
101 _APPLY(GetTimeFormatEx, ({ api_ms_win_core_datetime_l1_1_1, kernel32 })) \
102 _APPLY(GetUserDefaultLocaleName, ({ api_ms_win_core_localization_l1_2_1, kernel32 })) \
103 _APPLY(GetUserObjectInformationW, ({ ext_ms_win_ntuser_windowstation_l1_1_0, user32 })) \
104 _APPLY(GetXStateFeaturesMask, ({ api_ms_win_core_xstate_l2_1_0, kernel32 })) \
105 _APPLY(InitializeCriticalSectionEx, ({ api_ms_win_core_synch_l1_2_0, kernel32 })) \
106 _APPLY(IsValidLocaleName, ({ api_ms_win_core_localization_l1_2_1, kernel32 })) \
107 _APPLY(LCMapStringEx, ({ api_ms_win_core_localization_l1_2_1, kernel32 })) \
108 _APPLY(LCIDToLocaleName, ({ api_ms_win_core_localization_obsolete_l1_2_0, kernel32 })) \
109 _APPLY(LocaleNameToLCID, ({ api_ms_win_core_localization_l1_2_1, kernel32 })) \
110 _APPLY(LocateXStateFeature, ({ api_ms_win_core_xstate_l2_1_0, kernel32 })) \
111 _APPLY(MessageBoxA, ({ ext_ms_win_ntuser_dialogbox_l1_1_0, user32 })) \
112 _APPLY(MessageBoxW, ({ ext_ms_win_ntuser_dialogbox_l1_1_0, user32 })) \
113 _APPLY(RoInitialize, ({ api_ms_win_core_winrt_l1_1_0 })) \
114 _APPLY(RoUninitialize, ({ api_ms_win_core_winrt_l1_1_0 })) \
115 _APPLY(AppPolicyGetProcessTerminationMethod, ({ api_ms_win_appmodel_runtime_l1_1_2 })) \
116 _APPLY(AppPolicyGetThreadInitializationType, ({ api_ms_win_appmodel_runtime_l1_1_2 })) \
117 _APPLY(AppPolicyGetShowDeveloperDiagnostic, ({ api_ms_win_appmodel_runtime_l1_1_2 })) \
118 _APPLY(AppPolicyGetWindowingModel, ({ api_ms_win_appmodel_runtime_l1_1_2 })) \
119 _APPLY(SetThreadStackGuarantee, ({ api_ms_win_core_processthreads_l1_1_2, kernel32 })) \
120 _APPLY(SystemFunction036, ({ api_ms_win_security_systemfunctions_l1_1_0, advapi32 }))
121
122#if FLS_ALWAYS_AVAILABLE
123
124#define _ACRT_APPLY_TO_LATE_BOUND_FUNCTIONS_1 /* nothing */
125
126#else
127
128#define _ACRT_APPLY_TO_LATE_BOUND_FUNCTIONS_1 \
129 _APPLY(FlsAlloc, ({ api_ms_win_core_fibers_l1_1_0, kernel32 })) \
130 _APPLY(FlsFree, ({ api_ms_win_core_fibers_l1_1_0, kernel32 })) \
131 _APPLY(FlsGetValue, ({ api_ms_win_core_fibers_l1_1_0, kernel32 })) \
132 _APPLY(FlsSetValue, ({ api_ms_win_core_fibers_l1_1_0, kernel32 }))
133
134#endif
135
136#define _ACRT_APPLY_TO_LATE_BOUND_FUNCTIONS \
137 _ACRT_APPLY_TO_LATE_BOUND_FUNCTIONS_0 \
138 _ACRT_APPLY_TO_LATE_BOUND_FUNCTIONS_1 \
139
140namespace
141{
142 // Generate enumerators for each of the modules:
143 enum module_id : unsigned
144 {
145 #define _APPLY(_SYMBOL, _NAME) _SYMBOL,
147 #undef _APPLY
148
150 };
151
152 // Generate a table of module names that can be indexed by the module_id
153 // enumerators:
154 static wchar_t const* const module_names[module_id_count] =
155 {
156 #define _APPLY(_SYMBOL, _NAME) _CRT_WIDE(_NAME),
158 #undef _APPLY
159 };
160
161 // Generate enumerators for each of the functions:
162 enum function_id : unsigned
163 {
164 #define _APPLY(_FUNCTION, _MODULES) _CRT_CONCATENATE(_FUNCTION, _id),
166 #undef _APPLY
167
169 };
170
171 // Generate a typedef for each function of the form function_pft.
172 #define _APPLY(_FUNCTION, _MODULES) \
173 using _CRT_CONCATENATE(_FUNCTION, _pft) = decltype(_FUNCTION)*;
175 #undef _APPLY
176}
177
178// This table stores the module handles that we have obtained via LoadLibrary.
179// If a handle is null, we have not yet attempted to load that module. If a
180// handle is -1 (INVALID_HANDLE_VALUE), we have attempted to load the module
181// but the attempt failed.
183
184// This table stores the function pointers that we have loaded dynamically. The
185// function pointers are stored in encoded form via __crt_fast_encode_ponter. If
186// a function pointer is an encoded null pointer, we have not yet attempted to
187// get that function pointer. If a function pointer is an encoded -1, we have
188// attempted to get that function pointer but the attempt failed.
190
192{
193 void* const encoded_nullptr = __crt_fast_encode_pointer(nullptr);
194
195 for (void*& p : encoded_function_pointers)
196 {
197 p = encoded_nullptr;
198 }
199
200 return true;
201}
202
203extern "C" bool __cdecl __acrt_uninitialize_winapi_thunks(bool const terminating)
204{
205 // If the process is terminating, there's no need to free any module handles
206 if (terminating)
207 {
208 return true;
209 }
210
212 {
213 if (module)
214 {
216 {
218 }
219
220 module = nullptr;
221 }
222 }
223
224 return true;
225}
226
227static __forceinline void* __cdecl invalid_function_sentinel() throw()
228{
229 return reinterpret_cast<void*>(static_cast<uintptr_t>(-1));
230}
231
232static HMODULE __cdecl try_load_library_from_system_directory(wchar_t const* const name) throw()
233{
235 if (handle)
236 {
237 return handle;
238 }
239
240 // LOAD_LIBRARY_SEARCH_SYSTEM32 is only supported by Windows 7 and above; if
241 // the OS does not support this flag, try again without it. On these OSes,
242 // all APISets will be forwarders. To prevent DLL hijacking, do not attempt
243 // to load the APISet forwarders dynamically. This will cause our caller to
244 // fall back to the real DLL (e.g. kernel32). All of those are known DLLs.
246 wcsncmp(name, L"api-ms-", 7) != 0 &&
247 wcsncmp(name, L"ext-ms-", 7) != 0)
248 {
249 return LoadLibraryExW(name, nullptr, 0);
250 }
251
252 return nullptr;
253}
254
255static HMODULE __cdecl try_get_module(module_id const id) throw()
256{
257 // First check to see if we've cached the module handle:
258 if (HMODULE const cached_handle = __crt_interlocked_read_pointer(module_handles + id))
259 {
260 if (cached_handle == INVALID_HANDLE_VALUE)
261 {
262 return nullptr;
263 }
264
265 return cached_handle;
266 }
267
268 // If we haven't yet cached the module handle, try to load the library. If
269 // this fails, cache the sentinel handle value INVALID_HANDLE_VALUE so that
270 // we don't attempt to load the module again:
272 if (!new_handle)
273 {
274 if (HMODULE const cached_handle = __crt_interlocked_exchange_pointer(module_handles + id, INVALID_HANDLE_VALUE))
275 {
276 _ASSERTE(cached_handle == INVALID_HANDLE_VALUE);
277 }
278
279 return nullptr;
280 }
281
282 // Swap the new handle into the cache. If the cache no longer contained a
283 // null handle, then some other thread loaded the module and cached the
284 // handle while we were doing the same. In that case, we free the handle
285 // once to maintain the reference count:
286 if (HMODULE const cached_handle = __crt_interlocked_exchange_pointer(module_handles + id, new_handle))
287 {
288 _ASSERTE(cached_handle == new_handle);
289 FreeLibrary(new_handle);
290 }
291
292 return new_handle;
293}
294
296 module_id const* const first,
297 module_id const* const last
298 ) throw()
299{
300 for (module_id const* it = first; it != last; ++it)
301 {
302 HMODULE const handle = try_get_module(*it);
303 if (handle)
304 {
305 return handle;
306 }
307 }
308
309 return nullptr;
310}
311
313 char const* const name,
314 module_id const* const first_module_id,
315 module_id const* const last_module_id
316 ) throw()
317{
318 HMODULE const module_handle = try_get_first_available_module(first_module_id, last_module_id);
319 if (!module_handle)
320 {
321 return nullptr;
322 }
323
324 return reinterpret_cast<void*>(GetProcAddress(module_handle, name));
325}
326
328 function_id const id,
329 char const* const name,
330 module_id const* const first_module_id,
331 module_id const* const last_module_id
332 ) throw()
333{
334 // First check to see if we've cached the function pointer:
335 {
336 void* const cached_fp = __crt_fast_decode_pointer(
337 __crt_interlocked_read_pointer(encoded_function_pointers + id));
338
339 if (cached_fp == invalid_function_sentinel())
340 {
341 return nullptr;
342 }
343
344 if (cached_fp)
345 {
346 return cached_fp;
347 }
348 }
349
350 // If we haven't yet cached the function pointer, try to import it from any
351 // of the modules in which it might be defined. If this fails, cache the
352 // sentinel pointer so that we don't attempt to load this function again:
353 void* const new_fp = try_get_proc_address_from_first_available_module(name, first_module_id, last_module_id);
354 if (!new_fp)
355 {
356 void* const cached_fp = __crt_fast_decode_pointer(
357 __crt_interlocked_exchange_pointer(
359 __crt_fast_encode_pointer(invalid_function_sentinel())));
360
361 if (cached_fp)
362 {
363 _ASSERTE(cached_fp == invalid_function_sentinel());
364 }
365
366 return nullptr;
367 }
368
369 // Swap the newly obtained function pointer into the cache. The cache may
370 // no longer contain an encoded null pointer if another thread obtained the
371 // function address while we were doing the same (both threads should have
372 // gotten the same function pointer):
373 {
374 void* const cached_fp = __crt_fast_decode_pointer(
375 __crt_interlocked_exchange_pointer(
377 __crt_fast_encode_pointer(new_fp)));
378
379 if (cached_fp)
380 {
381 _ASSERTE(cached_fp == new_fp);
382 }
383 }
384
385 return new_fp;
386}
387
388// Generate accessors that wrap the general try_get_function for each function,
389// passing the correct set of candidate modules and returning a function pointer
390// of the correct type:
391#define _APPLY(_FUNCTION, _MODULES) \
392 static _CRT_CONCATENATE(_FUNCTION, _pft) __cdecl _CRT_CONCATENATE(try_get_, _FUNCTION)() throw() \
393 { \
394 static module_id const candidate_modules[] = _CRT_UNPARENTHESIZE(_MODULES); \
395 \
396 return reinterpret_cast<_CRT_CONCATENATE(_FUNCTION, _pft)>(try_get_function( \
397 _CRT_CONCATENATE(_FUNCTION, _id), \
398 _CRT_STRINGIZE(_FUNCTION), \
399 candidate_modules, \
400 candidate_modules + _countof(candidate_modules))); \
401 }
403#undef _APPLY
404
406{
407 if (auto const are_file_apis_ansi = try_get_AreFileApisANSI())
408 {
409 return are_file_apis_ansi();
410 }
411
412 // If we were unable to get the AreFileApisANSI function, we can safely
413 // assume that the file APIs are, in fact, ANSI:
414 return TRUE;
415}
416
418 LPCWSTR const locale_name,
419 DWORD const flags,
420 LPCWCH const string1,
421 int const string1_count,
422 LPCWCH const string2,
423 int const string2_count,
425 LPVOID const reserved,
426 LPARAM const param
427 )
428{
429 if (auto const compare_string_ex = try_get_CompareStringEx())
430 {
431 // On WCOS devices, CompareStringEx may calls into icu.dll which is an OS component using the UCRT.
432 // If icu.dll calls any UCRT export under OS mode (ex: malloc), then CompareStringEx will return under Prog Mode even if
433 // we started in OS mode. To prevent this, an OS mode guard is in place.
434 __crt_state_management::scoped_global_state_reset os_mode_guard;
435 return compare_string_ex(locale_name, flags, string1, string1_count, string2, string2_count, version, reserved, param);
436 }
437
438 return CompareStringW(__acrt_LocaleNameToLCID(locale_name, 0), flags, string1, string1_count, string2, string2_count);
439}
440
441#ifdef __clang__
442static LOCALE_ENUMPROCEX static_enum_proc;
443static BOOL CALLBACK LocaleEnumProcW(LPWSTR locale_string)
444{
445 return __crt_fast_decode_pointer(static_enum_proc)(locale_string, 0, 0);
446}
447#endif
448
449// This has been split into its own function to work around a bug in the Dev12
450// C++ compiler where nested captureless lambdas are not convertible to the
451// required function pointer type.
454 ) throw()
455{
456#ifndef __clang__
457 static LOCALE_ENUMPROCEX static_enum_proc;
458#endif
459
460 static_enum_proc = __crt_fast_encode_pointer(enum_proc);
462#ifdef __clang__
463 LocaleEnumProcW,
464#else
465 [](LPWSTR locale_string)
466 #if defined(__GNUC__) && !defined(__clang__)
468 #endif // __GNUC__
469 { return __crt_fast_decode_pointer(static_enum_proc)(locale_string, 0, 0); },
470#endif
472 static_enum_proc = __crt_fast_encode_pointer(nullptr);
473
474 return result;
475}
476
479 DWORD const flags,
480 LPARAM const param,
481 LPVOID const reserved
482 )
483{
484 if (auto const enum_system_locales_ex = try_get_EnumSystemLocalesEx())
485 {
486 return enum_system_locales_ex(enum_proc, flags, param, reserved);
487 }
488
489 return __acrt_lock_and_call(__acrt_locale_lock, [&]() -> BOOL
490 {
492 });
493}
494
496{
497#if FLS_ALWAYS_AVAILABLE
498 return FlsAlloc(callback);
499#else
500 if (auto const fls_alloc = try_get_FlsAlloc())
501 {
502 return fls_alloc(callback);
503 }
504
505 return TlsAlloc();
506#endif
507}
508
509extern "C" BOOL WINAPI __acrt_FlsFree(DWORD const fls_index)
510{
511#if FLS_ALWAYS_AVAILABLE
512 return FlsFree(fls_index);
513#else
514 if (auto const fls_free = try_get_FlsFree())
515 {
516 return fls_free(fls_index);
517 }
518
519 return TlsFree(fls_index);
520#endif
521}
522
523extern "C" PVOID WINAPI __acrt_FlsGetValue(DWORD const fls_index)
524{
525#if FLS_ALWAYS_AVAILABLE
526 return FlsGetValue(fls_index);
527#else
528 if (auto const fls_get_value = try_get_FlsGetValue())
529 {
530 return fls_get_value(fls_index);
531 }
532
533 return TlsGetValue(fls_index);
534#endif
535}
536
537extern "C" BOOL WINAPI __acrt_FlsSetValue(DWORD const fls_index, PVOID const fls_data)
538{
539#if FLS_ALWAYS_AVAILABLE
540 return FlsSetValue(fls_index, fls_data);
541#else
542 if (auto const fls_set_value = try_get_FlsSetValue())
543 {
544 return fls_set_value(fls_index, fls_data);
545 }
546
547 return TlsSetValue(fls_index, fls_data);
548#endif
549}
550
552 LPCWSTR const locale_name,
553 DWORD const flags,
554 SYSTEMTIME CONST* const date,
555 LPCWSTR const format,
556 LPWSTR const buffer,
557 int const buffer_count,
558 LPCWSTR const calendar
559 )
560{
561 if (auto const get_date_format_ex = try_get_GetDateFormatEx())
562 {
563 return get_date_format_ex(locale_name, flags, date, format, buffer, buffer_count, calendar);
564 }
565
567}
568
572)
573{
574 if (auto const get_temp_path2w = try_get_GetTempPath2W())
575 {
576 return get_temp_path2w(nBufferLength, lpBuffer);
577 }
579}
580
582{
583 if (auto const get_enabled_xstate_features = try_get_GetEnabledXStateFeatures())
584 {
585 return get_enabled_xstate_features();
586 }
587
588 abort(); // No fallback; callers should check availablility before calling
589}
590
592 LPCWSTR const locale_name,
593 LCTYPE const lc_type,
594 LPWSTR const data,
595 int const data_count
596 )
597{
598 if (auto const get_locale_info_ex = try_get_GetLocaleInfoEx())
599 {
600 return get_locale_info_ex(locale_name, lc_type, data, data_count);
601 }
602
603 return GetLocaleInfoW(__acrt_LocaleNameToLCID(locale_name, 0), lc_type, data, data_count);
604}
605
607{
608 if (auto const get_system_time_precise_as_file_time = try_get_GetSystemTimePreciseAsFileTime())
609 {
610 return get_system_time_precise_as_file_time(system_time);
611 }
612
613 return GetSystemTimeAsFileTime(system_time);
614}
615
617 LPCWSTR const locale_name,
618 DWORD const flags,
619 SYSTEMTIME CONST* const time,
620 LPCWSTR const format,
621 LPWSTR const buffer,
622 int const buffer_count
623 )
624{
625 if (auto const get_time_format_ex = try_get_GetTimeFormatEx())
626 {
627 return get_time_format_ex(locale_name, flags, time, format, buffer, buffer_count);
628 }
629
631}
632
634 LPWSTR const locale_name,
635 int const locale_name_count
636 )
637{
638 if (auto const get_user_default_locale_name = try_get_GetUserDefaultLocaleName())
639 {
640 return get_user_default_locale_name(locale_name, locale_name_count);
641 }
642
643 return __acrt_LCIDToLocaleName(GetUserDefaultLCID(), locale_name, locale_name_count, 0);
644}
645
647 PCONTEXT const context,
648 PDWORD64 const feature_mask
649 )
650{
651 if (auto const get_xstate_features_mask = try_get_GetXStateFeaturesMask())
652 {
653 return get_xstate_features_mask(context, feature_mask);
654 }
655
656 abort(); // No fallback; callers should check availablility before calling
657}
658
661 DWORD const spin_count,
662 DWORD const flags
663 )
664{
665 if (auto const initialize_critical_section_ex = try_get_InitializeCriticalSectionEx())
666 {
667 return initialize_critical_section_ex(critical_section, spin_count, flags);
668 }
669
671}
672
674{
675 if (auto const is_valid_locale_name = try_get_IsValidLocaleName())
676 {
677 return is_valid_locale_name(locale_name);
678 }
679
681}
682
684 LPCWSTR const locale_name,
685 DWORD const flags,
686 LPCWSTR const source,
687 int const source_count,
688 LPWSTR const destination,
689 int const destination_count,
691 LPVOID const reserved,
692 LPARAM const sort_handle
693 )
694{
695 if (auto const lc_map_string_ex = try_get_LCMapStringEx())
696 {
697 return lc_map_string_ex(locale_name, flags, source, source_count, destination, destination_count, version, reserved, sort_handle);
698 }
699#pragma warning(disable:__WARNING_PRECONDITION_NULLTERMINATION_VIOLATION) // 26035 LCMapStringW annotation is presently incorrect 11/26/2014 Jaykrell
701}
702
704 LCID const locale,
705 LPWSTR const name,
706 int const name_count,
707 DWORD const flags
708 )
709{
710 if (auto const lcid_to_locale_name = try_get_LCIDToLocaleName())
711 {
712 return lcid_to_locale_name(locale, name, name_count, flags);
713 }
714
715 return __acrt_DownlevelLCIDToLocaleName(locale, name, name_count);
716}
717
719 LPCWSTR const name,
720 DWORD const flags
721 )
722{
723 if (auto const locale_name_to_lcid = try_get_LocaleNameToLCID())
724 {
725 return locale_name_to_lcid(name, flags);
726 }
727
729}
730
732 PCONTEXT const content,
733 DWORD const feature_id,
734 PDWORD const length
735 )
736{
737 if (auto const locate_xstate_feature = try_get_LocateXStateFeature())
738 {
739 return locate_xstate_feature(content, feature_id, length);
740 }
741
742 abort(); // No fallback; callers should check availablility before calling
743}
744
746 HWND const hwnd,
747 LPCSTR const text,
748 LPCSTR const caption,
749 UINT const type
750 )
751{
752 if (auto const message_box_a = try_get_MessageBoxA())
753 {
754 return message_box_a(hwnd, text, caption, type);
755 }
756
757 abort(); // No fallback; callers should check availablility before calling
758}
759
761 HWND const hwnd,
762 LPCWSTR const text,
763 LPCWSTR const caption,
764 UINT const type
765 )
766{
767 if (auto const message_box_w = try_get_MessageBoxW())
768 {
769 return message_box_w(hwnd, text, caption, type);
770 }
771
772 abort(); // No fallback; callers should check availablility before calling
773}
774
776 PVOID const buffer,
777 ULONG const buffer_count
778 )
779{
780 if (auto const rtl_gen_random = try_get_SystemFunction036())
781 {
782 return rtl_gen_random(buffer, buffer_count);
783 }
784
785 abort(); // No fallback (this function should exist)
786}
787
789{
790 if (auto const ro_initialize = try_get_RoInitialize())
791 {
792 return ro_initialize(init_type);
793 }
794
795 return S_OK; // No fallback (this is a best-effort wrapper)
796}
797
799{
800 if (auto const ro_uninitialize = try_get_RoUninitialize())
801 {
802 return ro_uninitialize();
803 }
804
805 // No fallback (this is a best-effort wrapper)
806}
807
809{
810 if (auto const app_policy_get_process_terminaton_method_claims = try_get_AppPolicyGetProcessTerminationMethod())
811 {
812 return app_policy_get_process_terminaton_method_claims(GetCurrentThreadEffectiveToken(), policy);
813 }
814
815 return STATUS_NOT_FOUND;
816}
817
819{
820 if (auto const app_policy_get_thread_initialization_type_claims = try_get_AppPolicyGetThreadInitializationType())
821 {
822 return app_policy_get_thread_initialization_type_claims(GetCurrentThreadEffectiveToken(), policy);
823 }
824
825 return STATUS_NOT_FOUND;
826}
827
829{
830 if (auto const app_policy_get_show_developer_diagnostic_claims = try_get_AppPolicyGetShowDeveloperDiagnostic())
831 {
832 return app_policy_get_show_developer_diagnostic_claims(GetCurrentThreadEffectiveToken(), policy);
833 }
834
835 return STATUS_NOT_FOUND;
836}
837
839{
840 if (auto const app_policy_get_windowing_model_claims = try_get_AppPolicyGetWindowingModel())
841 {
842 return app_policy_get_windowing_model_claims(GetCurrentThreadEffectiveToken(), policy);
843 }
844
845 return STATUS_NOT_FOUND;
846}
847
848extern "C" BOOL WINAPI __acrt_SetThreadStackGuarantee(PULONG const stack_size_in_bytes)
849{
850 if (auto const set_thread_stack_guarantee = try_get_SetThreadStackGuarantee())
851 {
852 return set_thread_stack_guarantee(stack_size_in_bytes);
853 }
854
855 return FALSE;
856}
857
859{
860 bool can_show_message_box = false;
862 && try_get_MessageBoxA() != nullptr
863 && try_get_MessageBoxW() != nullptr)
864 {
865 can_show_message_box = true;
866 }
867 return can_show_message_box;
868}
869
871{
872 return try_get_CompareStringEx() != nullptr;
873}
874
875// This function simply attempts to get each of the locale-related APIs. This
876// allows a caller to "pre-load" the modules in which these APIs are hosted. We
877// use this in the _wsetlocale implementation to avoid calls to LoadLibrary while
878// the locale lock is held.
880{
881 try_get_AreFileApisANSI();
882 try_get_CompareStringEx();
883 try_get_EnumSystemLocalesEx();
884 try_get_GetDateFormatEx();
885 try_get_GetLocaleInfoEx();
886 try_get_GetTimeFormatEx();
887 try_get_GetUserDefaultLocaleName();
888 try_get_IsValidLocaleName();
889 try_get_LCMapStringEx();
890 try_get_LCIDToLocaleName();
891 try_get_LocaleNameToLCID();
892}
893
895{
896 return try_get_LocateXStateFeature() != nullptr;
897}
898
900{
901 auto const get_active_window = try_get_GetActiveWindow();
902 if (!get_active_window)
903 {
904 return nullptr;
905 }
906
907 HWND const active_window = get_active_window();
908 if (!active_window)
909 {
910 return nullptr;
911 }
912
913 auto const get_last_active_popup = try_get_GetLastActivePopup();
914 if (!get_last_active_popup)
915 {
916 return active_window;
917 }
918
919 return get_last_active_popup(active_window);
920}
921
923{
924 auto const get_process_window_station = try_get_GetProcessWindowStation();
925 if (!get_process_window_station)
926 {
927 return true;
928 }
929
930 auto const get_user_object_information = try_get_GetUserObjectInformationW();
931 if (!get_user_object_information)
932 {
933 return true;
934 }
935
936 HWINSTA const hwinsta = get_process_window_station();
937 if (!hwinsta)
938 {
939 return false;
940 }
941
942 USEROBJECTFLAGS uof{};
943 if (!get_user_object_information(hwinsta, UOI_FLAGS, &uof, sizeof(uof), nullptr))
944 {
945 return false;
946 }
947
948 if ((uof.dwFlags & WSF_VISIBLE) == 0)
949 {
950 return false;
951 }
952
953 return true;
954}
unsigned char BOOLEAN
#define __GNUC__
Definition: _icc.h:38
#define __cdecl
Definition: accygwin.h:79
AppPolicyShowDeveloperDiagnostic
Definition: appmodel.h:27
AppPolicyThreadInitializationType
Definition: appmodel.h:21
AppPolicyWindowingModel
Definition: appmodel.h:33
AppPolicyProcessTerminationMethod
Definition: appmodel.h:15
WINBASEAPI _Check_return_ _Out_ AppPolicyProcessTerminationMethod * policy
Definition: appmodel.h:47
Definition: bufpool.h:45
Definition: _locale.h:75
@ __acrt_locale_lock
@ windowing_model_policy_hwnd
LCID __cdecl __acrt_DownlevelLocaleNameToLCID(_In_opt_ LPCWSTR localeName)
windowing_model_policy __cdecl __acrt_get_windowing_model_policy(void)
#define _ASSERTE(expr)
Definition: crtdbg.h:114
result_buffer_count char *const _In_ int const _In_ bool const _In_ unsigned const _In_ STRFLT const _In_ bool const _Inout_ __crt_cached_ptd_host &ptd throw()
Definition: cvt.cpp:119
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
content
Definition: atl_ax.c:994
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define CALLBACK
Definition: compat.h:35
static const WCHAR version[]
Definition: asmname.c:66
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex)
Definition: fiber.c:460
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
Definition: fiber.c:481
BOOL WINAPI FlsFree(DWORD dwFlsIndex)
Definition: fiber.c:400
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
Definition: fiber.c:341
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1240
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1100
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
Definition: thread.c:1276
BOOL WINAPI TlsFree(IN DWORD Index)
Definition: thread.c:1166
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW lpfnLocaleEnum, DWORD dwFlags)
Definition: locale.c:2999
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4014
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: locale.c:2923
LCID WINAPI GetUserDefaultLCID(void)
Definition: locale.c:1211
INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen)
Definition: locale.c:3805
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1666
const WCHAR * text
Definition: package.c:1794
r reserved
Definition: btrfs.c:3006
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
const GLint * first
Definition: glext.h:5794
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
#define WINBASEAPI
Definition: green.h:8
#define abort()
Definition: i386-dis.c:34
#define S_OK
Definition: intsafe.h:52
INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
Definition: lcformat.c:1093
INT WINAPI GetDateFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
Definition: lcformat.c:993
int __cdecl __acrt_DownlevelLCIDToLocaleName(LCID lcid, LPWSTR outLocaleName, int cchLocaleName)
unsigned int uintptr_t
Definition: intrin.h:47
__u16 date
Definition: mkdosfs.c:8
__u16 time
Definition: mkdosfs.c:8
CRITICAL_SECTION critical_section
#define GetCurrentThreadEffectiveToken()
Definition: security.c:42
static IPrintDialogCallback callback
Definition: printdlg.c:326
static CHAR string1[MAX_PATH]
Definition: asmname.c:32
static UINT UINT last
Definition: font.c:45
static CHAR string2[MAX_PATH]
Definition: automation.c:345
static wchar_t const *const module_names[module_id_count]
unsigned int UINT
Definition: ndis.h:50
#define _Out_writes_to_opt_(s, c)
Definition: no_sal2.h:238
#define _Out_opt_
Definition: no_sal2.h:214
#define _Success_(c)
Definition: no_sal2.h:84
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
CONST WCHAR * LPCWCH
Definition: ntbasedef.h:419
#define L(x)
Definition: ntvdm.h:50
#define CONST
Definition: pedump.c:81
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
RO_INIT_TYPE
Definition: roapi.h:24
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
DWORD LCID
Definition: nls.h:13
size_t const source_count
Definition: read.cpp:240
#define STATUS_NOT_FOUND
Definition: shellext.h:72
Definition: http.c:7252
Definition: format.c:58
Definition: name.c:39
BOOL WINAPI InitializeCriticalSectionAndSpinCount(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount)
Definition: synch.c:765
uint64_t * PDWORD64
Definition: typedefs.h:67
uint32_t * PULONG
Definition: typedefs.h:59
uint64_t DWORD64
Definition: typedefs.h:67
#define __stdcall
Definition: typedefs.h:25
uint32_t ULONG
Definition: typedefs.h:59
size_t const destination_count
Definition: wcrtomb.cpp:52
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
static BOOL CALLBACK enum_proc(HWND hwnd, LPARAM lParam)
Definition: win.c:671
BOOL WINAPI __acrt_IsValidLocaleName(LPCWSTR const locale_name)
LONG WINAPI __acrt_AppPolicyGetThreadInitializationTypeInternal(_Out_ AppPolicyThreadInitializationType *policy)
bool __cdecl __acrt_can_show_message_box()
BOOL WINAPI __acrt_FlsFree(DWORD const fls_index)
DWORD64 WINAPI __acrt_GetEnabledXStateFeatures()
int WINAPI __acrt_CompareStringEx(LPCWSTR const locale_name, DWORD const flags, LPCWCH const string1, int const string1_count, LPCWCH const string2, int const string2_count, LPNLSVERSIONINFO const version, LPVOID const reserved, LPARAM const param)
LONG WINAPI __acrt_AppPolicyGetWindowingModelInternal(_Out_ AppPolicyWindowingModel *policy)
#define _ACRT_APPLY_TO_LATE_BOUND_FUNCTIONS
int WINAPI __acrt_MessageBoxW(HWND const hwnd, LPCWSTR const text, LPCWSTR const caption, UINT const type)
_In_ DWORD feature_id
int WINAPI __acrt_LCMapStringEx(LPCWSTR const locale_name, DWORD const flags, LPCWSTR const source, int const source_count, LPWSTR const destination, int const destination_count, LPNLSVERSIONINFO const version, LPVOID const reserved, LPARAM const sort_handle)
DWORD WINAPI __acrt_FlsAlloc(PFLS_CALLBACK_FUNCTION const callback)
bool __cdecl __acrt_initialize_winapi_thunks()
_Must_inspect_result_ WINBASEAPI BOOL WINAPI GetXStateFeaturesMask(_In_ PCONTEXT context, _Out_ PDWORD64 feature_mask)
LCID WINAPI __acrt_LocaleNameToLCID(LPCWSTR const name, DWORD const flags)
static HMODULE __cdecl try_get_first_available_module(module_id const *const first, module_id const *const last)
VOID WINAPI __acrt_GetSystemTimePreciseAsFileTime(LPFILETIME const system_time)
static HMODULE __cdecl try_get_module(module_id const id)
static void *__cdecl try_get_function(function_id const id, char const *const name, module_id const *const first_module_id, module_id const *const last_module_id)
int WINAPI __acrt_GetLocaleInfoEx(LPCWSTR const locale_name, LCTYPE const lc_type, LPWSTR const data, int const data_count)
static BOOL enum_system_locales_ex_nolock(LOCALE_ENUMPROCEX const enum_proc)
BOOL WINAPI __acrt_GetXStateFeaturesMask(PCONTEXT const context, PDWORD64 const feature_mask)
int WINAPI __acrt_GetTimeFormatEx(LPCWSTR const locale_name, DWORD const flags, SYSTEMTIME CONST *const time, LPCWSTR const format, LPWSTR const buffer, int const buffer_count)
BOOL WINAPI __acrt_FlsSetValue(DWORD const fls_index, PVOID const fls_data)
WINBASEAPI DWORD64 WINAPI GetEnabledXStateFeatures()
void WINAPI __acrt_RoUninitialize()
LONG WINAPI __acrt_AppPolicyGetProcessTerminationMethodInternal(_Out_ AppPolicyProcessTerminationMethod *policy)
BOOL WINAPI __acrt_SetThreadStackGuarantee(PULONG const stack_size_in_bytes)
BOOL WINAPI __acrt_EnumSystemLocalesEx(LOCALE_ENUMPROCEX const enum_proc, DWORD const flags, LPARAM const param, LPVOID const reserved)
int WINAPI __acrt_LCIDToLocaleName(LCID const locale, LPWSTR const name, int const name_count, DWORD const flags)
BOOL WINAPI __acrt_InitializeCriticalSectionEx(LPCRITICAL_SECTION const critical_section, DWORD const spin_count, DWORD const flags)
#define _ACRT_APPLY_TO_LATE_BOUND_MODULES
bool __cdecl __acrt_uninitialize_winapi_thunks(bool const terminating)
LONG WINAPI __acrt_AppPolicyGetShowDeveloperDiagnosticInternal(_Out_ AppPolicyShowDeveloperDiagnostic *policy)
int WINAPI __acrt_GetUserDefaultLocaleName(LPWSTR const locale_name, int const locale_name_count)
bool __cdecl __acrt_is_interactive()
HRESULT WINAPI __acrt_RoInitialize(RO_INIT_TYPE const init_type)
int WINAPI __acrt_GetTempPath2W(DWORD nBufferLength, LPWSTR lpBuffer)
bool __cdecl __acrt_can_use_vista_locale_apis()
PVOID WINAPI __acrt_FlsGetValue(DWORD const fls_index)
HWND __cdecl __acrt_get_parent_window()
static __forceinline void *__cdecl try_get_proc_address_from_first_available_module(char const *const name, module_id const *const first_module_id, module_id const *const last_module_id)
BOOLEAN WINAPI __acrt_RtlGenRandom(PVOID const buffer, ULONG const buffer_count)
static void * encoded_function_pointers[function_id_count]
static __forceinline void *__cdecl invalid_function_sentinel()
_ACRT_APPLY_TO_LATE_BOUND_FUNCTIONS BOOL WINAPI __acrt_AreFileApisANSI()
PVOID WINAPI __acrt_LocateXStateFeature(PCONTEXT const content, DWORD const feature_id, PDWORD const length)
int WINAPI __acrt_MessageBoxA(HWND const hwnd, LPCSTR const text, LPCSTR const caption, UINT const type)
static HMODULE __cdecl try_load_library_from_system_directory(wchar_t const *const name)
static HMODULE module_handles[module_id_count]
int WINAPI __acrt_GetDateFormatEx(LPCWSTR const locale_name, DWORD const flags, SYSTEMTIME CONST *const date, LPCWSTR const format, LPWSTR const buffer, int const buffer_count, LPCWSTR const calendar)
bool __cdecl __acrt_can_use_xstate_apis()
void __cdecl __acrt_eagerly_load_locale_apis()
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOAD_LIBRARY_SEARCH_SYSTEM32
Definition: winbase.h:379
VOID(WINAPI * PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winbase.h:1469
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD nBufferLength
Definition: winbase.h:3098
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
BOOL(CALLBACK * LOCALE_ENUMPROCEX)(LPWSTR, DWORD, LPARAM)
Definition: winnls.h:541
#define LCID_INSTALLED
Definition: winnls.h:203
DWORD LCTYPE
Definition: winnls.h:519
BOOL(CALLBACK * LOCALE_ENUMPROCW)(LPWSTR)
Definition: winnls.h:540
#define WSF_VISIBLE
Definition: winuser.h:2455
#define UOI_FLAGS
Definition: winuser.h:1086
const char * LPCSTR
Definition: xmlstorage.h:183
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
size_t const buffer_count
Definition: xtoa.cpp:36