mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Rework registry handling
This commit is contained in:
parent
4ea51c1cf4
commit
05c7028e1e
5 changed files with 196 additions and 85 deletions
|
@ -81,7 +81,7 @@ public class AppAvCheck {
|
|||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return WindowsRegistry.exists(
|
||||
return WindowsRegistry.local().valueExists(
|
||||
WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Bitdefender", "InstallDir");
|
||||
}
|
||||
},
|
||||
|
@ -93,7 +93,7 @@ public class AppAvCheck {
|
|||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return WindowsRegistry.exists(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Malwarebytes", "id");
|
||||
return WindowsRegistry.local().valueExists(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Malwarebytes", "id");
|
||||
}
|
||||
},
|
||||
MCAFEE("McAfee") {
|
||||
|
@ -104,7 +104,7 @@ public class AppAvCheck {
|
|||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return WindowsRegistry.exists(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\McAfee", "mi");
|
||||
return WindowsRegistry.local().valueExists(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\McAfee", "mi");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -64,11 +64,11 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
|
||||
@Override
|
||||
protected Optional<Path> determineInstallation() {
|
||||
var found = WindowsRegistry.readString(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Notepad++", null);
|
||||
var found = WindowsRegistry.local().readString(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Notepad++", null);
|
||||
|
||||
// Check 32 bit install
|
||||
if (found.isEmpty()) {
|
||||
found = WindowsRegistry.readString(
|
||||
found = WindowsRegistry.local().readString(
|
||||
WindowsRegistry.HKEY_LOCAL_MACHINE, "WOW6432Node\\SOFTWARE\\Notepad++", null);
|
||||
}
|
||||
return found.map(p -> p + "\\notepad++.exe").map(Path::of);
|
||||
|
|
|
@ -85,7 +85,7 @@ public interface TabbyTerminalType extends ExternalTerminalType {
|
|||
|
||||
@Override
|
||||
protected Optional<Path> determineInstallation() {
|
||||
var perUser = WindowsRegistry.readString(
|
||||
var perUser = WindowsRegistry.local().readString(
|
||||
WindowsRegistry.HKEY_CURRENT_USER,
|
||||
"SOFTWARE\\71445fac-d6ef-5436-9da7-5a323762d7f5",
|
||||
"InstallLocation")
|
||||
|
@ -95,7 +95,7 @@ public interface TabbyTerminalType extends ExternalTerminalType {
|
|||
return perUser;
|
||||
}
|
||||
|
||||
var systemWide = WindowsRegistry.readString(
|
||||
var systemWide = WindowsRegistry.local().readString(
|
||||
WindowsRegistry.HKEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\71445fac-d6ef-5436-9da7-5a323762d7f5",
|
||||
"InstallLocation")
|
||||
|
|
|
@ -52,7 +52,7 @@ public interface WezTerminalType extends ExternalTerminalType {
|
|||
@Override
|
||||
protected Optional<Path> determineInstallation() {
|
||||
Optional<String> launcherDir;
|
||||
launcherDir = WindowsRegistry.readString(
|
||||
launcherDir = WindowsRegistry.local().readString(
|
||||
WindowsRegistry.HKEY_LOCAL_MACHINE,
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{BCF6F0DA-5B9A-408D-8562-F680AE6E1EAF}_is1",
|
||||
"InstallLocation")
|
||||
|
|
|
@ -6,103 +6,214 @@ import io.xpipe.core.process.ShellControl;
|
|||
|
||||
import com.sun.jna.platform.win32.Advapi32Util;
|
||||
import com.sun.jna.platform.win32.WinReg;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class WindowsRegistry {
|
||||
public abstract class WindowsRegistry {
|
||||
|
||||
@Value
|
||||
public static class Key {
|
||||
int hkey;
|
||||
String key;
|
||||
}
|
||||
|
||||
public static WindowsRegistry.Local local() {
|
||||
return new Local();
|
||||
}
|
||||
|
||||
public static WindowsRegistry ofShell(ShellControl shellControl) {
|
||||
return shellControl.isLocal() ? local() : new Remote(shellControl);
|
||||
}
|
||||
|
||||
public static final int HKEY_CURRENT_USER = 0x80000001;
|
||||
public static final int HKEY_LOCAL_MACHINE = 0x80000002;
|
||||
|
||||
public static boolean exists(int hkey, String key, String valueName) {
|
||||
// This can fail even with errors in case the jna native library extraction fails
|
||||
try {
|
||||
return Advapi32Util.registryValueExists(
|
||||
hkey == HKEY_LOCAL_MACHINE ? WinReg.HKEY_LOCAL_MACHINE : WinReg.HKEY_CURRENT_USER, key, valueName);
|
||||
} catch (Throwable t) {
|
||||
ErrorEvent.fromThrowable(t).handle();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public abstract boolean keyExists(int hkey, String key) throws Exception;
|
||||
|
||||
public static Optional<String> readString(int hkey, String key) {
|
||||
public abstract boolean valueExists(int hkey, String key, String valueName) throws Exception;
|
||||
|
||||
public abstract Optional<String> readString(int hkey, String key, String valueName) throws Exception;
|
||||
|
||||
public Optional<String> readString(int hkey, String key) throws Exception {
|
||||
return readString(hkey, key, null);
|
||||
}
|
||||
|
||||
public static Optional<String> readString(int hkey, String key, String valueName) {
|
||||
// This can fail even with errors in case the jna native library extraction fails
|
||||
try {
|
||||
if (!Advapi32Util.registryValueExists(
|
||||
hkey == HKEY_LOCAL_MACHINE ? WinReg.HKEY_LOCAL_MACHINE : WinReg.HKEY_CURRENT_USER,
|
||||
key,
|
||||
valueName)) {
|
||||
public abstract Optional<String> findValuesRecursive(int hkey, String key, String valueName) throws Exception;
|
||||
|
||||
public abstract Optional<Key> findKeyForEqualMatchRecursive(int hkey, String key, String match) throws Exception;
|
||||
|
||||
|
||||
public static class Local extends WindowsRegistry {
|
||||
|
||||
private WinReg.HKEY hkey(int hkey) {
|
||||
return hkey == HKEY_LOCAL_MACHINE ? WinReg.HKEY_LOCAL_MACHINE : WinReg.HKEY_CURRENT_USER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyExists(int hkey, String key) throws Exception {
|
||||
// This can fail even with errors in case the jna native library extraction or loading fails
|
||||
try {
|
||||
return Advapi32Util.registryKeyExists(hkey(hkey), key);
|
||||
} catch (Throwable t) {
|
||||
ErrorEvent.fromThrowable(t).handle();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean valueExists(int hkey, String key, String valueName) {
|
||||
// This can fail even with errors in case the jna native library extraction or loading fails
|
||||
try {
|
||||
return Advapi32Util.registryValueExists(hkey(hkey), key, valueName);
|
||||
} catch (Throwable t) {
|
||||
ErrorEvent.fromThrowable(t).handle();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> readString(int hkey, String key, String valueName) {
|
||||
// This can fail even with errors in case the jna native library extraction or loading fails
|
||||
try {
|
||||
if (!Advapi32Util.registryValueExists(
|
||||
hkey(hkey),
|
||||
key,
|
||||
valueName)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.ofNullable(Advapi32Util.registryGetStringValue(hkey(hkey), key, valueName));
|
||||
} catch (Throwable t) {
|
||||
ErrorEvent.fromThrowable(t).handle();
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> findValuesRecursive(int hkey, String key, String valueName) throws Exception {
|
||||
try (var sc = LocalShell.getShell().start()) {
|
||||
return new Remote(sc).findValuesRecursive(hkey, key, valueName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Key> findKeyForEqualMatchRecursive(int hkey, String key, String match) throws Exception {
|
||||
try (var sc = LocalShell.getShell().start()) {
|
||||
return new Remote(sc).findKeyForEqualMatchRecursive(hkey, key, match);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Remote extends WindowsRegistry {
|
||||
|
||||
private final ShellControl shellControl;
|
||||
|
||||
public Remote(ShellControl shellControl) {this.shellControl = shellControl;}
|
||||
|
||||
private String hkey(int hkey) {
|
||||
return hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyExists(int hkey, String key) throws Exception {
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted(hkey(hkey) + "\\" + key)
|
||||
.add("/ve");
|
||||
try (var c = shellControl.command(command).start()) {
|
||||
return c.discardAndCheckExit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean valueExists(int hkey, String key, String valueName) throws Exception {
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted(hkey(hkey) + "\\" + key)
|
||||
.add("/v")
|
||||
.addQuoted(valueName);
|
||||
try (var c = shellControl.command(command).start()) {
|
||||
return c.discardAndCheckExit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> readString(int hkey, String key, String valueName) throws Exception {
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted(hkey(hkey) + "\\" + key)
|
||||
.add("/v")
|
||||
.addQuoted(valueName);
|
||||
|
||||
String output;
|
||||
try (var c = shellControl.command(command).start()) {
|
||||
output = c.readStdoutDiscardErr();
|
||||
if (c.getExitCode() != 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
// Output has the following format:
|
||||
// \n<Version information>\n\n<key>\t<registry type>\t<value>
|
||||
if (output.contains("\t")) {
|
||||
String[] parsed = output.split("\t");
|
||||
return Optional.of(parsed[parsed.length - 1]);
|
||||
}
|
||||
|
||||
if (output.contains(" ")) {
|
||||
String[] parsed = output.split(" ");
|
||||
return Optional.of(parsed[parsed.length - 1]);
|
||||
}
|
||||
|
||||
return Optional.ofNullable(Advapi32Util.registryGetStringValue(
|
||||
hkey == HKEY_LOCAL_MACHINE ? WinReg.HKEY_LOCAL_MACHINE : WinReg.HKEY_CURRENT_USER, key, valueName));
|
||||
} catch (Throwable t) {
|
||||
ErrorEvent.fromThrowable(t).handle();
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean remoteKeyExists(ShellControl shellControl, int hkey, String key) throws Exception {
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted((hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER") + "\\" + key)
|
||||
.add("/ve");
|
||||
try (var c = shellControl.command(command).start()) {
|
||||
return c.discardAndCheckExit();
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<String> findRemoteValuesRecursive(
|
||||
ShellControl shellControl, int hkey, String key, String valueName) throws Exception {
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted((hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER") + "\\" + key)
|
||||
.add("/v")
|
||||
.addQuoted(valueName)
|
||||
.add("/s");
|
||||
try (var c = shellControl.command(command).start()) {
|
||||
var output = c.readStdoutDiscardErr();
|
||||
if (c.getExitCode() != 0) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<String> readRemoteString(ShellControl shellControl, int hkey, String key, String valueName)
|
||||
throws Exception {
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted((hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER") + "\\" + key)
|
||||
.add("/v")
|
||||
.addQuoted(valueName);
|
||||
|
||||
String output;
|
||||
try (var c = shellControl.command(command).start()) {
|
||||
output = c.readStdoutDiscardErr();
|
||||
if (c.getExitCode() != 0) {
|
||||
return Optional.empty();
|
||||
@Override
|
||||
public Optional<String> findValuesRecursive(int hkey, String key, String valueName) throws Exception {
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted(hkey(hkey) + "\\" + key)
|
||||
.add("/v")
|
||||
.addQuoted(valueName)
|
||||
.add("/s");
|
||||
try (var c = shellControl.command(command).start()) {
|
||||
var output = c.readStdoutDiscardErr();
|
||||
if (c.getExitCode() != 0) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output has the following format:
|
||||
// \n<Version information>\n\n<key>\t<registry type>\t<value>
|
||||
if (output.contains("\t")) {
|
||||
String[] parsed = output.split("\t");
|
||||
return Optional.of(parsed[parsed.length - 1]);
|
||||
@Override
|
||||
public Optional<Key> findKeyForEqualMatchRecursive(int hkey, String key, String match) throws Exception {
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted(hkey(hkey) + "\\" + key)
|
||||
.add("/f")
|
||||
.addQuoted(match)
|
||||
.add("/s")
|
||||
.add("/e")
|
||||
.add("/d");
|
||||
try (var c = shellControl.command(command).start()) {
|
||||
var output = c.readStdoutDiscardErr();
|
||||
if (c.getExitCode() != 0) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return output.lines().findFirst().flatMap(s -> {
|
||||
if (s.startsWith("HKEY_CURRENT_USER\\")) {
|
||||
return Optional.of(new Key(HKEY_CURRENT_USER, s.replace("HKEY_CURRENT_USER\\", "")));
|
||||
}
|
||||
if (s.startsWith("HKEY_LOCAL_MACHINE\\")) {
|
||||
return Optional.of(new Key(HKEY_LOCAL_MACHINE, s.replace("HKEY_LOCAL_MACHINE\\", "")));
|
||||
}
|
||||
return Optional.empty();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output.contains(" ")) {
|
||||
String[] parsed = output.split(" ");
|
||||
return Optional.of(parsed[parsed.length - 1]);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue