{
public partial class CompareInfo
{
- private unsafe void InitSort(CultureInfo culture)
+ internal static unsafe IntPtr GetSortHandle(string cultureName)
{
- _sortName = culture.SortName;
-
if (GlobalizationMode.Invariant)
{
- _sortHandle = IntPtr.Zero;
+ return IntPtr.Zero;
}
- else
- {
- const uint LCMAP_SORTHANDLE = 0x20000000;
- IntPtr handle;
- int ret = Interop.Kernel32.LCMapStringEx(_sortName, LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
- _sortHandle = ret > 0 ? handle : IntPtr.Zero;
+ IntPtr handle;
+ int ret = Interop.Kernel32.LCMapStringEx(cultureName, Interop.Kernel32.LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
+ if (ret > 0)
+ {
+ // Even if we can get the sort handle, it is not guaranteed to work when Windows compatibility shim is applied
+ // e.g. Windows 7 compatibility mode. We need to ensure it is working before using it.
+ // otherwise the whole framework app will not start.
+ int hashValue = 0;
+ char a = 'a';
+ ret = Interop.Kernel32.LCMapStringEx(null, Interop.Kernel32.LCMAP_HASH, &a, 1, &hashValue, sizeof(int), null, null, handle);
+ if (ret > 1)
+ {
+ return handle;
+ }
}
+
+ return IntPtr.Zero;
+ }
+
+ private void InitSort(CultureInfo culture)
+ {
+ _sortName = culture.SortName;
+ _sortHandle = GetSortHandle(_sortName);
}
private static unsafe int FindStringOrdinal(
{
private unsafe void FinishInitialization()
{
- if (GlobalizationMode.Invariant)
- {
- _sortHandle = IntPtr.Zero;
- return;
- }
-
- const uint LCMAP_SORTHANDLE = 0x20000000;
-
- IntPtr handle;
- int ret = Interop.Kernel32.LCMapStringEx(_textInfoName, LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
- _sortHandle = ret > 0 ? handle : IntPtr.Zero;
+ _sortHandle = CompareInfo.GetSortHandle(_textInfoName);
}
private unsafe void ChangeCase(char* pSource, int pSourceLen, char* pResult, int pResultLen, bool toUpper)