Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 0fca828

Browse files
authored
Port The Fix When Enabling Windows Compatibilty Mode (#26805)
1 parent 82f0216 commit 0fca828

File tree

3 files changed

+31
-24
lines changed

3 files changed

+31
-24
lines changed

src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Globalization.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ internal static unsafe partial class Kernel32
2424
internal const uint LOCALE_RETURN_NUMBER = 0x20000000;
2525
internal const uint LOCALE_NOUSEROVERRIDE = 0x80000000;
2626

27+
internal const uint LCMAP_SORTHANDLE = 0x20000000;
28+
internal const uint LCMAP_HASH = 0x00040000;
29+
2730
internal const int COMPARE_STRING = 0x0001;
2831

2932
internal const uint TIME_NOSECONDS = 0x00000002;
@@ -115,7 +118,7 @@ internal static extern unsafe bool IsNLSDefinedString(
115118

116119
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
117120
internal static extern bool EnumTimeFormatsEx(EnumTimeFormatsProcEx lpTimeFmtEnumProcEx, string lpLocaleName, uint dwFlags, void* lParam);
118-
121+
119122
internal delegate BOOL EnumTimeFormatsProcEx(char* lpTimeFormatString, void* lParam);
120123

121124
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
@@ -126,7 +129,7 @@ internal static extern unsafe bool IsNLSDefinedString(
126129

127130
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
128131
internal static extern bool EnumCalendarInfoExEx(EnumCalendarInfoProcExEx pCalInfoEnumProcExEx, string lpLocaleName, uint Calendar, string? lpReserved, uint CalType, void* lParam);
129-
132+
130133
internal delegate BOOL EnumCalendarInfoProcExEx(char* lpCalendarInfoString, uint Calendar, IntPtr lpReserved, void* lParam);
131134

132135
[StructLayout(LayoutKind.Sequential)]
@@ -138,7 +141,7 @@ internal struct NlsVersionInfoEx
138141
internal int dwEffectiveId;
139142
internal Guid guidCustomVersion;
140143
}
141-
144+
142145
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
143146
internal static extern unsafe bool GetNLSVersionEx(int function, string localeName, NlsVersionInfoEx* lpVersionInformation);
144147
}

src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Windows.cs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,36 @@ namespace System.Globalization
1212
{
1313
public partial class CompareInfo
1414
{
15-
private unsafe void InitSort(CultureInfo culture)
15+
internal static unsafe IntPtr GetSortHandle(string cultureName)
1616
{
17-
_sortName = culture.SortName;
18-
1917
if (GlobalizationMode.Invariant)
2018
{
21-
_sortHandle = IntPtr.Zero;
19+
return IntPtr.Zero;
2220
}
23-
else
24-
{
25-
const uint LCMAP_SORTHANDLE = 0x20000000;
2621

27-
IntPtr handle;
28-
int ret = Interop.Kernel32.LCMapStringEx(_sortName, LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
29-
_sortHandle = ret > 0 ? handle : IntPtr.Zero;
22+
IntPtr handle;
23+
int ret = Interop.Kernel32.LCMapStringEx(cultureName, Interop.Kernel32.LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
24+
if (ret > 0)
25+
{
26+
// Even if we can get the sort handle, it is not guaranteed to work when Windows compatibility shim is applied
27+
// e.g. Windows 7 compatibility mode. We need to ensure it is working before using it.
28+
// otherwise the whole framework app will not start.
29+
int hashValue = 0;
30+
char a = 'a';
31+
ret = Interop.Kernel32.LCMapStringEx(null, Interop.Kernel32.LCMAP_HASH, &a, 1, &hashValue, sizeof(int), null, null, handle);
32+
if (ret > 1)
33+
{
34+
return handle;
35+
}
3036
}
37+
38+
return IntPtr.Zero;
39+
}
40+
41+
private void InitSort(CultureInfo culture)
42+
{
43+
_sortName = culture.SortName;
44+
_sortHandle = GetSortHandle(_sortName);
3145
}
3246

3347
private static unsafe int FindStringOrdinal(

src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Windows.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,7 @@ public partial class TextInfo
1010
{
1111
private unsafe void FinishInitialization()
1212
{
13-
if (GlobalizationMode.Invariant)
14-
{
15-
_sortHandle = IntPtr.Zero;
16-
return;
17-
}
18-
19-
const uint LCMAP_SORTHANDLE = 0x20000000;
20-
21-
IntPtr handle;
22-
int ret = Interop.Kernel32.LCMapStringEx(_textInfoName, LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
23-
_sortHandle = ret > 0 ? handle : IntPtr.Zero;
13+
_sortHandle = CompareInfo.GetSortHandle(_textInfoName);
2414
}
2515

2616
private unsafe void ChangeCase(char* pSource, int pSourceLen, char* pResult, int pResultLen, bool toUpper)

0 commit comments

Comments
 (0)