-
-
Notifications
You must be signed in to change notification settings - Fork 142
fix(windows): set basekeyboard as current user not the admin user on a elevated process. #16162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
65335ec
92643e3
2f4c428
27970c6
9108af2
62dd0de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,29 +11,36 @@ interface | |
| TfrmBaseKeyboard = class(TfrmWebContainer) | ||
| procedure TntFormCreate(Sender: TObject); | ||
| private | ||
| FBaseKeyboardID: Integer; | ||
| procedure Footer_Cancel; | ||
| procedure Footer_OK(params: TStringList); | ||
| protected | ||
| procedure FireCommand(const command: WideString; params: TStringList); override; | ||
| end; | ||
|
|
||
| function ConfigureBaseKeyboard: Boolean; | ||
| function ConfigureBaseKeyboard(out BaseKeyboardID: Integer): Boolean; | ||
| function SetBaseKeyboard(WindowHandle: THandle; BaseKeyboardID: Integer): Boolean; | ||
| function MCompileBaseKeyboard(const BaseKeyboardIDText: string): Boolean; | ||
| function CompileForBaseKeyboard(BaseKeyboardID: Integer): Boolean; | ||
|
|
||
| implementation | ||
|
|
||
| {$R *.dfm} | ||
|
|
||
| uses | ||
| BaseKeyboards, | ||
| kmint; | ||
| ErrorControlledRegistry, | ||
| RegistryKeys, | ||
| keymanapi_TLB, | ||
| kmint, | ||
| utilkmshell; | ||
|
|
||
| function ConfigureBaseKeyboard: Boolean; | ||
| begin | ||
| with TfrmBaseKeyboard.Create(nil) do | ||
| function ConfigureBaseKeyboard(out BaseKeyboardID: Integer): Boolean; | ||
| begin with TfrmBaseKeyboard.Create(nil) do | ||
| try | ||
| Result := ShowModal = mrOk; | ||
| if Result then | ||
| kmcom.Apply; | ||
| BaseKeyboardID := FBaseKeyboardID; | ||
| finally | ||
| Free; | ||
| end; | ||
|
|
@@ -65,9 +72,74 @@ procedure TfrmBaseKeyboard.Footer_OK(params: TStringList); | |
| v: Integer; | ||
| begin | ||
| if not TryStrToInt('$'+params.Values['id'], v) then Exit; | ||
| kmcom.Options['koBaseLayout'].Value := v; | ||
| kmcom.Options.Apply; | ||
| FBaseKeyboardID := v; | ||
| ModalResult := mrOk; | ||
| end; | ||
|
|
||
| function MCompileBaseKeyboard(const BaseKeyboardIDText: string): Boolean; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should move this into its own unit
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This has changed a fair bit since this comment is it still valid. However, looking at it these 3 functions could be in there own unit around "Setting Base Keyboard" and are not tightly coupled to a form. |
||
| var | ||
| BaseKeyboardID: Integer; | ||
| begin | ||
| Result := False; | ||
| if not TryStrToInt('$' + BaseKeyboardIDText, BaseKeyboardID) or | ||
| not kmcom.SystemInfo.IsAdministrator then | ||
| Exit; | ||
| Result := CompileForBaseKeyboard(BaseKeyboardID); | ||
| end; | ||
|
|
||
| function BaseKeyboardNeedsMCompile(BaseKeyboardID: Integer): Boolean; | ||
| var | ||
| I: Integer; | ||
| Keyboard: IKeymanKeyboardInstalled; | ||
| BaseFileName: string; | ||
| BaseKeyboardIDHex: string; | ||
| begin | ||
| BaseKeyboardIDHex := IntToHex(BaseKeyboardID, 8); | ||
| for I := 0 to kmcom.Keyboards.Count - 1 do | ||
| begin | ||
| Keyboard := kmcom.Keyboards.Items[I]; | ||
| BaseFileName := Keyboard.Filename; | ||
| if FileExists(BaseFileName) and | ||
| (not FileExists(ChangeFileExt(BaseFileName, '') + '-' + BaseKeyboardIDHex + '.kmx') or | ||
| not FileExists(ChangeFileExt(BaseFileName, '') + '-' + BaseKeyboardIDHex + '-d.kmx')) then | ||
| Exit(True); | ||
| end; | ||
| Result := False; | ||
| end; | ||
|
|
||
| function SetBaseKeyboard(WindowHandle: THandle; BaseKeyboardID: Integer): Boolean; | ||
| var | ||
| MCompileResult: Boolean; | ||
| begin | ||
| MCompileResult := True; | ||
| Result := False; | ||
| if BaseKeyboardNeedsMCompile(BaseKeyboardID) then | ||
| begin | ||
| if not kmcom.SystemInfo.IsAdministrator then | ||
| begin | ||
| MCompileResult := WaitForElevatedConfiguration(WindowHandle, '-mcompilekbds ' + IntToHex(BaseKeyboardID, 8)) = 0; | ||
| end | ||
| else | ||
| MCompileResult := CompileForBaseKeyboard(BaseKeyboardID); | ||
| end; | ||
| if not MCompileResult then | ||
| Exit; | ||
|
|
||
| kmcom.Options['koBaseLayout'].Value := BaseKeyboardID; | ||
| kmcom.Options.Apply; | ||
| Result := True; | ||
| end; | ||
|
|
||
| function CompileForBaseKeyboard(BaseKeyboardID: Integer): Boolean; | ||
| var | ||
| i: Integer; | ||
| kbd: IKeymanKeyboardInstalled; | ||
| begin | ||
| for i := 0 to kmcom.Keyboards.Count - 1 do | ||
| begin | ||
| kbd := kmcom.Keyboards[i]; | ||
| (kbd as IKeymanKeyboardInstalled2).MCompileForBaseKeyboard(BaseKeyboardID); | ||
| end; | ||
| end; | ||
|
|
||
| end. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,7 +63,8 @@ TKeymanKeyboardInstalled = class; | |
| TKeymanKeyboardInstalled = class( // I3581 | ||
| TKeymanKeyboard, | ||
| IIntKeymanKeyboardInstalled, | ||
| IKeymanKeyboardInstalled) | ||
| IKeymanKeyboardInstalled, | ||
| IKeymanKeyboardInstalled2) | ||
| private | ||
| FRegKeyboard: TRegKeyboard; | ||
| FVisualKeyboard: IKeymanVisualKeyboard; | ||
|
|
@@ -112,6 +113,9 @@ TKeymanKeyboardInstalled = class( // I3581 | |
| procedure UpdateBaseLayout; // I4169 | ||
| procedure RefreshInstallation; | ||
|
|
||
| { IKeymanKeyboardInstalled2 } | ||
| procedure MCompileForBaseKeyboard(KLID: Integer); safecall; | ||
|
|
||
| public | ||
| constructor Create(AContext: TKeymanContext; const Name: string); | ||
| destructor Destroy; override; | ||
|
|
@@ -152,14 +156,19 @@ procedure TKeymanKeyboardInstalled.Uninstall; | |
| end; | ||
|
|
||
| procedure TKeymanKeyboardInstalled.UpdateBaseLayout; // I4169 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could now be removed |
||
| var | ||
| BaseKeyboardID: Integer; | ||
| begin | ||
| if FRegKeyboard.MnemonicLayout and FileExists(FRegKeyboard.KeymanFile) then // I4615 | ||
| begin | ||
| BaseKeyboardID := (Context.Options as IKeymanOptions).Items['koBaseLayout'].Value; | ||
|
rc-swag marked this conversation as resolved.
|
||
| with TKPRecompileMnemonicKeyboard.Create(Context) do | ||
| try | ||
| Execute(FRegKeyboard.KeymanFile, FRegKeyboard.PackageName); | ||
| Execute(FRegKeyboard.KeymanFile, FRegKeyboard.PackageName, BaseKeyboardID); | ||
| finally | ||
| Free; | ||
| end; | ||
| end; | ||
| end; | ||
|
|
||
| function TKeymanKeyboardInstalled.Get_Copyright: WideString; | ||
|
|
@@ -471,5 +480,21 @@ function TKeymanKeyboardInstalled.RegKeyboard: TRegKeyboard; | |
| Result := FRegKeyboard; | ||
| end; | ||
|
|
||
| { IKeymanKeyboardInstalled2 } | ||
| procedure TKeymanKeyboardInstalled.MCompileForBaseKeyboard(KLID: Integer); safecall; | ||
| var | ||
| RecompileMnemonicKeyboard: TKPRecompileMnemonicKeyboard; | ||
| begin | ||
| if FRegKeyboard.MnemonicLayout and FileExists(FRegKeyboard.KeymanFile) then | ||
| begin | ||
| RecompileMnemonicKeyboard := TKPRecompileMnemonicKeyboard.Create(Context); | ||
| try | ||
| RecompileMnemonicKeyboard.Execute(FRegKeyboard.KeymanFile, FRegKeyboard.PackageName, KLID); | ||
| finally | ||
| RecompileMnemonicKeyboard.Free; | ||
| end; | ||
| end; | ||
| end; | ||
|
|
||
| end. | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,6 +125,7 @@ procedure TKPInstallKeyboard.Execute(const FileName, PackageID: string; FInstall | |
| FExitCode: Integer; | ||
| FKVKName: WideString; | ||
| FCreatedIcon: Boolean; | ||
| BaseKeyboardID: Integer; | ||
| begin | ||
| KL.MethodEnter(Self, 'Execute', [FileName,PackageID,ikPartOfPackage in FInstallOptions ,Force]); | ||
| try | ||
|
|
@@ -248,9 +249,11 @@ procedure TKPInstallKeyboard.Execute(const FileName, PackageID: string; FInstall | |
| // Recompile a mnemonic layout to the user's selected base layout | ||
| if ki.MnemonicLayout then // I4169 | ||
| begin | ||
| with Context as TKeymanContext do | ||
| BaseKeyboardID := (Options as IKeymanOptions).Items['koBaseLayout'].Value; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will this still get the admin value of base layout? do we need to be able to pass baselayout as a param to elevated kmshell?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm yes I think we do. I just realised I have it resolved this case where it is on the install of new keyboard. We need get the users baselayout |
||
| with TKPRecompileMnemonicKeyboard.Create(Context) do | ||
| try | ||
| Execute(FDestFileName, PackageID); | ||
| Execute(FDestFileName, PackageID, BaseKeyboardID); | ||
| finally | ||
| Free; | ||
| end; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.