diff --git a/src/operations.cpp b/src/operations.cpp index 4114e02a..bea1c68c 100644 --- a/src/operations.cpp +++ b/src/operations.cpp @@ -548,9 +548,7 @@ namespace /*_In_*/ BOOLEAN CaseInSensitive ); - PtrRtlEqualUnicodeString rtl_equal_unicode_string_api = PtrRtlEqualUnicodeString( - ::GetProcAddress( - ::GetModuleHandleW(L"ntdll.dll"), "RtlEqualUnicodeString")); + PtrRtlEqualUnicodeString rtl_equal_unicode_string_api; #ifndef LOCALE_INVARIANT # define LOCALE_INVARIANT (MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)) @@ -614,9 +612,35 @@ namespace typedef bool (*Ptr_equal_string_ordinal_ic)(const wchar_t*, const wchar_t*); - Ptr_equal_string_ordinal_ic equal_string_ordinal_ic = - rtl_equal_unicode_string_api ? equal_string_ordinal_ic_1 : equal_string_ordinal_ic_2; - + BOOST_NOINLINE Ptr_equal_string_ordinal_ic get_compare_function() + { + rtl_equal_unicode_string_api = PtrRtlEqualUnicodeString( + ::GetProcAddress( + ::GetModuleHandleW(L"ntdll.dll"), "RtlEqualUnicodeString")); + + return rtl_equal_unicode_string_api ? equal_string_ordinal_ic_1 + : equal_string_ordinal_ic_2; + } + + static Ptr_equal_string_ordinal_ic compare_function; + + inline Ptr_equal_string_ordinal_ic compare() + { + if (!compare_function) + { + compare_function = get_compare_function(); + } + return compare_function; + } + + // force function pointer setup into initialization phase + static bool compare_function_initializer = compare() != 0; + + inline bool equal_string_ordinal_ic(const wchar_t* s1, const wchar_t* s2) + { + return compare()(s1, s2); + } + perms make_permissions(const path& p, DWORD attr) { perms prms = fs::owner_read | fs::group_read | fs::others_read;