Skip to content

Commit 08b93b4

Browse files
authored
Added Windows Service optimization to Harden System Security (#1119)
Added a new section to the Service Manager in the Harden System Security app that offers a quick and easy way to optimize your system by disabling and stopping services that are rarely used.
1 parent 220d37e commit 08b93b4

4 files changed

Lines changed: 228 additions & 40 deletions

File tree

Harden System Security/Pages/ServiceManager.xaml

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,69 @@
124124
</DataTemplate>
125125
</ToggleButton.ContentTemplate>
126126
</ToggleButton>
127+
128+
<!-- Optimize Services Flyout -->
129+
<Button VerticalAlignment="Center"
130+
x:Uid="OptimizeServicesButton"
131+
IsEnabled="{x:Bind ViewModel.AreElementsEnabled, Mode=OneWay}">
132+
<Button.ContentTemplate>
133+
<DataTemplate x:DataType="x:String">
134+
<StackPanel Orientation="Horizontal" Spacing="8">
135+
<FontIcon Glyph="&#xEC4A;" FontSize="16"/>
136+
<TextBlock Text="{x:Bind}"/>
137+
</StackPanel>
138+
</DataTemplate>
139+
</Button.ContentTemplate>
140+
<Button.Flyout>
141+
<Flyout Placement="BottomEdgeAlignedLeft">
142+
<Grid Width="380">
143+
<Grid.RowDefinitions>
144+
<RowDefinition Height="Auto"/>
145+
<RowDefinition Height="Auto"/>
146+
<RowDefinition Height="*"/>
147+
</Grid.RowDefinitions>
148+
149+
<TextBlock Grid.Row="0" x:Uid="RecommendedServices" Style="{StaticResource SubtitleTextBlockStyle}" Margin="0,0,0,12"/>
150+
151+
<Button Grid.Row="1" x:Uid="StopAndDisableAllRecommendedServicesButton" HorizontalAlignment="Stretch" Margin="0,0,0,12" Click="{x:Bind ViewModel.DisableAndStopAllRecommendedServices_Click}">
152+
<Button.ContentTemplate>
153+
<DataTemplate x:DataType="x:String">
154+
<StackPanel Orientation="Horizontal" Spacing="8" HorizontalAlignment="Center">
155+
<FontIcon Glyph="&#xE71A;" FontSize="14" Foreground="{ThemeResource SystemFillColorCriticalBrush}"/>
156+
<TextBlock Text="{x:Bind}"/>
157+
</StackPanel>
158+
</DataTemplate>
159+
</Button.ContentTemplate>
160+
</Button>
161+
162+
<ScrollViewer Grid.Row="2" MaxHeight="400" VerticalScrollBarVisibility="Auto" Padding="0,0,8,0">
163+
<ItemsControl ItemsSource="{x:Bind ViewModel.RecommendedServices, Mode=OneWay}">
164+
<ItemsControl.ItemTemplate>
165+
<DataTemplate x:DataType="vm:RecommendedService">
166+
<Border Margin="0,0,0,8" Padding="12" CornerRadius="8" BorderThickness="1" BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}" Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}">
167+
<Grid ColumnSpacing="12">
168+
<Grid.ColumnDefinitions>
169+
<ColumnDefinition Width="*"/>
170+
<ColumnDefinition Width="Auto"/>
171+
</Grid.ColumnDefinitions>
172+
<StackPanel Grid.Column="0" Spacing="4" VerticalAlignment="Center">
173+
<TextBlock Text="{x:Bind DisplayName}" Style="{StaticResource BodyStrongTextBlockStyle}"/>
174+
<TextBlock Text="{x:Bind Description}" Style="{StaticResource CaptionTextBlockStyle}" Foreground="{ThemeResource TextFillColorSecondaryBrush}" TextWrapping="Wrap"/>
175+
</StackPanel>
176+
<Button Grid.Column="1" VerticalAlignment="Center" Tag="{x:Bind}" Click="{x:Bind vm:ViewModelProvider.ServiceManagerVM.DisableAndStopRecommendedService_Click}" x:Uid="StopAndDisableServiceButton">
177+
<FontIcon Glyph="&#xE71A;" Foreground="{ThemeResource SystemFillColorCriticalBrush}"/>
178+
</Button>
179+
</Grid>
180+
</Border>
181+
</DataTemplate>
182+
</ItemsControl.ItemTemplate>
183+
</ItemsControl>
184+
</ScrollViewer>
185+
</Grid>
186+
</Flyout>
187+
</Button.Flyout>
188+
</Button>
189+
127190
</StackPanel>
128191
</Border>
129192

