return i;
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- ////////////////////////////////////////////////////////////////////////////
- //
- // LoadSortModuleAndInvariant()
- //
- // Attempts to load the given dll. If that is successful, attempts to
- // load the invariant data. If that is successful, returns the module handle
- // and the addresses of the SortGetHandle function and SortCloseHandle function
- //
- // failure is indicated by returning NULL for the module handle and the
- // function addresses
- //
- ////////////////////////////////////////////////////////////////////////////
-
- HMODULE LoadSortModuleAndInvariant(
- __in LPCWSTR sDllName,
- __in DWORD dwVersion,
- __out SORTGETHANDLE* ppGetHandle,
- __out SORTCLOSEHANDLE* ppCloseHandle
- )
- {
- *ppGetHandle = NULL;
- *ppCloseHandle = NULL;
- HMODULE hSort;
-
- if(FAILED(UtilCode::LoadLibraryShim(sDllName, NULL, NULL, &hSort)))
- {
- return NULL;
- }
-
- SORTGETHANDLE pGetHandle = (SORTGETHANDLE)GetProcAddress(hSort, "SortGetHandle");
- SORTCLOSEHANDLE pCloseHandle = (SORTCLOSEHANDLE)GetProcAddress(hSort, "SortCloseHandle");
-
- // If we didn't load the procs, then remember that
- if (pCloseHandle == NULL || pGetHandle == NULL)
- {
- ::FreeLibrary(hSort);
- return NULL;
- }
-
- // Verify that the data file's available
- NLSVERSIONINFO sortVersion;
- sortVersion.dwNLSVersionInfoSize = sizeof(NLSVERSIONINFO);
- sortVersion.dwNLSVersion = dwVersion;
- sortVersion.dwDefinedVersion = dwVersion;
-
- // Invariant must be there and is kinda common, so we'll just get it
- PSORTHANDLE pSort = pGetHandle(W(""), &sortVersion, NULL);
- if (!pSort)
- {
- // Yikes, invariant failed, forget about it.
- ::FreeLibrary(hSort);
- return NULL;
- }
-
- // Since we found it, may as well remember it.
- const SORTHANDLE * const pSortInHash = InsertSortHashNode(pSort);
-
- // If we got a different one back then free the one we added
- if (pSortInHash != pSort && pSortInHash)
- {
- // We got a different one from the hash (someone beat us to the cache)
- // so use that and discard the new one.
- pCloseHandle(pSort);
- }
-
- *ppGetHandle = pGetHandle;
- *ppCloseHandle = pCloseHandle;
- return hSort;
- }
-
- // Attempts to load a Sort DLL. If this fails, the values of the __out parameters are unchanged.
- __success(return)
- BOOL LoadSortDllAndPublish(
- __in LPCWSTR sDllName,
- __in DWORD dwVersion,
- __out __encoded_pointer SORTGETHANDLE* ppGetHandle,
- __out __encoded_pointer SORTCLOSEHANDLE* ppCloseHandle,
- __out HMODULE* phSortDll)
- {
- HMODULE hSortDll;
- SORTGETHANDLE pGetHandle;
- SORTCLOSEHANDLE pCloseHandle;
-
- hSortDll = LoadSortModuleAndInvariant(sDllName, dwVersion, &pGetHandle, &pCloseHandle);
-
- if(hSortDll != NULL) {
- *phSortDll = hSortDll;
- *ppGetHandle = (SORTGETHANDLE)EncodePointer(pGetHandle);
- *ppCloseHandle = (SORTCLOSEHANDLE)EncodePointer(pCloseHandle);
- return TRUE;
- }
-
- return FALSE;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetSortGetHandle()
- //
- // Get the SortGetHandle() function for the proper dll version.
- //
- ////////////////////////////////////////////////////////////////////////////
- SORTGETHANDLE GetSortGetHandle(__in DWORD dwVersion)
- {
- if(dwVersion == SORT_VERSION_DEFAULT)
- {
- // If we haven't tried to load the module/proc before do so now
- if (g_hSortDefault == (HMODULE)-1)
- {
- LoadSortDllAndPublish(SORT_DEFAULT_DLL_NAME, SORT_VERSION_DEFAULT, &g_pDefaultGetHandle, &g_pDefaultCloseHandle, &g_hSortDefault);
- }
-
- // This check is necessary because the LoadSortDllAndPublish call may have failed since some platforms
- // won't have nlssorting.dll (e.g. Windows 8 and above).
- if (g_hSortDefault != (HMODULE)-1)
- {
- return (SORTGETHANDLE)DecodePointer(g_pDefaultGetHandle);
- }
- }
-
- HMODULE* pHSortModule;
- SORTGETHANDLE* ppGetHandle;
- SORTCLOSEHANDLE* ppCloseHandle;
-
- if(dwVersion == SORT_VERSION_V4)
- {
- ppGetHandle = &g_pV4GetHandle;
- ppCloseHandle = &g_pV4CloseHandle;
- pHSortModule = &g_hSortCompatV4;
- }
- else if(dwVersion == SORT_VERSION_WHIDBEY)
- {
- ppGetHandle = &g_pV2GetHandle;
- ppCloseHandle = &g_pV2CloseHandle;
- pHSortModule = &g_hSortCompatV2;
- }
- else
- {
- // Unsupported sorting version.
- return NULL;
- }
-
- if(*pHSortModule == (HMODULE) -1)
- {
- // get module name - the module name should be "Sort"+dwVersion.ToString("x8")+".dll"
- WCHAR moduleName[] = W("Sort00000000.dll");
- // replace the "00000000" with the hexadecimal of dwVersion
- LPCWSTR hex = W("0123456789abcdef");
- WCHAR* p = &moduleName[4+8]; // position at end of number part of dll name
-
- unsigned int value = dwVersion;
-
- while (value != 0 && p != moduleName) {
- int digit = value & 0xF;
- *--p = hex[digit];
- value >>= 4;
- }
-
- if(!LoadSortDllAndPublish(&moduleName[0], dwVersion, ppGetHandle, ppCloseHandle, pHSortModule))
- {
- // We failed to load a versioned sort dll, try to fall back to the current version.
- // If we haven't tried to load the module/proc before do so now
- if (g_hSortDefault == (HMODULE)-1)
- {
- LoadSortDllAndPublish(SORT_DEFAULT_DLL_NAME, SORT_VERSION_DEFAULT, &g_pDefaultGetHandle, &g_pDefaultCloseHandle, &g_hSortDefault);
- }
-
- *pHSortModule = g_hSortDefault;
- *ppCloseHandle = g_pDefaultCloseHandle;
- *ppGetHandle = g_pDefaultGetHandle;
- }
- }
-
- // At this point, we've either loaded a sorting dll or we've exausted all options.
- if(*pHSortModule == (HMODULE) -1)
- {
- // Couldn't find anything, give up.
- return NULL;
- }
- else
- {
- return (SORTGETHANDLE)DecodePointer(*ppGetHandle);
- }
-
- // Unknown version requested
- return NULL;
- }
-
- void DoSortCloseHandle(__in DWORD dwVersion, __in PSORTHANDLE pSort)
- {
- if (dwVersion == SORT_VERSION_DEFAULT)
- {
- SORTCLOSEHANDLE pDefaultCloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pDefaultCloseHandle);
- if(pDefaultCloseHandle != NULL)
- {
- (pDefaultCloseHandle)(pSort);
- return;
- }
- }
-
- if (dwVersion == SORT_VERSION_V4)
- {
- SORTCLOSEHANDLE pV4CloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pV4CloseHandle);
- if(pV4CloseHandle != NULL)
- {
- (pV4CloseHandle)(pSort);
- return;
- }
- }
-
-
- if (dwVersion == SORT_VERSION_WHIDBEY)
- {
- SORTCLOSEHANDLE pV2CloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pV2CloseHandle);
- if(pV2CloseHandle != NULL)
- {
- (pV2CloseHandle)(pSort);
- return;
- }
- }
- }
-
-#else // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
SORTGETHANDLE GetSortGetHandle(__in DWORD dwVersion)
{
{
}
-#endif // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////
DWORD SortNLSVersion()
{
-#ifdef FEATURE_CORECLR
return SORT_VERSION_DEFAULT;
-#else
- static bool sortNLSVersionConfigChecked = false;
- static DWORD sortNLSVersion = SORT_VERSION_DEFAULT;
-
- if(!sortNLSVersionConfigChecked)
- {
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return false);
- sortNLSVersion = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CompatSortNLSVersion);
- if(sortNLSVersion == 0)
- {
- sortNLSVersion = SORT_VERSION_DEFAULT;
- }
- END_SO_INTOLERANT_CODE;
-
- sortNLSVersionConfigChecked = true;
- }
- return sortNLSVersion;
-#endif // !FEATURE_CORECLR
}
////////////////////////////////////////////////////////////////////////////