diff --git a/src/common/GPOWrapper/GPOWrapper.cpp b/src/common/GPOWrapper/GPOWrapper.cpp index 02075707b7..67dae70930 100644 --- a/src/common/GPOWrapper/GPOWrapper.cpp +++ b/src/common/GPOWrapper/GPOWrapper.cpp @@ -200,6 +200,10 @@ namespace winrt::PowerToys::GPOWrapper::implementation { return static_cast(powertoys_gpo::getConfiguredMwbDisallowBlockingScreensaverValue()); } + GpoRuleConfigured GPOWrapper::GetConfiguredMwbAllowServiceModeValue() + { + return static_cast(powertoys_gpo::getConfiguredMwbAllowServiceModeValue()); + } GpoRuleConfigured GPOWrapper::GetConfiguredMwbSameSubnetOnlyValue() { return static_cast(powertoys_gpo::getConfiguredMwbSameSubnetOnlyValue()); diff --git a/src/common/GPOWrapper/GPOWrapper.h b/src/common/GPOWrapper/GPOWrapper.h index 71f9799c85..8df863b9d7 100644 --- a/src/common/GPOWrapper/GPOWrapper.h +++ b/src/common/GPOWrapper/GPOWrapper.h @@ -56,6 +56,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation static GpoRuleConfigured GetConfiguredMwbFileTransferEnabledValue(); static GpoRuleConfigured GetConfiguredMwbUseOriginalUserInterfaceValue(); static GpoRuleConfigured GetConfiguredMwbDisallowBlockingScreensaverValue(); + static GpoRuleConfigured GetConfiguredMwbAllowServiceModeValue(); static GpoRuleConfigured GetConfiguredMwbSameSubnetOnlyValue(); static GpoRuleConfigured GetConfiguredMwbValidateRemoteIpValue(); static GpoRuleConfigured GetConfiguredMwbDisableUserDefinedIpMappingRulesValue(); diff --git a/src/common/GPOWrapper/GPOWrapper.idl b/src/common/GPOWrapper/GPOWrapper.idl index 256a77a739..d22ab63e09 100644 --- a/src/common/GPOWrapper/GPOWrapper.idl +++ b/src/common/GPOWrapper/GPOWrapper.idl @@ -60,6 +60,7 @@ namespace PowerToys static GpoRuleConfigured GetConfiguredMwbFileTransferEnabledValue(); static GpoRuleConfigured GetConfiguredMwbUseOriginalUserInterfaceValue(); static GpoRuleConfigured GetConfiguredMwbDisallowBlockingScreensaverValue(); + static GpoRuleConfigured GetConfiguredMwbAllowServiceModeValue(); static GpoRuleConfigured GetConfiguredMwbSameSubnetOnlyValue(); static GpoRuleConfigured GetConfiguredMwbValidateRemoteIpValue(); static GpoRuleConfigured GetConfiguredMwbDisableUserDefinedIpMappingRulesValue(); diff --git a/src/common/utils/gpo.h b/src/common/utils/gpo.h index cd10b776a6..d1341c63ac 100644 --- a/src/common/utils/gpo.h +++ b/src/common/utils/gpo.h @@ -79,6 +79,7 @@ namespace powertoys_gpo { const std::wstring POLICY_MWB_FILE_TRANSFER_ENABLED = L"MwbFileTransferEnabled"; const std::wstring POLICY_MWB_USE_ORIGINAL_USER_INTERFACE = L"MwbUseOriginalUserInterface"; const std::wstring POLICY_MWB_DISALLOW_BLOCKING_SCREENSAVER = L"MwbDisallowBlockingScreensaver"; + const std::wstring POLICY_MWB_ALLOW_SERVICE_MODE = L"MwbAllowServiceMode"; const std::wstring POLICY_MWB_SAME_SUBNET_ONLY = L"MwbSameSubnetOnly"; const std::wstring POLICY_MWB_VALIDATE_REMOTE_IP = L"MwbValidateRemoteIp"; const std::wstring POLICY_MWB_DISABLE_USER_DEFINED_IP_MAPPING_RULES = L"MwbDisableUserDefinedIpMappingRules"; @@ -558,6 +559,11 @@ namespace powertoys_gpo { return getConfiguredValue(POLICY_MWB_DISALLOW_BLOCKING_SCREENSAVER); } + inline gpo_rule_configured_t getConfiguredMwbAllowServiceModeValue() + { + return getConfiguredValue(POLICY_MWB_ALLOW_SERVICE_MODE); + } + inline gpo_rule_configured_t getConfiguredMwbSameSubnetOnlyValue() { return getConfiguredValue(POLICY_MWB_SAME_SUBNET_ONLY); diff --git a/src/gpo/assets/PowerToys.admx b/src/gpo/assets/PowerToys.admx index 74b8d9fdc5..188b92c353 100644 --- a/src/gpo/assets/PowerToys.admx +++ b/src/gpo/assets/PowerToys.admx @@ -1,11 +1,11 @@ - + - + @@ -24,6 +24,7 @@ + @@ -602,6 +603,16 @@ + + + + + + + + + + diff --git a/src/gpo/assets/en-US/PowerToys.adml b/src/gpo/assets/en-US/PowerToys.adml index 68da74c6de..6ff31ebc51 100644 --- a/src/gpo/assets/en-US/PowerToys.adml +++ b/src/gpo/assets/en-US/PowerToys.adml @@ -1,7 +1,7 @@ - + PowerToys PowerToys @@ -31,6 +31,7 @@ PowerToys version 0.85.0 or later PowerToys version 0.86.0 or later PowerToys version 0.88.0 or later + PowerToys version 0.89.0 or later From PowerToys version 0.64.0 until PowerToys version 0.87.1 This policy configures the enabled state for all PowerToys utilities. @@ -169,7 +170,14 @@ If you enable this policy, the user won't be able to enable the "block screensav If you disable or don't configure this policy, the user takes control over the setting and can block the screensaver. + This policy configures if the user is allowed to use Mouse Without Borders in Service Mode. +If this setting is enabled or not configured, the user can enable and use Mouse Without Borders in Service Mode. + +If this setting is disabled, the user won't be able to enable or use Mouse Without Borders in Service Mode. + +Note: As most other PowerToys policies, a restart of PowerToys is required for a change in this policy to take full effect. + This policy configures if connections are only allowed in the same subnet. If you enable this policy, the setting is enabled and only connections in the same subnet are allowed. @@ -264,6 +272,7 @@ If you don't configure this policy, the user takes control over the setting and File transfer enabled Original user interface is available Disallow blocking screensaver on other machines + Allow Service Mode Connect only in same subnet Validate remote machine IP Address Disable user defined IP Address mapping rules diff --git a/src/modules/MouseWithoutBorders/App/Class/Program.cs b/src/modules/MouseWithoutBorders/App/Class/Program.cs index 3e3795f6ef..7a6b3a37ed 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Program.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Program.cs @@ -92,6 +92,17 @@ namespace MouseWithoutBorders.Class bool serviceMode = firstArg == ServiceModeArg; + if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMwbAllowServiceModeValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + if (runningAsSystem) + { + Logger.Log("Can't run as a service. It's not allowed according to GPO policy. Please contact your systems administrator."); + return; + } + + serviceMode = false; + } + // If we're started from the .dll module or from the service process, we should // assume the service mode. if (serviceMode && !runningAsSystem) diff --git a/src/modules/MouseWithoutBorders/App/Class/Setting.cs b/src/modules/MouseWithoutBorders/App/Class/Setting.cs index 23ca49309c..8d2270424d 100644 --- a/src/modules/MouseWithoutBorders/App/Class/Setting.cs +++ b/src/modules/MouseWithoutBorders/App/Class/Setting.cs @@ -1090,6 +1090,11 @@ namespace MouseWithoutBorders.Class { get { + if (GPOWrapper.GetConfiguredMwbAllowServiceModeValue() == GpoRuleConfigured.Disabled) + { + return false; + } + lock (_loadingSettingsLock) { return _properties.UseService; @@ -1098,6 +1103,11 @@ namespace MouseWithoutBorders.Class set { + if (AllowServiceModeIsGpoConfigured) + { + return; + } + lock (_loadingSettingsLock) { _properties.UseService = value; @@ -1109,6 +1119,10 @@ namespace MouseWithoutBorders.Class } } + [CmdConfigureIgnore] + [JsonIgnore] + internal bool AllowServiceModeIsGpoConfigured => GPOWrapper.GetConfiguredMwbAllowServiceModeValue() == GpoRuleConfigured.Disabled; + // Note(@htcfreek): Settings UI CheckBox is disabled in frmMatrix.cs > FrmMatrix_Load() internal bool SendErrorLogV2 { diff --git a/src/modules/MouseWithoutBorders/App/Service/Program.cs b/src/modules/MouseWithoutBorders/App/Service/Program.cs index 350ff1df4e..72fc31d14e 100644 --- a/src/modules/MouseWithoutBorders/App/Service/Program.cs +++ b/src/modules/MouseWithoutBorders/App/Service/Program.cs @@ -28,7 +28,8 @@ namespace MouseWithoutBordersService [STAThread] private static void Main() { - if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMouseWithoutBordersEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMouseWithoutBordersEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled + || PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMwbAllowServiceModeValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled ) { // TODO: Add logging. // Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator."); diff --git a/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp b/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp index 463d527230..67799aa6c5 100644 --- a/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp +++ b/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp @@ -363,7 +363,11 @@ private: void update_state_from_settings(const PowerToysSettings::PowerToyValues& values) { - const bool new_run_in_service_mode = values.get_bool_value(USE_SERVICE_PROPERTY_NAME).value_or(false); + bool new_run_in_service_mode = values.get_bool_value(USE_SERVICE_PROPERTY_NAME).value_or(false); + if (powertoys_gpo::getConfiguredMwbAllowServiceModeValue() == powertoys_gpo::gpo_rule_configured_disabled) + { + new_run_in_service_mode = false; + } if (new_run_in_service_mode != run_in_service_mode) { diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml index 0046bca990..883e3674de 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml @@ -186,12 +186,19 @@ - - + + + + + + + Settings.Properties.UseService; + get + { + if (_allowServiceModeGpoConfiguration == GpoRuleConfigured.Disabled) + { + return false; + } + + return Settings.Properties.UseService; + } set { + if (_allowServiceModeIsGPOConfigured) + { + return; + } + var valueChanged = Settings.Properties.UseService != value; // Set the UI property itself instantly @@ -122,6 +135,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public bool UseServiceSettingIsEnabled => _allowServiceModeIsGPOConfigured == false; + public bool ConnectFieldsVisible { get => _connectFieldsVisible; @@ -185,6 +200,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private bool _useOriginalUserInterfaceIsGPOConfigured; private GpoRuleConfigured _disallowBlockingScreensaverGpoConfiguration; private bool _disallowBlockingScreensaverIsGPOConfigured; + private GpoRuleConfigured _allowServiceModeGpoConfiguration; + private bool _allowServiceModeIsGPOConfigured; private GpoRuleConfigured _sameSubnetOnlyGpoConfiguration; private bool _sameSubnetOnlyIsGPOConfigured; private GpoRuleConfigured _validateRemoteIpGpoConfiguration; @@ -507,6 +524,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels _disableUserDefinedIpMappingRulesIsGPOConfigured = _disableUserDefinedIpMappingRulesGpoConfiguration == GpoRuleConfigured.Enabled; // Policies supporting only disabled state + _allowServiceModeGpoConfiguration = GPOWrapper.GetConfiguredMwbAllowServiceModeValue(); + _allowServiceModeIsGPOConfigured = _allowServiceModeGpoConfiguration == GpoRuleConfigured.Disabled; _clipboardSharingEnabledGpoConfiguration = GPOWrapper.GetConfiguredMwbClipboardSharingEnabledValue(); _clipboardSharingEnabledIsGPOConfigured = _clipboardSharingEnabledGpoConfiguration == GpoRuleConfigured.Disabled; _fileTransferEnabledGpoConfiguration = GPOWrapper.GetConfiguredMwbFileTransferEnabledValue(); @@ -1231,6 +1250,14 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels SendCustomAction("uninstall_service"); } + public bool ShowPolicyConfiguredInfoForServiceSettings + { + get + { + return IsEnabled && _allowServiceModeIsGPOConfigured; + } + } + public bool ShowPolicyConfiguredInfoForBehaviorSettings { get @@ -1248,7 +1275,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels public bool ShowInfobarRunAsAdminText { - get { return !CanToggleUseService && IsEnabled; } + get { return !CanToggleUseService && IsEnabled && !ShowPolicyConfiguredInfoForServiceSettings; } } } } diff --git a/tools/BugReportTool/BugReportTool/ReportGPOValues.cpp b/tools/BugReportTool/BugReportTool/ReportGPOValues.cpp index 07842af576..2ba84a55e4 100644 --- a/tools/BugReportTool/BugReportTool/ReportGPOValues.cpp +++ b/tools/BugReportTool/BugReportTool/ReportGPOValues.cpp @@ -87,6 +87,7 @@ void ReportGPOValues(const std::filesystem::path &tmpDir) report << "getConfiguredMwbFileTransferEnabledValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredMwbFileTransferEnabledValue()) << std::endl; report << "getConfiguredMwbUseOriginalUserInterfaceValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredMwbUseOriginalUserInterfaceValue()) << std::endl; report << "getConfiguredMwbDisallowBlockingScreensaverValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredMwbDisallowBlockingScreensaverValue()) << std::endl; + report << "getConfiguredMwbAllowServiceModeValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredMwbAllowServiceModeValue()) << std::endl; report << "getConfiguredMwbSameSubnetOnlyValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredMwbSameSubnetOnlyValue()) << std::endl; report << "getConfiguredMwbValidateRemoteIpValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredMwbValidateRemoteIpValue()) << std::endl; report << "getConfiguredMwbDisableUserDefinedIpMappingRulesValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredMwbDisableUserDefinedIpMappingRulesValue()) << std::endl;