@@ -354,7 +417,7 @@
354417
</Grid.ColumnDefinitions>
355418

356419
<!-- Column 0: Service Name -->
357-
<TextBlock Grid.Column="0" Text="{x:Bind Item.ServiceName}" Style="{StaticResource BodyStrongTextBlockStyle}" VerticalAlignment="Center" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" ToolTipService.ToolTip="{x:Bind Item.ServiceName}"/>
420+
<TextBlock Grid.Column="0" Text="{x:Bind Item.ServiceName}" Style="{StaticResource BodyStrongTextBlockStyle}" VerticalAlignment="Center" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" IsTextSelectionEnabled="True" ToolTipService.ToolTip="{x:Bind Item.ServiceName}"/>
358421

359422
<!-- Column 1: Display Name -->
360423
<TextBlock Grid.Column="1" Text="{x:Bind Item.DisplayName}" Style="{StaticResource BodyTextBlockStyle}" VerticalAlignment="Center" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" ToolTipService.ToolTip="{x:Bind Item.DisplayName}"/>

Harden System Security/Strings/en-US/Resources.resw

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5594,4 +5594,47 @@ Thumbprint: {3}</value>
55945594
<data name="ElevationContextSwitchButtonTeachingTip.ActionButtonContent" xml:space="preserve">
55955595
<value>Relaunch</value>
55965596
</data>
5597+
<!--NEW-->
5598+
<data name="OptimizeServicesButton.Content" xml:space="preserve">
5599+
<value>Optimize</value>
5600+
</data>
5601+
<data name="OptimizeServicesButton.ToolTipService.ToolTip" xml:space="preserve">
5602+
<value>Optimize the system services by stopping and disabling certain rarely used and safe to disable services in Windows. You can always undo these actions at any time.</value>
5603+
</data>
5604+
<data name="OptimizeServicesButton.AutomationProperties.HelpText" xml:space="preserve">
5605+
<value>Optimize the system services by stopping and disabling certain rarely used and safe to disable services in Windows. You can always undo these actions at any time.</value>
5606+
</data>
5607+
<data name="RecommendedServices.Text" xml:space="preserve">
5608+
<value>Recommended Services</value>
5609+
</data>
5610+
<data name="StopAndDisableAllRecommendedServicesButton.Content" xml:space="preserve">
5611+
<value>Stop and disable all</value>
5612+
</data>
5613+
<data name="StopAndDisableAllRecommendedServicesButton.ToolTipService.ToolTip" xml:space="preserve">
5614+
<value>Stop and disable all of the recommended services.</value>
5615+
</data>
5616+
<data name="StopAndDisableAllRecommendedServicesButton.AutomationProperties.HelpText" xml:space="preserve">
5617+
<value>Stop and disable all of the recommended services.</value>
5618+
</data>
5619+
<data name="MapsBrokerServiceDescription" xml:space="preserve">
5620+
<value>This is used to manage downloaded maps in Windows.</value>
5621+
</data>
5622+
<data name="WebClientServiceDescription" xml:space="preserve">
5623+
<value>Disabling this is recommended by Microsoft to improve security.</value>
5624+
</data>
5625+
<data name="StiSvcServiceDescription" xml:space="preserve">
5626+
<value>Only disable this if you do not use a scanner, digital camera or their image acquisition functions.</value>
5627+
</data>
5628+
<data name="DusmSvcServiceDescription" xml:space="preserve">
5629+
<value>Only disable this if you do not worry about data caps, you don't limit your network usage and you do not use metered networks.</value>
5630+
</data>
5631+
<data name="StopAndDisableServiceButton.ToolTipService.ToolTip" xml:space="preserve">
5632+
<value>Stop and disable the service.</value>
5633+
</data>
5634+
<data name="StopAndDisableServiceButton.AutomationProperties.HelpText" xml:space="preserve">
5635+
<value>Stop and disable the service.</value>
5636+
</data>
5637+
<data name="FileEnumerationDurationMessage" xml:space="preserve">
5638+
<value>File enumeration took {0} hours and {1} minutes and {2} seconds to complete.</value>
5639+
</data>
55975640
</root>

