Skip to content

Commit

Permalink
Clean-up WindowsDefenderConfigurator after subsequent check refinements
Browse files Browse the repository at this point in the history
Also rename 'Windows Defender' to 'Microsoft Defender' in texts and
labels since it is now branded as such.
  • Loading branch information
HannesWell committed Mar 22, 2024
1 parent dd5068c commit b7b8593
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 43 deletions.
Expand Up @@ -21,6 +21,7 @@
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
Expand All @@ -29,6 +30,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IProduct;
Expand Down Expand Up @@ -156,27 +158,23 @@ private static Boolean runExclusionCheck(IProgressMonitor m, Optional<Path> inst
}
Display display = Display.getDefault();
HandlingOption decision = askForDefenderHandlingDecision(display);
if (decision != null) {
switch (decision) {
case EXECUTE_EXCLUSION -> {
if (isExclusionTamperProtectionEnabled(monitor.split(1))) {
display.syncExec(() -> MessageDialog.openError(null, "Exclusion failed", //$NON-NLS-1$
bindProductName(WorkbenchMessages.WindowsDefenderConfigurator_exclusionFailed_Protected)));
savePreference(ConfigurationScope.INSTANCE, PREFERENCE_STARTUP_CHECK_SKIP, "true"); //$NON-NLS-1$
return null; // Consider selection as 'aborted' and don't show the dialog again on startup
}
try {
WindowsDefenderConfigurator.excludeDirectoryFromScanning(monitor.split(2));
savePreference(ConfigurationScope.INSTANCE, PREFERENCE_EXCLUDED_INSTALLATION_PATH,
installLocation.map(Path::toString).orElse("")); //$NON-NLS-1$
} catch (IOException e) {
display.syncExec(() -> MessageDialog.openError(null, "Exclusion failed", //$NON-NLS-1$
bindProductName(WorkbenchMessages.WindowsDefenderConfigurator_exclusionFailed)));
}
if (decision == HandlingOption.EXECUTE_EXCLUSION) {
if (isExclusionTamperProtectionEnabled(monitor.split(1))) {
display.syncExec(() -> MessageDialog.openError(null, "Exclusion failed", //$NON-NLS-1$
bindProductName(WorkbenchMessages.WindowsDefenderConfigurator_exclusionFailed_Protected)));
savePreference(ConfigurationScope.INSTANCE, PREFERENCE_STARTUP_CHECK_SKIP, "true"); //$NON-NLS-1$
return null; // Consider selection as 'aborted' and don't show the dialog again on startup
}
case IGNORE_THIS_INSTALLATION -> savePreference(ConfigurationScope.INSTANCE, PREFERENCE_STARTUP_CHECK_SKIP,
"true"); //$NON-NLS-1$
try {
WindowsDefenderConfigurator.excludeDirectoryFromScanning(monitor.split(2));
savePreference(ConfigurationScope.INSTANCE, PREFERENCE_EXCLUDED_INSTALLATION_PATH,
installLocation.map(Path::toString).orElse("")); //$NON-NLS-1$
} catch (IOException e) {
display.syncExec(() -> MessageDialog.openError(null, "Exclusion failed", //$NON-NLS-1$
bindProductName(WorkbenchMessages.WindowsDefenderConfigurator_exclusionFailed)));
}
} else if (decision == HandlingOption.IGNORE_THIS_INSTALLATION) {
savePreference(ConfigurationScope.INSTANCE, PREFERENCE_STARTUP_CHECK_SKIP, "true"); //$NON-NLS-1$
}
return decision == HandlingOption.EXECUTE_EXCLUSION ? Boolean.TRUE : null;
}
Expand Down Expand Up @@ -285,9 +283,8 @@ private static List<Path> getExecutablePath() {
private static boolean isExclusionTamperProtectionEnabled(IProgressMonitor monitor) {
// https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/manage-tamper-protection-intune?view=o365-worldwide#how-to-determine-whether-antivirus-exclusions-are-tamper-protected-on-a-windows-device
try { // Query the Windows Registry
List<String> result = runProcess(List.of("powershell.exe", "-Command", //$NON-NLS-1$//$NON-NLS-2$
"Get-ItemPropertyValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows Defender\\Features' -Name 'TPExclusions'"), //$NON-NLS-1$
monitor);
List<String> result = runPowershell(monitor, "-Command", //$NON-NLS-1$
"Get-ItemPropertyValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows Defender\\Features' -Name 'TPExclusions'"); //$NON-NLS-1$
return result.size() == 1 && "1".equals(result.get(0)); //$NON-NLS-1$
} catch (IOException e) {
return false;
Expand All @@ -298,8 +295,7 @@ private static boolean isWindowsDefenderServiceRunning(IProgressMonitor monitor)
// https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-service?view=powershell-7.4
// https://learn.microsoft.com/en-us/dotnet/api/system.serviceprocess.servicecontrollerstatus?view=dotnet-plat-ext-8.0
try {
List<String> result = runProcess(List.of("powershell.exe", "-Command", "(Get-Service 'WinDefend').Status"), //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
monitor);
List<String> result = runPowershell(monitor, "-Command", "(Get-Service 'WinDefend').Status"); //$NON-NLS-1$ //$NON-NLS-2$
return result.size() == 1 && "Running".equalsIgnoreCase(result.get(0)); //$NON-NLS-1$
} catch (IOException e) {
ILog.get().error("Failed to obtain 'WinDefend' service state", e); //$NON-NLS-1$
Expand All @@ -308,10 +304,9 @@ private static boolean isWindowsDefenderServiceRunning(IProgressMonitor monitor)
}

private static boolean isWindowsDefenderActive(IProgressMonitor monitor) throws CoreException {
// https://learn.microsoft.com/en-us/powershell/module/defender/get-mpcomputerstatus
List<String> command = List.of("powershell.exe", "-Command", "(Get-MpComputerStatus).AMRunningMode"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
// https://learn.microsoft.com/en-us/powershell/module/defender/get-mpcomputerstatus?view=windowsserver2019-ps
try {
List<String> lines = runProcess(command, monitor);
List<String> lines = runPowershell(monitor, "-Command", "(Get-MpComputerStatus).AMRunningMode"); //$NON-NLS-1$ //$NON-NLS-2$
String onlyLine = lines.size() == 1 ? lines.get(0) : ""; //$NON-NLS-1$
return switch (onlyLine) {
// Known values as listed in
Expand All @@ -329,8 +324,8 @@ public static String createAddExclusionsPowershellCommand(String extraSeparator)
List<Path> paths = getExecutablePath();
// For detailed explanations about how to read existing exclusions and how to
// add new ones see:
// https://learn.microsoft.com/en-us/powershell/module/defender/add-mppreference
// https://learn.microsoft.com/en-us/powershell/module/defender/get-mppreference
// https://learn.microsoft.com/en-us/powershell/module/defender/add-mppreference?view=windowsserver2019-ps
// https://learn.microsoft.com/en-us/powershell/module/defender/get-mppreference?view=windowsserver2019-ps
//
// For .NET's stream API called LINQ see:
// https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable
Expand All @@ -351,7 +346,7 @@ private static void excludeDirectoryFromScanning(IProgressMonitor monitor) throw
// a second one with elevated rights is started and runs the
// add-exclusions-command. For a detailed explanation of the Start-process
// parameters see
// https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process#parameters
// https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-7.4#parameters
//
// In order to avoid quoting when passing a command through multiple
// process-calls/command line processors, the command is passed as
Expand All @@ -360,11 +355,13 @@ private static void excludeDirectoryFromScanning(IProgressMonitor monitor) throw
// https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe#-encodedcommand-base64encodedcommand
String encodedCommand = Base64.getEncoder()
.encodeToString(exclusionsCommand.getBytes(StandardCharsets.UTF_16LE)); // encoding as specified
List<String> command = List.of("powershell.exe", //$NON-NLS-1$
// Launch child powershell with administrator privileges
runPowershell(monitor, // Launch child powershell with administrator privileges
"Start-Process", "powershell", "-Verb", "RunAs", "-Wait", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
"-ArgumentList", "'-EncodedCommand " + encodedCommand + "'"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
runProcess(command, monitor);
}

private static List<String> runPowershell(IProgressMonitor monitor, String... arguments) throws IOException {
return runProcess(Stream.concat(Stream.of("powershell.exe"), Arrays.stream(arguments)).toList(), monitor); //$NON-NLS-1$
}

private static List<String> runProcess(List<String> command, IProgressMonitor monitor) throws IOException {
Expand Down
Expand Up @@ -568,25 +568,25 @@ CheckedTreeSelectionDialog_nothing_available=No entries available.
CheckedTreeSelectionDialog_select_all=Select &All
CheckedTreeSelectionDialog_deselect_all=&Deselect All

WindowsDefenderConfigurator_statusCheck=Windows Defender Exclusion Check
WindowsDefenderConfigurator_exclusionCheckMessage=Microsoft''s Windows Defender is active and could significantly decrease the startup and overall performance of {0}.\n\
Select how this installation should be handled by Windows Defender:
WindowsDefenderConfigurator_exclusionInformation=If Windows Defender is active and scans {0} it can significantly slow down its startup and overall performance.\n\
To prevent a decrease in performance {0} can exclude itself and all files opened from real-time scanning by Windows Defender.\n\
WindowsDefenderConfigurator_statusCheck=Microsoft Defender Exclusion Check
WindowsDefenderConfigurator_exclusionCheckMessage=Microsoft Windows Defender is active and could significantly decrease the startup and overall performance of {0}.\n\
Select how this installation should be handled by Microsoft Defender:
WindowsDefenderConfigurator_exclusionInformation=If Microsoft Defender is active on Windows 10 or later and scans {0} it can significantly slow down its startup and overall performance.\n\
To prevent a decrease in performance {0} can exclude its process and consequently all files touched by it from real-time scanning by the Defender.\n\
Be aware that in general adding exclusions could affect this computer''s security.
WindowsDefenderConfigurator_scriptShowLabel=Show Powershell script >>
WindowsDefenderConfigurator_scriptHideLabel=<< Hide Powershell script
WindowsDefenderConfigurator_scriptHint=Adding exclusions respectively running the Powershell script to do it requires administrator privileges.
WindowsDefenderConfigurator_performExclusionChoice=Exclude {0} from being scanned to improve performance.\n\
(In general adding exclusions may affect the security level of this computer)
WindowsDefenderConfigurator_ignoreThisInstallationChoice=Keep {0} being scanned by Windows Defender.
WindowsDefenderConfigurator_ignoreThisInstallationChoice=Keep {0} being scanned by Microsoft Defender.
WindowsDefenderConfigurator_ignoreAllChoice=Skip exclusion check on startup for all new Eclipse-based installations
WindowsDefenderConfigurator_detailsAndOptionsLinkText=See '<a>Startup and Shutdown</a>' preference for more details and configuration options.
WindowsDefenderConfigurator_runExclusionFromPreferenceButtonLabel=Run exclusion check now
WindowsDefenderConfigurator_statusInactive=Windows Defender is not active on this computer.
WindowsDefenderConfigurator_statusCheckFailed=Failed to retrieve Windows Defender status.
WindowsDefenderConfigurator_exclusionFailed=Failed to exclude {0} from being scanned by Windows Defender.
WindowsDefenderConfigurator_exclusionFailed_Protected=Cannot exclude {0} from being scanned by Windows Defender.\nTamper protection for antivirus exclusions is enabled.
WindowsDefenderConfigurator_statusInactive=Microsoft Defender is not active on this computer.
WindowsDefenderConfigurator_statusCheckFailed=Failed to retrieve Microsoft Defender status.
WindowsDefenderConfigurator_exclusionFailed=Failed to exclude {0} from being scanned by Microsoft Defender.
WindowsDefenderConfigurator_exclusionFailed_Protected=Cannot exclude {0} from being scanned by Microsoft Defender.\nTamper protection for antivirus exclusions is enabled.

# ==============================================================================
# Editor Framework
Expand Down

0 comments on commit b7b8593

Please sign in to comment.