mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-09 18:35:32 +00:00
Fixes #1285. If running Windows 10 19597 or later, the underlying issue has been addressed, so disable the mitigation for new installs of the keyboard. Does not attempt to change the language code if the keyboard is already installed.
124 lines
4 KiB
ObjectPascal
124 lines
4 KiB
ObjectPascal
// See discussion online at https://github.com/keymanapp/keyman/issues/1285
|
|
// Introduced in Keyman 11. Back ported to Keyman 10. If Microsoft introduces
|
|
// a fix in a later release, we will need to update this to turn the mitigation
|
|
// off for that version. In that situation, users will need to reinstall their
|
|
// language profile in order to get the corrected language.
|
|
unit Keyman.System.MitigateWin10_1803LanguageInstall;
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows;
|
|
|
|
type
|
|
TMitigateWin10_1803 = class
|
|
type
|
|
TLanguageReference = record
|
|
Code: LANGID;
|
|
BCP47: string;
|
|
Name: string;
|
|
end;
|
|
|
|
TMitigatedLanguage = record
|
|
OriginalLanguage: TLanguageReference;
|
|
NewLanguage: TLanguageReference;
|
|
end;
|
|
|
|
class function IsMitigationRequired(Code: LANGID; var lang: TMitigateWin10_1803.TMitigatedLanguage): Boolean; overload;
|
|
class function IsMitigationRequired(BCP47Tag: string; var lang: TMitigateWin10_1803.TMitigatedLanguage): Boolean; overload;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.SysUtils;
|
|
|
|
const
|
|
MitigatedLanguages: array[0..2] of TMitigateWin10_1803.TMitigatedLanguage = (
|
|
(OriginalLanguage: (Code: $005E; BCP47: 'am'; Name: 'Amharic'); NewLanguage: (BCP47: 'gez-Ethi-ET'; Name: 'Geez')),
|
|
(OriginalLanguage: (Code: $0073; BCP47: 'ti'; Name: 'Tigrinya'); NewLanguage: (BCP47: 'gez-Ethi-ET'; Name: 'Geez')),
|
|
(OriginalLanguage: (Code: $005B; BCP47: 'si'; Name: 'Sinhala'); NewLanguage: (Code: $0409; Name: 'English (US)'))
|
|
);
|
|
|
|
{ TMitigateWin10_1803 }
|
|
|
|
const
|
|
WINDOWS_10_MAJORVERSION = 10;
|
|
WINDOWS_10_MINORVERSION = 0;
|
|
WINDOWS_10_BUILDNUMBER_WithFailure = 17134;
|
|
WINDOWS_10_BUILDNUMBER_Fixed = 19597;
|
|
|
|
function IsWindows10_OrGreater_Build(Build: DWORD): BOOL; inline;
|
|
var
|
|
osvi: OSVERSIONINFOEXW;
|
|
dwlConditionMask: DWORDLONG;
|
|
begin
|
|
// Code pattern comes from Keyman.Winapi.VersionHelpers, but testing also
|
|
// build number so cannot use functions already there. This also makes back-porting
|
|
// to Keyman 10 simpler.
|
|
FillChar(osvi, SizeOf(osvi), 0);
|
|
osvi.dwOSVersionInfoSize := SizeOf(osvi);
|
|
dwlConditionMask := VerSetConditionMask(
|
|
VerSetConditionMask(
|
|
VerSetConditionMask(
|
|
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
|
|
VER_MINORVERSION, VER_GREATER_EQUAL),
|
|
VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
|
|
|
osvi.dwMajorVersion := WINDOWS_10_MAJORVERSION;
|
|
osvi.dwMinorVersion := WINDOWS_10_MINORVERSION;
|
|
osvi.dwBuildNumber := Build;
|
|
|
|
Result := VerifyVersionInfoW(osvi, VER_MAJORVERSION or VER_MINORVERSION or VER_BUILDNUMBER, dwlConditionMask) <> False;
|
|
end;
|
|
|
|
class function TMitigateWin10_1803.IsMitigationRequired(Code: LANGID; var lang: TMitigateWin10_1803.TMitigatedLanguage): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not IsWindows10_OrGreater_Build(WINDOWS_10_BUILDNUMBER_WithFailure) then
|
|
Exit(False);
|
|
|
|
if IsWindows10_OrGreater_Build(WINDOWS_10_BUILDNUMBER_Fixed) then
|
|
Exit(False);
|
|
|
|
Code := PRIMARYLANGID(Code);
|
|
for I := Low(MitigatedLanguages) to High(MitigatedLanguages) do
|
|
if MitigatedLanguages[I].OriginalLanguage.Code = Code then
|
|
begin
|
|
lang := MitigatedLanguages[I];
|
|
Exit(True);
|
|
end;
|
|
// lang value undefined.
|
|
Result := False;
|
|
end;
|
|
|
|
class function TMitigateWin10_1803.IsMitigationRequired(BCP47Tag: string;
|
|
var lang: TMitigateWin10_1803.TMitigatedLanguage): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not IsWindows10_OrGreater_Build(WINDOWS_10_BUILDNUMBER_WithFailure) then
|
|
Exit(False);
|
|
|
|
if IsWindows10_OrGreater_Build(WINDOWS_10_BUILDNUMBER_Fixed) then
|
|
Exit(False);
|
|
|
|
// We only want to look at the primary language tag for comparison
|
|
// And we assume that the tag has been canonicalized from ISO639-3 first
|
|
BCP47Tag := LowerCase(BCP47Tag);
|
|
I := Pos('-', BCP47Tag);
|
|
if I > 0 then
|
|
BCP47Tag := Copy(BCP47Tag, 1, I-1);
|
|
|
|
for I := Low(MitigatedLanguages) to High(MitigatedLanguages) do
|
|
if MitigatedLanguages[I].OriginalLanguage.BCP47 = BCP47Tag then
|
|
begin
|
|
lang := MitigatedLanguages[I];
|
|
Exit(True);
|
|
end;
|
|
// lang value undefined.
|
|
Result := False;
|
|
end;
|
|
|
|
end.
|