Harden System Security/ViewModels/MiscellaneousConfigsVM.cs

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -322,43 +322,7 @@ private static List<MUnit> CreateUnits()
322322

323323
applyStrategy: new DefaultApply(() =>
324324
{
325-
IntPtr scManager = NativeMethods.OpenSCManagerW(null, null, NativeMethods.SC_MANAGER_CONNECT);
326-
if (scManager != IntPtr.Zero)
327-
{
328-
try
329-
{
330-
IntPtr hService = NativeMethods.OpenServiceW(scManager, "WebClient", NativeMethods.SERVICE_CHANGE_CONFIG | NativeMethods.SERVICE_STOP);
331-
if (hService != IntPtr.Zero)
332-
{
333-
try
334-
{
335-
SERVICE_STATUS status = new();
336-
_ = NativeMethods.ControlService(hService, NativeMethods.SERVICE_CONTROL_STOP, ref status);
337-
338-
_ = NativeMethods.ChangeServiceConfigW(
339-
hService,
340-
NativeMethods.SERVICE_NO_CHANGE,
341-
4, // SERVICE_DISABLED
342-
NativeMethods.SERVICE_NO_CHANGE,
343-
null,
344-
null,
345-
IntPtr.Zero,
346-
IntPtr.Zero,
347-
null,
348-
null,
349-
null);
350-
}
351-
finally
352-
{
353-
_ = NativeMethods.CloseServiceHandle(hService);
354-
}
355-
}
356-
}
357-
finally
358-
{
359-
_ = NativeMethods.CloseServiceHandle(scManager);
360-
}
361-
}
325+
ViewModels.ServiceManagerVM.DisableAndStopServices(["WebClient"]);
362326
}),
363327

364328
verifyStrategy: new DefaultVerify(() =>

Harden System Security/ViewModels/ServiceManagerVM.cs

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030

3131
namespace HardenSystemSecurity.ViewModels;
3232

33+
internal sealed class RecommendedService(string serviceName, string displayName, string description)
34+
{
35+
internal string ServiceName => serviceName;
36+
internal string DisplayName => displayName;
37+
internal string Description => description;
38+
}
39+
3340
internal sealed partial class ServiceItemViewModel : ViewModelBase
3441
{
3542
internal ServiceItem Item { get; }
@@ -267,7 +274,6 @@ internal sealed partial class ServiceManagerVM : ViewModelBase
267274
{
268275
internal ServiceManagerVM() => FilteredServices.CollectionChanged += (s, e) => OnPropertyChanged(nameof(EmptyStatePlaceholderVisibility));
269276

270-
271277
internal readonly InfoBarSettings MainInfoBar = new();
272278

273279
// Whether the UI elements are enabled or disabled
@@ -307,6 +313,14 @@ internal bool IsLoading
307313
internal readonly RangedObservableCollection<ServiceItemViewModel> FilteredServices = [];
308314
internal readonly RangedObservableCollection<FilterGroupVM> FilterGroups = [];
309315

316+
internal readonly List<RecommendedService> RecommendedServices =
317+
[
318+
new("MapsBroker", "Maps Broker", Atlas.GetStr("MapsBrokerServiceDescription")),
319+
new("WebClient", "Web Client", Atlas.GetStr("WebClientServiceDescription")),
320+
new("StiSvc", "Windows Image acquisition", Atlas.GetStr("StiSvcServiceDescription")),
321+
new("DusmSvc", "Data usage restriction", Atlas.GetStr("DusmSvcServiceDescription"))
322+
];
323+
310324
internal Visibility EmptyStatePlaceholderVisibility => FilteredServices.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
311325

312326
internal string? SearchText
@@ -998,7 +1012,6 @@ internal async void CopyItem_Click(object sender, RoutedEventArgs e)
9981012
}
9991013
}
10001014

1001-
10021015
private bool ModifyServiceConfig(string serviceName, uint serviceType, uint startType, uint errorControl)
10031016
{
10041017
IntPtr scManager = NativeMethods.OpenSCManagerW(null, null, NativeMethods.SC_MANAGER_CONNECT);
@@ -1450,6 +1463,111 @@ internal async void LoadServicesButton_Loaded(object sender, Microsoft.UI.Xaml.R
14501463
if (AllServices.Count == 0)
14511464
_ = await FocusManager.TryFocusAsync((Button)sender, Microsoft.UI.Xaml.FocusState.Keyboard);
14521465
}
1466+
1467+
internal async void DisableAndStopRecommendedService_Click(object sender, RoutedEventArgs e)
1468+
{
1469+
if (sender is Button button && button.Tag is RecommendedService service)
1470+
{
1471+
try
1472+
{
1473+
AreElementsEnabled = false;
1474+
1475+
await Task.Run(() =>
1476+
{
1477+
DisableAndStopServices([service.ServiceName]);
1478+
});
1479+
1480+
MainInfoBar.WriteSuccess($"Successfully disabled and stopped {service.DisplayName}.");
1481+
RefreshList();
1482+
}
1483+
catch (Exception ex)
1484+
{
1485+
MainInfoBar.WriteError(ex);
1486+
}
1487+
finally
1488+
{
1489+
AreElementsEnabled = true;
1490+
}
1491+
}
1492+
}
1493+
1494+
internal async void DisableAndStopAllRecommendedServices_Click(object sender, RoutedEventArgs e)
1495+
{
1496+
try
1497+
{
1498+
AreElementsEnabled = false;
1499+
1500+
List<string> list = new(RecommendedServices.Count);
1501+
foreach (RecommendedService s in RecommendedServices)
1502+
{
1503+
list.Add(s.ServiceName);
1504+
}
1505+
1506+
await Task.Run(() =>
1507+
{
1508+
DisableAndStopServices(list);
1509+
});
1510+
1511+
MainInfoBar.WriteSuccess("Successfully disabled and stopped all recommended services.");
1512+
RefreshList();
1513+
}
1514+
catch (Exception ex)
1515+
{
1516+
MainInfoBar.WriteError(ex);
1517+
}
1518+
finally
1519+
{
1520+
AreElementsEnabled = true;
1521+
}
1522+
}
1523+
1524+
/// <summary>
1525+
/// Disables and stops services.
1526+
/// </summary>
1527+
/// <param name="serviceNames">Service names to disable and stop.</param>
1528+
internal static void DisableAndStopServices(List<string> serviceNames)
1529+
{
1530+
IntPtr scManager = NativeMethods.OpenSCManagerW(null, null, NativeMethods.SC_MANAGER_CONNECT);
1531+
if (scManager != IntPtr.Zero)
1532+
{
1533+
try
1534+
{
1535+
foreach (string serviceName in CollectionsMarshal.AsSpan(serviceNames))
1536+
{
1537+
IntPtr hService = NativeMethods.OpenServiceW(scManager, serviceName, NativeMethods.SERVICE_CHANGE_CONFIG | NativeMethods.SERVICE_STOP);
1538+
if (hService != IntPtr.Zero)
1539+
{
1540+
try
1541+
{
1542+
SERVICE_STATUS status = new();
1543+
_ = NativeMethods.ControlService(hService, NativeMethods.SERVICE_CONTROL_STOP, ref status);
1544+
1545+
_ = NativeMethods.ChangeServiceConfigW(
1546+
hService,
1547+
NativeMethods.SERVICE_NO_CHANGE,
1548+
4, // SERVICE_DISABLED
1549+
NativeMethods.SERVICE_NO_CHANGE,
1550+
null,
1551+
null,
1552+
IntPtr.Zero,
1553+
IntPtr.Zero,
1554+
null,
1555+
null,
1556+
null);
1557+
}
1558+
finally
1559+
{
1560+
_ = NativeMethods.CloseServiceHandle(hService);
1561+
}
1562+
}
1563+
}
1564+
}
1565+
finally
1566+
{
1567+
_ = NativeMethods.CloseServiceHandle(scManager);
1568+
}
1569+
}
1570+
}
14531571
}
14541572

14551573
[System.Runtime.InteropServices.Marshalling.GeneratedComClass]

0 commit comments

Comments
 (0)