Projects STRLCPY NETworkManager Commits a5a1e71d
🤬
  • Feature: Remote Desktop Gateway server (#2108)

    * Feature: Implement RD Gateway in settings & some refactoring
    
    * Feature: Implement RD Gateway in settings
    
    * Feature: Gateway server in group implemented
    
    * Feature: Gateway server in host profile implemented
    
    * Feature: Disconnect reason
    
    * Feature: Add more disconnect reasons
    
    * Docs: Add #2108
  • Loading...
  • BornToBeRoot committed with GitHub 1 year ago
    a5a1e71d
    1 parent 5221674a
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Controls/RemoteDesktopControl.xaml.cs
    skipped 158 lines
    159 159   
    160 160   RdpClient.CreateControl();
    161 161   
     162 + // General
    162 163   RdpClient.Server = _rdpSessionInfo.Hostname;
    163  - RdpClient.AdvancedSettings9.RDPPort = _rdpSessionInfo.Port;
    164 164   
    165  - if (_rdpSessionInfo.CustomCredentials)
     165 + // Credentials
     166 + if (_rdpSessionInfo.UseCredentials)
    166 167   {
    167 168   RdpClient.UserName = _rdpSessionInfo.Username;
     169 + 
     170 + if (!string.IsNullOrEmpty(_rdpSessionInfo.Domain))
     171 + RdpClient.Domain = _rdpSessionInfo.Domain;
     172 + 
    168 173   RdpClient.AdvancedSettings9.ClearTextPassword = SecureStringHelper.ConvertToString(_rdpSessionInfo.Password);
    169 174   }
    170 175   
    171  - // AdvancedSettings
     176 + // Network
     177 + RdpClient.AdvancedSettings9.RDPPort = _rdpSessionInfo.Port;
     178 + 
     179 + // Display
     180 + RdpClient.ColorDepth = _rdpSessionInfo.ColorDepth; // 8, 15, 16, 24
     181 + 
     182 + if (_rdpSessionInfo.AdjustScreenAutomatically || _rdpSessionInfo.UseCurrentViewSize)
     183 + {
     184 + RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
     185 + RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
     186 + }
     187 + else
     188 + {
     189 + RdpClient.DesktopWidth = _rdpSessionInfo.DesktopWidth;
     190 + RdpClient.DesktopHeight = _rdpSessionInfo.DesktopHeight;
     191 + }
     192 + 
     193 + // Authentication
    172 194   RdpClient.AdvancedSettings9.AuthenticationLevel = _rdpSessionInfo.AuthenticationLevel;
    173 195   RdpClient.AdvancedSettings9.EnableCredSspSupport = _rdpSessionInfo.EnableCredSspSupport;
    174 196   
     197 + // Gateway server
     198 + if (_rdpSessionInfo.EnableGatewayServer && !string.IsNullOrEmpty(_rdpSessionInfo.GatewayServerHostname))
     199 + {
     200 + RdpClient.TransportSettings2.GatewayProfileUsageMethod = (uint)GatewayProfileUsageMethod.Explicit;
     201 + RdpClient.TransportSettings2.GatewayUsageMethod = (uint)(_rdpSessionInfo.GatewayServerBypassLocalAddresses ? GatewayUsageMethod.Detect : GatewayUsageMethod.Direct);
     202 + RdpClient.TransportSettings2.GatewayHostname = _rdpSessionInfo.GatewayServerHostname;
     203 + RdpClient.TransportSettings2.GatewayCredsSource = (uint)_rdpSessionInfo.GatewayServerLogonMethod;
     204 + RdpClient.TransportSettings2.GatewayCredSharing = _rdpSessionInfo.GatewayServerShareCredentialsWithRemoteComputer ? 1u : 0u;
     205 + 
     206 + // Credentials
     207 + if (_rdpSessionInfo.UseGatewayServerCredentials && Equals(_rdpSessionInfo.GatewayServerLogonMethod, GatewayUserSelectedCredsSource.Userpass))
     208 + {
     209 + RdpClient.TransportSettings2.GatewayUsername = _rdpSessionInfo.GatewayServerUsername;
     210 + 
     211 + if (!string.IsNullOrEmpty(_rdpSessionInfo.GatewayServerDomain))
     212 + RdpClient.TransportSettings2.GatewayDomain = _rdpSessionInfo.GatewayServerDomain;
     213 + 
     214 + RdpClient.TransportSettings2.GatewayPassword = SecureStringHelper.ConvertToString(_rdpSessionInfo.GatewayServerPassword);
     215 + }
     216 + }
     217 + else
     218 + {
     219 + RdpClient.TransportSettings2.GatewayProfileUsageMethod = (uint)GatewayProfileUsageMethod.Default;
     220 + RdpClient.TransportSettings2.GatewayUsageMethod = (uint)GatewayUsageMethod.NoneDirect;
     221 + }
     222 +
     223 + // Remote audio
     224 + RdpClient.AdvancedSettings9.AudioRedirectionMode = (uint)_rdpSessionInfo.AudioRedirectionMode;
     225 + RdpClient.AdvancedSettings9.AudioCaptureRedirectionMode = _rdpSessionInfo.AudioCaptureRedirectionMode == 0;
     226 +
    175 227   // Keyboard
    176 228   RdpClient.SecuredSettings3.KeyboardHookMode = (int)_rdpSessionInfo.KeyboardHookMode;
    177 229   
    skipped 4 lines
    182 234   RdpClient.AdvancedSettings9.RedirectPorts = _rdpSessionInfo.RedirectPorts;
    183 235   RdpClient.AdvancedSettings9.RedirectSmartCards = _rdpSessionInfo.RedirectSmartCards;
    184 236   RdpClient.AdvancedSettings9.RedirectPrinters = _rdpSessionInfo.RedirectPrinters;
    185  - 
    186  - // Audio
    187  - RdpClient.AdvancedSettings9.AudioRedirectionMode = (uint)_rdpSessionInfo.AudioRedirectionMode;
    188  - RdpClient.AdvancedSettings9.AudioCaptureRedirectionMode = _rdpSessionInfo.AudioCaptureRedirectionMode == 0;
    189 237   
    190 238   // Performance
    191 239   RdpClient.AdvancedSettings9.BitmapPeristence = _rdpSessionInfo.PersistentBitmapCaching ? 1 : 0;
    skipped 23 lines
    215 263   RdpClient.AdvancedSettings9.PerformanceFlags |= RemoteDesktopPerformanceConstants.TS_PERF_DISABLE_THEMING;
    216 264   }
    217 265   
    218  - // Display
    219  - RdpClient.ColorDepth = _rdpSessionInfo.ColorDepth; // 8, 15, 16, 24
    220  - 
    221  - if (_rdpSessionInfo.AdjustScreenAutomatically || _rdpSessionInfo.UseCurrentViewSize)
    222  - {
    223  - RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
    224  - RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
    225  - }
    226  - else
    227  - {
    228  - RdpClient.DesktopWidth = _rdpSessionInfo.DesktopWidth;
    229  - RdpClient.DesktopHeight = _rdpSessionInfo.DesktopHeight;
    230  - }
    231  - 
    232 266   FixWindowsFormsHostSize();
    233 267   
    234 268   // Events
    235 269   RdpClient.OnConnected += RdpClient_OnConnected;
    236 270   RdpClient.OnDisconnected += RdpClient_OnDisconnected;
    237 271   
     272 + // Static settings
    238 273   RdpClient.AdvancedSettings9.EnableWindowsKey = 1; // Enable window key
    239 274   RdpClient.AdvancedSettings9.allowBackgroundInput = 1; // Background input to send keystrokes like ctrl+alt+del
    240 275   
     276 + // Connect
    241 277   RdpClient.Connect();
    242 278   }
    243 279   
    skipped 4 lines
    248 284   
    249 285   IsConnecting = true;
    250 286   
    251  - if (_rdpSessionInfo.AdjustScreenAutomatically)
     287 + if (_rdpSessionInfo.AdjustScreenAutomatically || _rdpSessionInfo.UseCurrentViewSize)
    252 288   {
    253 289   RdpClient.DesktopWidth = (int)RdpGrid.ActualWidth;
    254 290   RdpClient.DesktopHeight = (int)RdpGrid.ActualHeight;
    skipped 55 lines
    310 346   Disconnect();
    311 347   }
    312 348   
     349 + /// <summary>
     350 + /// Get disconnect reason by code.
     351 + /// Docs: https://social.technet.microsoft.com/wiki/contents/articles/37870.remote-desktop-client-troubleshooting-disconnect-codes-and-reasons.aspx
     352 + /// </summary>
     353 + /// <param name="reason">Disconnect code</param>
     354 + /// <returns>Disconnect message</returns>
    313 355   private static string GetDisconnectReason(int reason)
    314 356   {
    315  - switch (reason)
     357 + return reason switch
    316 358   {
    317  - case 0:
    318  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_NoInfo;
    319  - case 1:
    320  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LocalNotError;
    321  - case 2:
    322  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_RemoteByUser;
    323  - case 3:
    324  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ByServer;
    325  - case 4:
    326  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TotalLoginTimeLimitReached;
    327  - case 260:
    328  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DNSLookupFailed;
    329  - case 262:
    330  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory;
    331  - case 264:
    332  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ConnectionTimedOut;
    333  - case 516:
    334  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SocketConnectFailed;
    335  - case 518:
    336  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory2;
    337  - case 520:
    338  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_HostNotFound;
    339  - case 772:
    340  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_WinsockSendFailed;
    341  - case 774:
    342  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory3;
    343  - case 776:
    344  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidIPAddr;
    345  - case 1028:
    346  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SocketRecvFailed;
    347  - case 1030:
    348  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidSecurityData;
    349  - case 1032:
    350  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalError;
    351  - case 1286:
    352  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidEncryption;
    353  - case 1288:
    354  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DNSLookupFailed2;
    355  - case 1540:
    356  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_GetHostByNameFailed;
    357  - case 1542:
    358  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidServerSecurityInfo;
    359  - case 1544:
    360  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TimerError;
    361  - case 1796:
    362  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_TimeoutOccurred;
    363  - case 1798:
    364  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ServerCertificateUnpackErr;
    365  - case 2052:
    366  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidIP;
    367  - case 2055:
    368  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrLogonFailure;
    369  - case 2056:
    370  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LicensingFailed;
    371  - case 2308:
    372  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_AtClientWinsockFDCLOSE;
    373  - case 2310:
    374  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalSecurityError;
    375  - case 2312:
    376  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_LicensingTimeout;
    377  - case 2566:
    378  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalSecurityError2;
    379  - case 2567:
    380  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrNoSuchUser;
    381  - case 2822:
    382  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_EncryptionError;
    383  - case 2823:
    384  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountDisabled;
    385  - case 3078:
    386  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_DecryptionError;
    387  - case 3079:
    388  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountRestriction;
    389  - case 3080:
    390  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_ClientDecompressionError;
    391  - case 3335:
    392  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountLockedOut;
    393  - case 3591:
    394  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountExpired;
    395  - case 3847:
    396  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPasswordExpired;
    397  - case 4360:
    398  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_UnableToReconnectToRemoteSession;
    399  - case 4615:
    400  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPasswordMustChange;
    401  - case 5639:
    402  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrDelegationPolicy;
    403  - case 5895:
    404  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPolicyNTLMOnly;
    405  - case 6151:
    406  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrNoAuthenticatingAuthority;
    407  - case 6919:
    408  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrCertExpired;
    409  - case 7175:
    410  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrSmartcardWrongPIN;
    411  - case 8455:
    412  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrFreshCredRequiredByServer;
    413  - case 8711:
    414  - return Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrSmartcardCardBlocked;
    415  - default:
    416  - return "Disconnect reason code " + reason + " not found in resources!" + Environment.NewLine + "(You can report this on GitHub)";
    417  - }
     359 + 0 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_NoInfo,
     360 + 1 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_LocalNotError,
     361 + 2 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_RemoteByUser,
     362 + 3 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_ByServer,
     363 + 4 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_TotalLoginTimeLimitReached,
     364 + 260 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_DNSLookupFailed,
     365 + 262 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory,
     366 + 264 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_ConnectionTimedOut,
     367 + 516 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SocketConnectFailed,
     368 + 518 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory2,
     369 + 520 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_HostNotFound,
     370 + 772 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_WinsockSendFailed,
     371 + 774 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_OutOfMemory3,
     372 + 776 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidIPAddr,
     373 + 1028 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SocketRecvFailed,
     374 + 1030 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidSecurityData,
     375 + 1032 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalError,
     376 + 1286 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidEncryption,
     377 + 1288 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_DNSLookupFailed2,
     378 + 1540 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_GetHostByNameFailed,
     379 + 1542 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidServerSecurityInfo,
     380 + 1544 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_TimerError,
     381 + 1796 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_TimeoutOccurred,
     382 + 1798 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_ServerCertificateUnpackErr,
     383 + 2052 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_InvalidIP,
     384 + 2055 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrLogonFailure,
     385 + 2056 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_LicensingFailed,
     386 + 2308 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_AtClientWinsockFDCLOSE,
     387 + 2310 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalSecurityError,
     388 + 2312 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_LicensingTimeout,
     389 + 2566 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_InternalSecurityError2,
     390 + 2567 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrNoSuchUser,
     391 + 2822 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_EncryptionError,
     392 + 2823 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountDisabled,
     393 + 3078 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_DecryptionError,
     394 + 3079 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountRestriction,
     395 + 3080 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_ClientDecompressionError,
     396 + 3335 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountLockedOut,
     397 + 3591 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrAccountExpired,
     398 + 3847 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPasswordExpired,
     399 + 4360 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_UnableToReconnectToRemoteSession,
     400 + 4615 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPasswordMustChange,
     401 + 5639 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrDelegationPolicy,
     402 + 5895 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrPolicyNTLMOnly,
     403 + 6151 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrNoAuthenticatingAuthority,
     404 + 6919 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrCertExpired,
     405 + 7175 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrSmartcardWrongPIN,
     406 + 8455 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrFreshCredRequiredByServer,
     407 + 8711 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_SslErrSmartcardCardBlocked,
     408 + 50331651 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331651,
     409 + 50331653 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331653,
     410 + 50331654 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331654,
     411 + 50331655 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331655,
     412 + 50331657 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331657,
     413 + 50331658 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331658,
     414 + 50331660 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331660,
     415 + 50331661 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331661,
     416 + 50331663 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331663,
     417 + 50331672 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331672,
     418 + 50331673 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331673,
     419 + 50331675 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331675,
     420 + 50331676 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331676,
     421 + 50331679 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331679,
     422 + 50331680 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331680,
     423 + 50331682 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331682,
     424 + 50331683 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331683,
     425 + 50331684 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331684,
     426 + 50331685 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331685,
     427 + 50331688 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331688,
     428 + 50331689 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331689,
     429 + 50331690 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331690,
     430 + 50331691 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331691,
     431 + 50331692 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331692,
     432 + 50331700 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331700,
     433 + 50331701 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331701,
     434 + 50331703 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331703,
     435 + 50331704 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331704,
     436 + 50331705 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331705,
     437 + 50331707 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331707,
     438 + 50331713 => Localization.Resources.Strings.RemoteDesktopDisconnectReason_50331713,
     439 + _ => "Disconnect reason code " + reason + " not found in resources!" + Environment.NewLine + "(Please report this on GitHub issues)",
     440 + };
    418 441   }
    419 442   #endregion
    420 443   
    skipped 15 lines
    436 459   private void RdpGrid_SizeChanged(object sender, SizeChangedEventArgs e)
    437 460   {
    438 461   if (IsConnected && _rdpSessionInfo.AdjustScreenAutomatically && !IsReconnecting)
    439  - InitiateReconnection();
     462 + ReconnectOnSizeChanged();
    440 463   }
    441 464   
    442  - private async Task InitiateReconnection()
     465 + private async Task ReconnectOnSizeChanged()
    443 466   {
    444 467   IsReconnecting = true;
    445 468   
    skipped 9 lines
    455 478   }
    456 479   #endregion
    457 480  }
     481 + 
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ProfileDialogManager.cs
    skipped 275 lines
    276 276   RemoteDesktop_Host = instance.RemoteDesktop_InheritHost ? instance.Host?.Trim() : instance.RemoteDesktop_Host?.Trim(),
    277 277   RemoteDesktop_UseCredentials = instance.RemoteDesktop_UseCredentials,
    278 278   RemoteDesktop_Username = instance.RemoteDesktop_UseCredentials ? instance.RemoteDesktop_Username : string.Empty, // Remove sensitive info on disable
     279 + RemoteDesktop_Domain = instance.RemoteDesktop_UseCredentials ? instance.RemoteDesktop_Domain : string.Empty, // Remove sensitive info on disable
    279 280   RemoteDesktop_Password = instance.RemoteDesktop_UseCredentials ? instance.RemoteDesktop_Password : new SecureString(), // Remove sensitive info on disable
    280 281   RemoteDesktop_OverrideDisplay = instance.RemoteDesktop_OverrideDisplay,
    281 282   RemoteDesktop_AdjustScreenAutomatically = instance.RemoteDesktop_AdjustScreenAutomatically,
    skipped 12 lines
    294 295   RemoteDesktop_EnableCredSspSupport = instance.RemoteDesktop_EnableCredSspSupport,
    295 296   RemoteDesktop_OverrideAuthenticationLevel = instance.RemoteDesktop_OverrideAuthenticationLevel,
    296 297   RemoteDesktop_AuthenticationLevel = instance.RemoteDesktop_AuthenticationLevel,
     298 + RemoteDesktop_OverrideGatewayServer = instance.RemoteDesktop_OverrideGatewayServer,
     299 + RemoteDesktop_EnableGatewayServer = instance.RemoteDesktop_EnableGatewayServer,
     300 + RemoteDesktop_GatewayServerHostname = instance.RemoteDesktop_GatewayServerHostname,
     301 + RemoteDesktop_GatewayServerBypassLocalAddresses = instance.RemoteDesktop_GatewayServerBypassLocalAddresses,
     302 + RemoteDesktop_GatewayServerLogonMethod = instance.RemoteDesktop_GatewayServerLogonMethod,
     303 + RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = instance.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer,
     304 + RemoteDesktop_UseGatewayServerCredentials = instance.RemoteDesktop_UseGatewayServerCredentials,
     305 + RemoteDesktop_GatewayServerUsername = instance.RemoteDesktop_EnableGatewayServer && Equals(instance.RemoteDesktop_GatewayServerLogonMethod, Models.RemoteDesktop.GatewayUserSelectedCredsSource.Userpass) && instance.RemoteDesktop_UseGatewayServerCredentials ? instance.RemoteDesktop_GatewayServerUsername : string.Empty, // Remove sensitive info on disable
     306 + RemoteDesktop_GatewayServerDomain = instance.RemoteDesktop_EnableGatewayServer && Equals(instance.RemoteDesktop_GatewayServerLogonMethod, Models.RemoteDesktop.GatewayUserSelectedCredsSource.Userpass) && instance.RemoteDesktop_UseGatewayServerCredentials ? instance.RemoteDesktop_GatewayServerDomain : string.Empty, // Remove sensitive info on disable
     307 + RemoteDesktop_GatewayServerPassword = instance.RemoteDesktop_EnableGatewayServer && Equals(instance.RemoteDesktop_GatewayServerLogonMethod, Models.RemoteDesktop.GatewayUserSelectedCredsSource.Userpass) && instance.RemoteDesktop_UseGatewayServerCredentials ? instance.RemoteDesktop_GatewayServerPassword : new SecureString(), // Remove sensitive info on disable
    297 308   RemoteDesktop_OverrideAudioRedirectionMode = instance.RemoteDesktop_OverrideAudioRedirectionMode,
    298 309   RemoteDesktop_AudioRedirectionMode = instance.RemoteDesktop_AudioRedirectionMode,
    299 310   RemoteDesktop_OverrideAudioCaptureRedirectionMode = instance.RemoteDesktop_OverrideAudioCaptureRedirectionMode,
    skipped 105 lines
    405 416   string name = instance.Name.Trim();
    406 417   
    407 418   // Update group in profiles
    408  - if(profiles.Count > 0)
     419 + if (profiles.Count > 0)
    409 420   {
    410  - if(!string.IsNullOrEmpty(instance.Group.Name) && !string.Equals(instance.Group.Name, name, System.StringComparison.Ordinal))
     421 + if (!string.IsNullOrEmpty(instance.Group.Name) && !string.Equals(instance.Group.Name, name, System.StringComparison.Ordinal))
    411 422   {
    412 423   foreach (ProfileInfo profile in profiles)
    413 424   profile.Group = name;
    skipped 13 lines
    427 438   // Remote Desktop
    428 439   RemoteDesktop_UseCredentials = instance.RemoteDesktop_UseCredentials,
    429 440   RemoteDesktop_Username = instance.RemoteDesktop_UseCredentials ? instance.RemoteDesktop_Username : string.Empty, // Remove sensitive info on disable
     441 + RemoteDesktop_Domain = instance.RemoteDesktop_UseCredentials ? instance.RemoteDesktop_Domain : string.Empty, // Remove sensitive info on disable
    430 442   RemoteDesktop_Password = instance.RemoteDesktop_UseCredentials ? instance.RemoteDesktop_Password : new SecureString(), // Remove sensitive info on disable
    431 443   RemoteDesktop_OverrideDisplay = instance.RemoteDesktop_OverrideDisplay,
    432 444   RemoteDesktop_AdjustScreenAutomatically = instance.RemoteDesktop_AdjustScreenAutomatically,
    skipped 12 lines
    445 457   RemoteDesktop_EnableCredSspSupport = instance.RemoteDesktop_EnableCredSspSupport,
    446 458   RemoteDesktop_OverrideAuthenticationLevel = instance.RemoteDesktop_OverrideAuthenticationLevel,
    447 459   RemoteDesktop_AuthenticationLevel = instance.RemoteDesktop_AuthenticationLevel,
     460 + RemoteDesktop_OverrideGatewayServer = instance.RemoteDesktop_OverrideGatewayServer,
     461 + RemoteDesktop_EnableGatewayServer = instance.RemoteDesktop_EnableGatewayServer,
     462 + RemoteDesktop_GatewayServerHostname = instance.RemoteDesktop_GatewayServerHostname,
     463 + RemoteDesktop_GatewayServerBypassLocalAddresses = instance.RemoteDesktop_GatewayServerBypassLocalAddresses,
     464 + RemoteDesktop_GatewayServerLogonMethod = instance.RemoteDesktop_GatewayServerLogonMethod,
     465 + RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = instance.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer,
     466 + RemoteDesktop_UseGatewayServerCredentials = instance.RemoteDesktop_UseGatewayServerCredentials,
     467 + RemoteDesktop_GatewayServerUsername = instance.RemoteDesktop_EnableGatewayServer && Equals(instance.RemoteDesktop_GatewayServerLogonMethod, Models.RemoteDesktop.GatewayUserSelectedCredsSource.Userpass) && instance.RemoteDesktop_UseGatewayServerCredentials ? instance.RemoteDesktop_GatewayServerUsername : string.Empty, // Remove sensitive info on disable
     468 + RemoteDesktop_GatewayServerDomain = instance.RemoteDesktop_EnableGatewayServer && Equals(instance.RemoteDesktop_GatewayServerLogonMethod, Models.RemoteDesktop.GatewayUserSelectedCredsSource.Userpass) && instance.RemoteDesktop_UseGatewayServerCredentials ? instance.RemoteDesktop_GatewayServerDomain : string.Empty, // Remove sensitive info on disable
     469 + RemoteDesktop_GatewayServerPassword = instance.RemoteDesktop_EnableGatewayServer && Equals(instance.RemoteDesktop_GatewayServerLogonMethod, Models.RemoteDesktop.GatewayUserSelectedCredsSource.Userpass) && instance.RemoteDesktop_UseGatewayServerCredentials ? instance.RemoteDesktop_GatewayServerPassword : new SecureString(), // Remove sensitive info on disable
    448 470   RemoteDesktop_OverrideAudioRedirectionMode = instance.RemoteDesktop_OverrideAudioRedirectionMode,
    449 471   RemoteDesktop_AudioRedirectionMode = instance.RemoteDesktop_AudioRedirectionMode,
    450 472   RemoteDesktop_OverrideAudioCaptureRedirectionMode = instance.RemoteDesktop_OverrideAudioCaptureRedirectionMode,
    skipped 68 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/AWSSessionManagerHostViewModel.cs
    skipped 259 lines
    260 260   if (value == _profileWidth)
    261 261   return;
    262 262   
    263  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     263 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    264 264   SettingsManager.Current.AWSSessionManager_ProfileWidth = value.Value;
    265 265   
    266 266   _profileWidth = value;
    skipped 563 lines
    830 830   
    831 831   if (dueToChangedSize)
    832 832   {
    833  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     833 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    834 834   }
    835 835   else
    836 836   {
    837 837   if (ExpandProfileView)
    838 838   {
    839  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     839 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    840 840   }
    841 841   else
    842 842   {
    skipped 155 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/DNSLookupHostViewModel.cs
    skipped 140 lines
    141 141   if (value == _profileWidth)
    142 142   return;
    143 143   
    144  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     144 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    145 145   SettingsManager.Current.DNSLookup_ProfileWidth = value.Value;
    146 146   
    147 147   _profileWidth = value;
    skipped 121 lines
    269 269   
    270 270   if (dueToChangedSize)
    271 271   {
    272  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     272 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    273 273   }
    274 274   else
    275 275   {
    276 276   if (ExpandProfileView)
    277 277   {
    278  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     278 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    279 279   }
    280 280   else
    281 281   {
    skipped 90 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/GroupViewModel.cs
    1  -using NETworkManager.Models.PowerShell;
     1 +using Amazon.EC2.Model;
     2 +using NETworkManager.Models.PowerShell;
    2 3  using NETworkManager.Models.PuTTY;
    3 4  using NETworkManager.Models.RemoteDesktop;
    4 5  using NETworkManager.Profiles;
    skipped 6 lines
    11 12  using System.Security;
    12 13  using System.Windows.Data;
    13 14  using System.Windows.Input;
     15 +using System.Xml.Serialization;
    14 16   
    15 17  namespace NETworkManager.ViewModels;
    16 18   
    skipped 73 lines
    90 92   }
    91 93   }
    92 94   
     95 + private string _remoteDesktop_Domain;
     96 + public string RemoteDesktop_Domain
     97 + {
     98 + get => _remoteDesktop_Domain;
     99 + set
     100 + {
     101 + if (value == _remoteDesktop_Domain)
     102 + return;
     103 + 
     104 + _remoteDesktop_Domain = value;
     105 + OnPropertyChanged();
     106 + }
     107 + }
     108 + 
    93 109   private bool _remoteDesktop_IsPasswordEmpty = true; // Initial it's empty
    94 110   public bool RemoteDesktop_IsPasswordEmpty
    95 111   {
    skipped 9 lines
    105 121   }
    106 122   
    107 123   private SecureString _remoteDesktop_Password;
    108  - 
    109  - /// <summary>
    110  - /// RemoteDesktop password as secure string.
    111  - /// </summary>
    112 124   public SecureString RemoteDesktop_Password
    113 125   {
    114 126   get => _remoteDesktop_Password;
    skipped 256 lines
    371 383   return;
    372 384   
    373 385   _remoteDesktop_AuthenticationLevel = value;
     386 + OnPropertyChanged();
     387 + }
     388 + }
     389 + 
     390 + private bool _remoteDesktop_OverrideGatewayServer;
     391 + public bool RemoteDesktop_OverrideGatewayServer
     392 + {
     393 + get => _remoteDesktop_OverrideGatewayServer;
     394 + set
     395 + {
     396 + if (value == _remoteDesktop_OverrideGatewayServer)
     397 + return;
     398 + 
     399 + _remoteDesktop_OverrideGatewayServer = value;
     400 + OnPropertyChanged();
     401 + }
     402 + }
     403 + 
     404 + private bool _remoteDesktop_EnableGatewayServer;
     405 + public bool RemoteDesktop_EnableGatewayServer
     406 + {
     407 + get => _remoteDesktop_EnableGatewayServer;
     408 + set
     409 + {
     410 + if (value == _remoteDesktop_EnableGatewayServer)
     411 + return;
     412 + 
     413 + _remoteDesktop_EnableGatewayServer = value;
     414 + OnPropertyChanged();
     415 + }
     416 + }
     417 + 
     418 + private string _remoteDesktop_GatewayServerHostname;
     419 + public string RemoteDesktop_GatewayServerHostname
     420 + {
     421 + get => _remoteDesktop_GatewayServerHostname;
     422 + set
     423 + {
     424 + if (value == _remoteDesktop_GatewayServerHostname)
     425 + return;
     426 + 
     427 + _remoteDesktop_GatewayServerHostname = value;
     428 + OnPropertyChanged();
     429 + }
     430 + }
     431 + 
     432 + private bool _remoteDesktop_GatewayServerBypassLocalAddresses;
     433 + public bool RemoteDesktop_GatewayServerBypassLocalAddresses
     434 + {
     435 + get => _remoteDesktop_GatewayServerBypassLocalAddresses;
     436 + set
     437 + {
     438 + if (value == _remoteDesktop_GatewayServerBypassLocalAddresses)
     439 + return;
     440 + 
     441 + _remoteDesktop_GatewayServerBypassLocalAddresses = value;
     442 + OnPropertyChanged();
     443 + }
     444 + }
     445 + 
     446 + public IEnumerable<GatewayUserSelectedCredsSource> RemoteDesktop_GatewayServerLogonMethods => Enum.GetValues(typeof(GatewayUserSelectedCredsSource)).Cast<GatewayUserSelectedCredsSource>();
     447 + 
     448 + private GatewayUserSelectedCredsSource _remoteDesktop_GatewayServerLogonMethod;
     449 + 
     450 + public GatewayUserSelectedCredsSource RemoteDesktop_GatewayServerLogonMethod
     451 + {
     452 + get => _remoteDesktop_GatewayServerLogonMethod;
     453 + set
     454 + {
     455 + if (Equals(value, _remoteDesktop_GatewayServerLogonMethod))
     456 + return;
     457 + 
     458 + _remoteDesktop_GatewayServerLogonMethod = value;
     459 + OnPropertyChanged();
     460 + }
     461 + }
     462 + 
     463 + private bool _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     464 + public bool RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer
     465 + {
     466 + get => _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     467 + set
     468 + {
     469 + if (value == _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer)
     470 + return;
     471 + 
     472 + _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = value;
     473 + OnPropertyChanged();
     474 + }
     475 + }
     476 + 
     477 + private bool _remoteDesktop_UseGatewayServerCredentials;
     478 + public bool RemoteDesktop_UseGatewayServerCredentials
     479 + {
     480 + get => _remoteDesktop_UseGatewayServerCredentials;
     481 + set
     482 + {
     483 + if (value == _remoteDesktop_UseGatewayServerCredentials)
     484 + return;
     485 + 
     486 + _remoteDesktop_UseGatewayServerCredentials = value;
     487 + OnPropertyChanged();
     488 + }
     489 + }
     490 + 
     491 + private string _remoteDesktop_GatewayServerUsername;
     492 + public string RemoteDesktop_GatewayServerUsername
     493 + {
     494 + get => _remoteDesktop_GatewayServerUsername;
     495 + set
     496 + {
     497 + if (value == _remoteDesktop_GatewayServerUsername)
     498 + return;
     499 + 
     500 + _remoteDesktop_GatewayServerUsername = value;
     501 + OnPropertyChanged();
     502 + }
     503 + }
     504 + 
     505 + private string _remoteDesktop_GatewayServerDomain;
     506 + public string RemoteDesktop_GatewayServerDomain
     507 + {
     508 + get => _remoteDesktop_GatewayServerDomain;
     509 + set
     510 + {
     511 + if (value == _remoteDesktop_GatewayServerDomain)
     512 + return;
     513 + 
     514 + _remoteDesktop_GatewayServerDomain = value;
     515 + OnPropertyChanged();
     516 + }
     517 + }
     518 + 
     519 + private bool _remoteDesktop_IsGatewayServerPasswordEmpty = true; // Initial it's empty
     520 + public bool RemoteDesktop_IsGatewayServerPasswordEmpty
     521 + {
     522 + get => _remoteDesktop_IsGatewayServerPasswordEmpty;
     523 + set
     524 + {
     525 + if (value == _remoteDesktop_IsGatewayServerPasswordEmpty)
     526 + return;
     527 + 
     528 + _remoteDesktop_IsGatewayServerPasswordEmpty = value;
     529 + OnPropertyChanged();
     530 + }
     531 + }
     532 + 
     533 + private SecureString _remoteDesktop_GatewayServerPassword;
     534 + public SecureString RemoteDesktop_GatewayServerPassword
     535 + {
     536 + get => _remoteDesktop_GatewayServerPassword;
     537 + set
     538 + {
     539 + if (value == _remoteDesktop_GatewayServerPassword)
     540 + return;
     541 + 
     542 + // Validate the password string
     543 + RemoteDesktop_IsGatewayServerPasswordEmpty = value == null || string.IsNullOrEmpty(SecureStringHelper.ConvertToString(value));
     544 + 
     545 + _remoteDesktop_GatewayServerPassword = value;
     546 + OnPropertyChanged();
     547 + }
     548 + }
     549 + 
     550 + private bool _remoteDesktop_GatewayServerPasswordChanged;
     551 + public bool RemoteDesktop_GatewayServerPasswordChanged
     552 + {
     553 + get => _remoteDesktop_GatewayServerPasswordChanged;
     554 + set
     555 + {
     556 + if (value == _remoteDesktop_GatewayServerPasswordChanged)
     557 + return;
     558 + 
     559 + _remoteDesktop_GatewayServerPasswordChanged = value;
    374 560   OnPropertyChanged();
    375 561   }
    376 562   }
    skipped 881 lines
    1258 1444   // Remote Desktop
    1259 1445   RemoteDesktop_UseCredentials = groupInfo.RemoteDesktop_UseCredentials;
    1260 1446   RemoteDesktop_Username = groupInfo.RemoteDesktop_Username;
     1447 + RemoteDesktop_Domain = groupInfo.RemoteDesktop_Domain;
    1261 1448   RemoteDesktop_Password = groupInfo.RemoteDesktop_Password;
    1262 1449   RemoteDesktop_OverrideDisplay = groupInfo.RemoteDesktop_OverrideDisplay;
    1263 1450   RemoteDesktop_AdjustScreenAutomatically = groupInfo.RemoteDesktop_AdjustScreenAutomatically;
    skipped 11 lines
    1275 1462   RemoteDesktop_EnableCredSspSupport = groupInfo.RemoteDesktop_EnableCredSspSupport;
    1276 1463   RemoteDesktop_OverrideAuthenticationLevel = groupInfo.RemoteDesktop_OverrideAuthenticationLevel;
    1277 1464   RemoteDesktop_AuthenticationLevel = groupInfo.RemoteDesktop_AuthenticationLevel;
     1465 + RemoteDesktop_OverrideGatewayServer = groupInfo.RemoteDesktop_OverrideGatewayServer;
     1466 + RemoteDesktop_EnableGatewayServer = groupInfo.RemoteDesktop_EnableGatewayServer;
     1467 + RemoteDesktop_GatewayServerHostname = groupInfo.RemoteDesktop_GatewayServerHostname;
     1468 + RemoteDesktop_GatewayServerBypassLocalAddresses = groupInfo.RemoteDesktop_GatewayServerBypassLocalAddresses;
     1469 + RemoteDesktop_GatewayServerLogonMethod = groupInfo.RemoteDesktop_GatewayServerLogonMethod;
     1470 + RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = groupInfo.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     1471 + RemoteDesktop_UseGatewayServerCredentials = groupInfo.RemoteDesktop_UseGatewayServerCredentials;
     1472 + RemoteDesktop_GatewayServerUsername = groupInfo.RemoteDesktop_GatewayServerUsername;
     1473 + RemoteDesktop_GatewayServerDomain = groupInfo.RemoteDesktop_GatewayServerDomain;
     1474 + RemoteDesktop_GatewayServerPassword = groupInfo.RemoteDesktop_GatewayServerPassword;
    1278 1475   RemoteDesktop_OverrideAudioRedirectionMode = groupInfo.RemoteDesktop_OverrideAudioRedirectionMode;
    1279 1476   RemoteDesktop_AudioRedirectionMode = RemoteDesktop_AudioRedirectionModes.FirstOrDefault(x => x == groupInfo.RemoteDesktop_AudioRedirectionMode);
    1280 1477   RemoteDesktop_OverrideAudioCaptureRedirectionMode = groupInfo.RemoteDesktop_OverrideAudioCaptureRedirectionMode;
    skipped 71 lines
    1352 1549   public ICommand CancelCommand { get; }
    1353 1550   
    1354 1551   public ICommand RemoteDesktopPasswordChangedCommand => new RelayCommand(p => RemoteDesktopPasswordChangedAction());
    1355  - #endregion
    1356 1552   
    1357  - #region Methods
    1358 1553   private void RemoteDesktopPasswordChangedAction()
    1359 1554   {
    1360 1555   RemoteDesktop_PasswordChanged = true;
    1361 1556   }
    1362 1557   
     1558 + public ICommand RemoteDesktopGatewayServerPasswordChangedCommand => new RelayCommand(p => RemoteDesktopGatewayServerPasswordChangedAction());
     1559 + 
     1560 + private void RemoteDesktopGatewayServerPasswordChangedAction()
     1561 + {
     1562 + RemoteDesktop_GatewayServerPasswordChanged = true;
     1563 + }
     1564 + #endregion
     1565 + 
     1566 + #region Methods
    1363 1567   private void ChangeNetworkConnectionTypeSettings(NetworkConnectionType connectionSpeed)
    1364 1568   {
    1365 1569   switch (connectionSpeed)
    skipped 39 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/IPScannerHostViewModel.cs
    skipped 140 lines
    141 141   if (value == _profileWidth)
    142 142   return;
    143 143   
    144  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     144 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    145 145   SettingsManager.Current.IPScanner_ProfileWidth = value.Value;
    146 146   
    147 147   _profileWidth = value;
    skipped 121 lines
    269 269   
    270 270   if (dueToChangedSize)
    271 271   {
    272  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     272 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    273 273   }
    274 274   else
    275 275   {
    276 276   if (ExpandProfileView)
    277 277   {
    278  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     278 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    279 279   }
    280 280   else
    281 281   {
    skipped 95 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/NetworkInterfaceViewModel.cs
    skipped 503 lines
    504 504   if (value == _profileWidth)
    505 505   return;
    506 506   
    507  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     507 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    508 508   SettingsManager.Current.NetworkInterface_ProfileWidth = value.Value;
    509 509   
    510 510   _profileWidth = value;
    skipped 562 lines
    1073 1073   
    1074 1074   if (dueToChangedSize)
    1075 1075   {
    1076  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     1076 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    1077 1077   }
    1078 1078   else
    1079 1079   {
    1080 1080   if (ExpandProfileView)
    1081 1081   {
    1082  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     1082 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    1083 1083   }
    1084 1084   else
    1085 1085   {
    skipped 186 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/PingMonitorHostViewModel.cs
    skipped 209 lines
    210 210   if (value == _profileWidth)
    211 211   return;
    212 212   
    213  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     213 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    214 214   SettingsManager.Current.PingMonitor_ProfileWidth = value.Value;
    215 215   
    216 216   _profileWidth = value;
    skipped 212 lines
    429 429   
    430 430   if (dueToChangedSize)
    431 431   {
    432  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     432 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    433 433   }
    434 434   else
    435 435   {
    436 436   if (ExpandProfileView)
    437 437   {
    438  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     438 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    439 439   }
    440 440   else
    441 441   {
    skipped 105 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/PortScannerHostViewModel.cs
    skipped 140 lines
    141 141   if (value == _profileWidth)
    142 142   return;
    143 143   
    144  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     144 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    145 145   SettingsManager.Current.PortScanner_ProfileWidth = value.Value;
    146 146   
    147 147   _profileWidth = value;
    skipped 121 lines
    269 269   
    270 270   if (dueToChangedSize)
    271 271   {
    272  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     272 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    273 273   }
    274 274   else
    275 275   {
    276 276   if (ExpandProfileView)
    277 277   {
    278  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     278 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    279 279   }
    280 280   else
    281 281   {
    skipped 96 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/PowerShellHostViewModel.cs
    skipped 192 lines
    193 193   if (value == _profileWidth)
    194 194   return;
    195 195   
    196  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     196 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    197 197   SettingsManager.Current.PowerShell_ProfileWidth = value.Value;
    198 198   
    199 199   _profileWidth = value;
    skipped 295 lines
    495 495   
    496 496   if (dueToChangedSize)
    497 497   {
    498  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     498 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    499 499   }
    500 500   else
    501 501   {
    502 502   if (ExpandProfileView)
    503 503   {
    504  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     504 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    505 505   }
    506 506   else
    507 507   {
    skipped 106 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/ProfileViewModel.cs
    skipped 13 lines
    14 14  using NETworkManager.Models.PuTTY;
    15 15  using System.Security;
    16 16  using NETworkManager.Models;
     17 +using Microsoft.PowerShell.Commands;
    17 18   
    18 19  namespace NETworkManager.ViewModels;
    19 20   
    skipped 558 lines
    578 579   }
    579 580   }
    580 581   
     582 + private string _remoteDesktop_Domain;
     583 + public string RemoteDesktop_Domain
     584 + {
     585 + get => _remoteDesktop_Domain;
     586 + set
     587 + {
     588 + if (value == _remoteDesktop_Domain)
     589 + return;
     590 + 
     591 + _remoteDesktop_Domain = value;
     592 + OnPropertyChanged();
     593 + }
     594 + }
     595 + 
    581 596   private bool _remoteDesktop_IsPasswordEmpty = true; // Initial it's empty
    582 597   public bool RemoteDesktop_IsPasswordEmpty
    583 598   {
    skipped 9 lines
    593 608   }
    594 609   
    595 610   private SecureString _remoteDesktop_Password;
    596  - 
    597  - /// <summary>
    598  - /// RemoteDesktop password as secure string.
    599  - /// </summary>
    600 611   public SecureString RemoteDesktop_Password
    601 612   {
    602 613   get => _remoteDesktop_Password;
    skipped 256 lines
    859 870   return;
    860 871   
    861 872   _remoteDesktop_AuthenticationLevel = value;
     873 + OnPropertyChanged();
     874 + }
     875 + }
     876 + 
     877 + private bool _remoteDesktop_OverrideGatewayServer;
     878 + public bool RemoteDesktop_OverrideGatewayServer
     879 + {
     880 + get => _remoteDesktop_OverrideGatewayServer;
     881 + set
     882 + {
     883 + if (value == _remoteDesktop_OverrideGatewayServer)
     884 + return;
     885 + 
     886 + _remoteDesktop_OverrideGatewayServer = value;
     887 + OnPropertyChanged();
     888 + }
     889 + }
     890 + 
     891 + private bool _remoteDesktop_EnableGatewayServer;
     892 + public bool RemoteDesktop_EnableGatewayServer
     893 + {
     894 + get => _remoteDesktop_EnableGatewayServer;
     895 + set
     896 + {
     897 + if (value == _remoteDesktop_EnableGatewayServer)
     898 + return;
     899 + 
     900 + _remoteDesktop_EnableGatewayServer = value;
     901 + OnPropertyChanged();
     902 + }
     903 + }
     904 + 
     905 + private string _remoteDesktop_GatewayServerHostname;
     906 + public string RemoteDesktop_GatewayServerHostname
     907 + {
     908 + get => _remoteDesktop_GatewayServerHostname;
     909 + set
     910 + {
     911 + if (value == _remoteDesktop_GatewayServerHostname)
     912 + return;
     913 + 
     914 + _remoteDesktop_GatewayServerHostname = value;
     915 + OnPropertyChanged();
     916 + }
     917 + }
     918 + 
     919 + private bool _remoteDesktop_GatewayServerBypassLocalAddresses;
     920 + public bool RemoteDesktop_GatewayServerBypassLocalAddresses
     921 + {
     922 + get => _remoteDesktop_GatewayServerBypassLocalAddresses;
     923 + set
     924 + {
     925 + if (value == _remoteDesktop_GatewayServerBypassLocalAddresses)
     926 + return;
     927 + 
     928 + _remoteDesktop_GatewayServerBypassLocalAddresses = value;
     929 + OnPropertyChanged();
     930 + }
     931 + }
     932 + 
     933 + public IEnumerable<GatewayUserSelectedCredsSource> RemoteDesktop_GatewayServerLogonMethods => Enum.GetValues(typeof(GatewayUserSelectedCredsSource)).Cast<GatewayUserSelectedCredsSource>();
     934 + 
     935 + private GatewayUserSelectedCredsSource _remoteDesktop_GatewayServerLogonMethod;
     936 + 
     937 + public GatewayUserSelectedCredsSource RemoteDesktop_GatewayServerLogonMethod
     938 + {
     939 + get => _remoteDesktop_GatewayServerLogonMethod;
     940 + set
     941 + {
     942 + if (Equals(value, _remoteDesktop_GatewayServerLogonMethod))
     943 + return;
     944 + 
     945 + _remoteDesktop_GatewayServerLogonMethod = value;
     946 + OnPropertyChanged();
     947 + }
     948 + }
     949 + 
     950 + private bool _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     951 + public bool RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer
     952 + {
     953 + get => _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     954 + set
     955 + {
     956 + if (value == _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer)
     957 + return;
     958 + 
     959 + _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = value;
     960 + OnPropertyChanged();
     961 + }
     962 + }
     963 + 
     964 + private bool _remoteDesktop_UseGatewayServerCredentials;
     965 + public bool RemoteDesktop_UseGatewayServerCredentials
     966 + {
     967 + get => _remoteDesktop_UseGatewayServerCredentials;
     968 + set
     969 + {
     970 + if (value == _remoteDesktop_UseGatewayServerCredentials)
     971 + return;
     972 + 
     973 + _remoteDesktop_UseGatewayServerCredentials = value;
     974 + OnPropertyChanged();
     975 + }
     976 + }
     977 + 
     978 + private string _remoteDesktop_GatewayServerUsername;
     979 + public string RemoteDesktop_GatewayServerUsername
     980 + {
     981 + get => _remoteDesktop_GatewayServerUsername;
     982 + set
     983 + {
     984 + if (value == _remoteDesktop_GatewayServerUsername)
     985 + return;
     986 + 
     987 + _remoteDesktop_GatewayServerUsername = value;
     988 + OnPropertyChanged();
     989 + }
     990 + }
     991 + 
     992 + private string _remoteDesktop_GatewayServerDomain;
     993 + public string RemoteDesktop_GatewayServerDomain
     994 + {
     995 + get => _remoteDesktop_GatewayServerDomain;
     996 + set
     997 + {
     998 + if (value == _remoteDesktop_GatewayServerDomain)
     999 + return;
     1000 + 
     1001 + _remoteDesktop_GatewayServerDomain = value;
     1002 + OnPropertyChanged();
     1003 + }
     1004 + }
     1005 + 
     1006 + private bool _remoteDesktop_IsGatewayServerPasswordEmpty = true; // Initial it's empty
     1007 + public bool RemoteDesktop_IsGatewayServerPasswordEmpty
     1008 + {
     1009 + get => _remoteDesktop_IsGatewayServerPasswordEmpty;
     1010 + set
     1011 + {
     1012 + if (value == _remoteDesktop_IsGatewayServerPasswordEmpty)
     1013 + return;
     1014 + 
     1015 + _remoteDesktop_IsGatewayServerPasswordEmpty = value;
     1016 + OnPropertyChanged();
     1017 + }
     1018 + }
     1019 + 
     1020 + private SecureString _remoteDesktop_GatewayServerPassword;
     1021 + public SecureString RemoteDesktop_GatewayServerPassword
     1022 + {
     1023 + get => _remoteDesktop_GatewayServerPassword;
     1024 + set
     1025 + {
     1026 + if (value == _remoteDesktop_GatewayServerPassword)
     1027 + return;
     1028 + 
     1029 + // Validate the password string
     1030 + RemoteDesktop_IsGatewayServerPasswordEmpty = value == null || string.IsNullOrEmpty(SecureStringHelper.ConvertToString(value));
     1031 + 
     1032 + _remoteDesktop_GatewayServerPassword = value;
     1033 + OnPropertyChanged();
     1034 + }
     1035 + }
     1036 + 
     1037 + private bool _remoteDesktop_GatewayServerPasswordChanged;
     1038 + public bool RemoteDesktop_GatewayServerPasswordChanged
     1039 + {
     1040 + get => _remoteDesktop_GatewayServerPasswordChanged;
     1041 + set
     1042 + {
     1043 + if (value == _remoteDesktop_GatewayServerPasswordChanged)
     1044 + return;
     1045 + 
     1046 + _remoteDesktop_GatewayServerPasswordChanged = value;
    862 1047   OnPropertyChanged();
    863 1048   }
    864 1049   }
    skipped 1421 lines
    2286 2471   RemoteDesktop_Host = profileInfo.RemoteDesktop_Host;
    2287 2472   RemoteDesktop_UseCredentials = profileInfo.RemoteDesktop_UseCredentials;
    2288 2473   RemoteDesktop_Username = profileInfo.RemoteDesktop_Username;
     2474 + RemoteDesktop_Domain = profileInfo.RemoteDesktop_Domain;
    2289 2475   RemoteDesktop_Password = profileInfo.RemoteDesktop_Password;
    2290 2476   RemoteDesktop_OverrideDisplay = profileInfo.RemoteDesktop_OverrideDisplay;
    2291 2477   RemoteDesktop_AdjustScreenAutomatically = profileInfo.RemoteDesktop_AdjustScreenAutomatically;
    skipped 11 lines
    2303 2489   RemoteDesktop_EnableCredSspSupport = profileInfo.RemoteDesktop_EnableCredSspSupport;
    2304 2490   RemoteDesktop_OverrideAuthenticationLevel = profileInfo.RemoteDesktop_OverrideAuthenticationLevel;
    2305 2491   RemoteDesktop_AuthenticationLevel = profileInfo.RemoteDesktop_AuthenticationLevel;
     2492 + RemoteDesktop_OverrideGatewayServer = profileInfo.RemoteDesktop_OverrideGatewayServer;
     2493 + RemoteDesktop_EnableGatewayServer = profileInfo.RemoteDesktop_EnableGatewayServer;
     2494 + RemoteDesktop_GatewayServerHostname = profileInfo.RemoteDesktop_GatewayServerHostname;
     2495 + RemoteDesktop_GatewayServerBypassLocalAddresses = profileInfo.RemoteDesktop_GatewayServerBypassLocalAddresses;
     2496 + RemoteDesktop_GatewayServerLogonMethod = profileInfo.RemoteDesktop_GatewayServerLogonMethod;
     2497 + RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = profileInfo.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     2498 + RemoteDesktop_UseGatewayServerCredentials = profileInfo.RemoteDesktop_UseGatewayServerCredentials;
     2499 + RemoteDesktop_GatewayServerUsername = profileInfo.RemoteDesktop_GatewayServerUsername;
     2500 + RemoteDesktop_GatewayServerDomain = profileInfo.RemoteDesktop_GatewayServerDomain;
     2501 + RemoteDesktop_GatewayServerPassword = profileInfo.RemoteDesktop_GatewayServerPassword;
    2306 2502   RemoteDesktop_OverrideAudioRedirectionMode = profileInfo.RemoteDesktop_OverrideAudioRedirectionMode;
    2307 2503   RemoteDesktop_AudioRedirectionMode = RemoteDesktop_AudioRedirectionModes.FirstOrDefault(x => x == profileInfo.RemoteDesktop_AudioRedirectionMode);
    2308 2504   RemoteDesktop_OverrideAudioCaptureRedirectionMode = profileInfo.RemoteDesktop_OverrideAudioCaptureRedirectionMode;
    skipped 140 lines
    2449 2645   
    2450 2646   public ICommand RemoteDesktopPasswordChangedCommand => new RelayCommand(p => RemoteDesktopPasswordChangedAction());
    2451 2647   
    2452  - #endregion
    2453  - 
    2454  - #region Methods
    2455 2648   private void RemoteDesktopPasswordChangedAction()
    2456 2649   {
    2457 2650   RemoteDesktop_PasswordChanged = true;
    2458 2651   }
    2459 2652   
     2653 + public ICommand RemoteDesktopGatewayServerPasswordChangedCommand => new RelayCommand(p => RemoteDesktopGatewayServerPasswordChangedAction());
     2654 + 
     2655 + private void RemoteDesktopGatewayServerPasswordChangedAction()
     2656 + {
     2657 + RemoteDesktop_GatewayServerPasswordChanged = true;
     2658 + }
     2659 + #endregion
     2660 + 
     2661 + #region Methods
    2460 2662   private void ChangeNetworkConnectionTypeSettings(NetworkConnectionType connectionSpeed)
    2461 2663   {
    2462 2664   switch (connectionSpeed)
    skipped 39 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/PuTTYHostViewModel.cs
    skipped 192 lines
    193 193   if (value == _profileWidth)
    194 194   return;
    195 195   
    196  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     196 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    197 197   SettingsManager.Current.PuTTY_ProfileWidth = value.Value;
    198 198   
    199 199   _profileWidth = value;
    skipped 374 lines
    574 574   
    575 575   if (dueToChangedSize)
    576 576   {
    577  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     577 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    578 578   }
    579 579   else
    580 580   {
    581 581   if (ExpandProfileView)
    582 582   {
    583  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     583 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    584 584   }
    585 585   else
    586 586   {
    skipped 116 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/RemoteDesktopHostViewModel.cs
    skipped 141 lines
    142 142   if (value == _profileWidth)
    143 143   return;
    144 144   
    145  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     145 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    146 146   SettingsManager.Current.RemoteDesktop_ProfileWidth = value.Value;
    147 147   
    148 148   _profileWidth = value;
    skipped 230 lines
    379 379   
    380 380   if (instance.UseCredentials)
    381 381   {
    382  - sessionInfo.CustomCredentials = true;
     382 + sessionInfo.UseCredentials = true;
    383 383   
    384 384   sessionInfo.Username = instance.Username;
    385 385   sessionInfo.Password = instance.Password;
    skipped 52 lines
    438 438   
    439 439   if (instance.UseCredentials)
    440 440   {
    441  - sessionInfo.CustomCredentials = true;
     441 + sessionInfo.UseCredentials = true;
    442 442   sessionInfo.Username = instance.Username;
    443 443   sessionInfo.Password = instance.Password;
    444 444   }
    skipped 48 lines
    493 493   
    494 494   if (dueToChangedSize)
    495 495   {
    496  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     496 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    497 497   }
    498 498   else
    499 499   {
    500 500   if (ExpandProfileView)
    501 501   {
    502  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     502 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    503 503   }
    504 504   else
    505 505   {
    skipped 92 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/RemoteDesktopSettingsViewModel.cs
    skipped 205 lines
    206 206   }
    207 207   }
    208 208   
     209 + private bool _enableGatewayServer;
     210 + public bool EnableGatewayServer
     211 + {
     212 + get => _enableGatewayServer;
     213 + set
     214 + {
     215 + if (value == _enableGatewayServer)
     216 + return;
     217 + 
     218 + if (!_isLoading)
     219 + SettingsManager.Current.RemoteDesktop_EnableGatewayServer = value;
     220 + 
     221 + _enableGatewayServer = value;
     222 + OnPropertyChanged();
     223 + }
     224 + }
     225 + 
     226 + private string _gatewayServerHostname;
     227 + public string GatewayServerHostname
     228 + {
     229 + get => _gatewayServerHostname;
     230 + set
     231 + {
     232 + if (value == _gatewayServerHostname)
     233 + return;
     234 + 
     235 + if (!_isLoading)
     236 + SettingsManager.Current.RemoteDesktop_GatewayServerHostname = value;
     237 + 
     238 + _gatewayServerHostname = value;
     239 + OnPropertyChanged();
     240 + }
     241 + }
     242 + 
     243 + private bool _gatewayServerBypassLocalAddresses;
     244 + public bool GatewayServerBypassLocalAddresses
     245 + {
     246 + get => _gatewayServerBypassLocalAddresses;
     247 + set
     248 + {
     249 + if (value == _gatewayServerBypassLocalAddresses)
     250 + return;
     251 + 
     252 + if (!_isLoading)
     253 + SettingsManager.Current.RemoteDesktop_GatewayServerBypassLocalAddresses = value;
     254 + 
     255 + _gatewayServerBypassLocalAddresses = value;
     256 + OnPropertyChanged();
     257 + }
     258 + }
     259 + 
     260 + public IEnumerable<GatewayUserSelectedCredsSource> GatewayServerLogonMethods => System.Enum.GetValues(typeof(GatewayUserSelectedCredsSource)).Cast<GatewayUserSelectedCredsSource>();
     261 + 
     262 + private GatewayUserSelectedCredsSource _gatewayServerLogonMethod;
     263 + 
     264 + public GatewayUserSelectedCredsSource GatewayServerLogonMethod
     265 + {
     266 + get => _gatewayServerLogonMethod;
     267 + set
     268 + {
     269 + if (Equals(value, _gatewayServerLogonMethod))
     270 + return;
     271 + 
     272 + if (!_isLoading)
     273 + SettingsManager.Current.RemoteDesktop_GatewayServerLogonMethod = value;
     274 + 
     275 + _gatewayServerLogonMethod = value;
     276 + OnPropertyChanged();
     277 + }
     278 + }
     279 + 
     280 + private bool _gatewayServerShareCredentialsWithRemoteComputer;
     281 + public bool GatewayServerShareCredentialsWithRemoteComputer
     282 + {
     283 + get => _gatewayServerShareCredentialsWithRemoteComputer;
     284 + set
     285 + {
     286 + if (value == _gatewayServerShareCredentialsWithRemoteComputer)
     287 + return;
     288 + 
     289 + if (!_isLoading)
     290 + SettingsManager.Current.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = value;
     291 + 
     292 + _gatewayServerShareCredentialsWithRemoteComputer = value;
     293 + OnPropertyChanged();
     294 + }
     295 + }
     296 + 
    209 297   public IEnumerable<AudioRedirectionMode> AudioRedirectionModes => System.Enum.GetValues(typeof(AudioRedirectionMode)).Cast<AudioRedirectionMode>();
    210 298   
    211 299   private AudioRedirectionMode _audioRedirectionMode;
    skipped 334 lines
    546 634   Port = SettingsManager.Current.RemoteDesktop_Port;
    547 635   EnableCredSspSupport = SettingsManager.Current.RemoteDesktop_EnableCredSspSupport;
    548 636   AuthenticationLevel = SettingsManager.Current.RemoteDesktop_AuthenticationLevel;
     637 + EnableGatewayServer = SettingsManager.Current.RemoteDesktop_EnableGatewayServer;
     638 + GatewayServerHostname = SettingsManager.Current.RemoteDesktop_GatewayServerHostname;
     639 + GatewayServerBypassLocalAddresses = SettingsManager.Current.RemoteDesktop_GatewayServerBypassLocalAddresses;
     640 + GatewayServerLogonMethod = GatewayServerLogonMethods.FirstOrDefault(x => x == SettingsManager.Current.RemoteDesktop_GatewayServerLogonMethod);
     641 + GatewayServerShareCredentialsWithRemoteComputer = SettingsManager.Current.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
    549 642   AudioRedirectionMode = AudioRedirectionModes.FirstOrDefault(x => x == SettingsManager.Current.RemoteDesktop_AudioRedirectionMode);
    550 643   AudioCaptureRedirectionMode = AudioCaptureRedirectionModes.FirstOrDefault(x => x == SettingsManager.Current.RemoteDesktop_AudioCaptureRedirectionMode);
    551 644   KeyboardHookMode = KeyboardHookModes.FirstOrDefault(x => x == SettingsManager.Current.RemoteDesktop_KeyboardHookMode);
    skipped 61 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/TigerVNCHostViewModel.cs
    skipped 157 lines
    158 158   if (value == _profileWidth)
    159 159   return;
    160 160   
    161  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     161 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    162 162   SettingsManager.Current.TigerVNC_ProfileWidth = value.Value;
    163 163   
    164 164   _profileWidth = value;
    skipped 247 lines
    412 412   
    413 413   if (dueToChangedSize)
    414 414   {
    415  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     415 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    416 416   }
    417 417   else
    418 418   {
    419 419   if (ExpandProfileView)
    420 420   {
    421  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     421 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    422 422   }
    423 423   else
    424 424   {
    skipped 91 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/TracerouteHostViewModel.cs
    skipped 140 lines
    141 141   if (value == _profileWidth)
    142 142   return;
    143 143   
    144  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     144 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    145 145   SettingsManager.Current.Traceroute_ProfileWidth = value.Value;
    146 146   
    147 147   _profileWidth = value;
    skipped 121 lines
    269 269   
    270 270   if (dueToChangedSize)
    271 271   {
    272  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     272 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    273 273   }
    274 274   else
    275 275   {
    276 276   if (ExpandProfileView)
    277 277   {
    278  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     278 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    279 279   }
    280 280   else
    281 281   {
    skipped 95 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/WakeOnLANViewModel.cs
    skipped 201 lines
    202 202   if (value == _profileWidth)
    203 203   return;
    204 204   
    205  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     205 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    206 206   SettingsManager.Current.WakeOnLAN_ProfileWidth = value.Value;
    207 207   
    208 208   _profileWidth = value;
    skipped 168 lines
    377 377   
    378 378   if (dueToChangedSize)
    379 379   {
    380  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     380 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    381 381   }
    382 382   else
    383 383   {
    384 384   if (ExpandProfileView)
    385 385   {
    386  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     386 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    387 387   }
    388 388   else
    389 389   {
    skipped 82 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/WebConsoleHostViewModel.cs
    skipped 163 lines
    164 164   if (value == _profileWidth)
    165 165   return;
    166 166   
    167  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     167 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    168 168   SettingsManager.Current.WebConsole_ProfileWidth = value.Value;
    169 169   
    170 170   _profileWidth = value;
    skipped 219 lines
    390 390   
    391 391   if (dueToChangedSize)
    392 392   {
    393  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     393 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    394 394   }
    395 395   else
    396 396   {
    397 397   if (ExpandProfileView)
    398 398   {
    399  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     399 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    400 400   }
    401 401   else
    402 402   {
    skipped 91 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/ViewModels/WhoisHostViewModel.cs
    skipped 140 lines
    141 141   if (value == _profileWidth)
    142 142   return;
    143 143   
    144  - if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
     144 + if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix) // Do not save the size when collapsed
    145 145   SettingsManager.Current.Whois_ProfileWidth = value.Value;
    146 146   
    147 147   _profileWidth = value;
    skipped 122 lines
    270 270   
    271 271   if (dueToChangedSize)
    272 272   {
    273  - ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.FloatPointFix;
     273 + ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) > GlobalStaticConfiguration.Profile_FloatPointFix;
    274 274   }
    275 275   else
    276 276   {
    277 277   if (ExpandProfileView)
    278 278   {
    279  - ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
     279 + ProfileWidth = Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) < GlobalStaticConfiguration.Profile_FloatPointFix ? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded) : new GridLength(_tempProfileWidth);
    280 280   }
    281 281   else
    282 282   {
    skipped 90 lines
  • ■ ■ ■ ■ ■
    Source/NETworkManager/Views/GroupDialog.xaml
    skipped 18 lines
    19 19   <converters:RemoteDesktopAudioCaptureRedirectionModeToStringConverter x:Key="RemoteDesktopAudioCaptureRedirectionModeToStringConverter" />
    20 20   <converters:RemoteDesktopAudioRedirectionModeToStringConverter x:Key="RemoteDesktopAudioRedirectionModeToStringConverter" />
    21 21   <converters:RemoteDesktopKeyboardHookModeToStringConverter x:Key="RemoteDesktopKeyboardHookModeToStringConverter" />
     22 + <converters:RemoteDesktopGatewayServerLogonMethodToStringConverter x:Key="RemoteDesktopGatewayServerLogonMethodToStringConverter" />
    22 23   <converters:RemoteDesktopNetworkConnectionTypeToStringConverter x:Key="RemoteDesktopNetworkConnectionTypeToStringConverter" />
    23 24   <converters:GroupViewNameToTranslatedStringConverter x:Key="GroupViewNameToTranslatedStringConverter" />
    24 25   <converters:PuTTYLogModeToStringConverter x:Key="PuTTYLogModeToStringConverter" />
    skipped 230 lines
    255 256   <RowDefinition Height="Auto" />
    256 257   <RowDefinition Height="10" />
    257 258   <RowDefinition Height="Auto" />
     259 + <RowDefinition Height="10" />
     260 + <RowDefinition Height="Auto" />
     261 + <RowDefinition Height="10" />
     262 + <RowDefinition Height="Auto" />
     263 + <RowDefinition Height="10" />
     264 + <RowDefinition Height="Auto" />
     265 + <RowDefinition Height="10" />
     266 + <RowDefinition Height="Auto" />
     267 + <RowDefinition Height="10" />
     268 + <RowDefinition Height="Auto" />
     269 + <RowDefinition Height="10" />
     270 + <RowDefinition Height="Auto" />
     271 + <RowDefinition Height="10" />
     272 + <RowDefinition Height="Auto" />
     273 + <RowDefinition Height="10" />
     274 + <RowDefinition Height="Auto" />
     275 + <RowDefinition Height="10" />
     276 + <RowDefinition Height="Auto" />
     277 + <RowDefinition Height="10" />
     278 + <RowDefinition Height="Auto" />
    258 279   </Grid.RowDefinitions>
    259 280   <Grid.ColumnDefinitions>
    260 281   <ColumnDefinition Width="1*" />
    skipped 14 lines
    275 296   </Binding>
    276 297   </TextBox.Text>
    277 298   </TextBox>
    278  - <TextBlock Grid.Column="0" Grid.Row="4" Text="{x:Static localization:Strings.Password}" />
    279  - <PasswordBox Grid.Column="2" Grid.Row="4" x:Name="PasswordBoxRemoteDesktopPassword" IsEnabled="{Binding RemoteDesktop_UseCredentials}">
     299 + <TextBlock Grid.Column="0" Grid.Row="4" Text="{x:Static localization:Strings.Domain}" />
     300 + <TextBox Grid.Column="2" Grid.Row="4" x:Name="TextBoxRemoteDesktopDomain" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleDomain}" IsEnabled="{Binding RemoteDesktop_UseCredentials}" Style="{StaticResource DefaultTextBox}">
     301 + <TextBox.Text>
     302 + <Binding Path="RemoteDesktop_Domain" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     303 + <Binding.ValidationRules>
     304 + <validators:EmptyOrWindowsDomainValidator ValidatesOnTargetUpdated="True" />
     305 + </Binding.ValidationRules>
     306 + </Binding>
     307 + </TextBox.Text>
     308 + </TextBox>
     309 + <TextBlock Grid.Column="0" Grid.Row="6" Text="{x:Static localization:Strings.Password}" />
     310 + <PasswordBox Grid.Column="2" Grid.Row="6" x:Name="PasswordBoxRemoteDesktopPassword" IsEnabled="{Binding RemoteDesktop_UseCredentials}">
    280 311   <PasswordBox.Style>
    281 312   <Style TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource DefaultPasswordBox}">
    282 313   <Setter Property="mah:TextBoxHelper.Watermark" Value="{x:Static localization:Strings.NotChanged}" />
    skipped 16 lines
    299 330   </interactivity:EventTrigger>
    300 331   </interactivity:Interaction.Triggers>
    301 332   </PasswordBox>
    302  - <Rectangle Width="24" Height="24" Grid.Column="3" Grid.Row="4" ToolTip="{x:Static localization:Strings.WarningMessage_ProfileFileNotEncryptedStoringPasswords}" Visibility="{Binding IsProfileFileEncrypted, Converter={StaticResource BooleanReverseToVisibilityCollapsedConverter}}" Style="{StaticResource WarnImageRectangle}" Margin="10,0,0,0">
     333 + <Rectangle Width="24" Height="24" Grid.Column="3" Grid.Row="6" ToolTip="{x:Static localization:Strings.WarningMessage_ProfileFileNotEncryptedStoringPasswords}" Visibility="{Binding IsProfileFileEncrypted, Converter={StaticResource BooleanReverseToVisibilityCollapsedConverter}}" Style="{StaticResource WarnImageRectangle}" Margin="10,0,0,0">
    303 334   <Rectangle.Resources>
    304 335   <Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource HelpToolTip}" />
    305 336   </Rectangle.Resources>
    306 337   </Rectangle>
    307  - <TextBlock Grid.Column="0" Grid.Row="6" Grid.ColumnSpan="4" Text="{x:Static localization:Strings.OverrideDefaultSettings}" Style="{StaticResource HeaderTextBlock}" Margin="0,10,0,0"/>
    308  - <Separator Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="4" Background="{DynamicResource MahApps.Brushes.Gray8}" Margin="0,0,0,10" />
    309  - <CheckBox Grid.Column="0" Grid.Row="10" VerticalAlignment="Top" Content="{x:Static localization:Strings.Display}" IsChecked="{Binding RemoteDesktop_OverrideDisplay}" Style="{StaticResource DefaultCheckBox}" />
    310  - <StackPanel Grid.Column="2" Grid.Row="10" IsEnabled="{Binding RemoteDesktop_OverrideDisplay}">
     338 + <TextBlock Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="4" Text="{x:Static localization:Strings.OverrideDefaultSettings}" Style="{StaticResource HeaderTextBlock}" Margin="0,10,0,0"/>
     339 + <Separator Grid.Column="0" Grid.Row="10" Grid.ColumnSpan="4" Background="{DynamicResource MahApps.Brushes.Gray8}" Margin="0,0,0,10" />
     340 + <CheckBox Grid.Column="0" Grid.Row="12" VerticalAlignment="Top" Content="{x:Static localization:Strings.Display}" IsChecked="{Binding RemoteDesktop_OverrideDisplay}" Style="{StaticResource DefaultCheckBox}" />
     341 + <StackPanel Grid.Column="2" Grid.Row="12" IsEnabled="{Binding RemoteDesktop_OverrideDisplay}">
    311 342   <RadioButton x:Name="RadioButtonAdjustScreenAutomatically" Content="{x:Static localization:Strings.AdjustScreenAutomatically}" IsChecked="{Binding RemoteDesktop_AdjustScreenAutomatically}" Margin="0,0,0,10" />
    312 343   <RadioButton x:Name="RadioButtonUseCurrentViewSize" Content="{x:Static localization:Strings.UseCurrentViewSize}" IsChecked="{Binding RemoteDesktop_UseCurrentViewSize}" Margin="0,0,0,10" />
    313 344   <RadioButton x:Name="RadioButtonFixedScreenSize" Content="{x:Static localization:Strings.FixedScreenSize}" IsChecked="{Binding RemoteDesktop_UseFixedScreenSize}" Margin="0,0,0,10" />
    skipped 41 lines
    355 386   </Grid>
    356 387   </GroupBox>
    357 388   </StackPanel>
    358  - <CheckBox Grid.Column="0" Grid.Row="12" Content="{x:Static localization:Strings.ColorDepthBit}" IsChecked="{Binding RemoteDesktop_OverrideColorDepth}" Style="{StaticResource DefaultCheckBox}" />
    359  - <ComboBox Grid.Column="2" Grid.Row="12" ItemsSource="{Binding RemoteDesktop_ColorDepths}" SelectedItem="{Binding RemoteDesktop_SelectedColorDepth}" IsEnabled="{Binding RemoteDesktop_OverrideColorDepth}"/>
    360  - <CheckBox Grid.Column="0" Grid.Row="14" Content="{x:Static localization:Strings.Port}" IsChecked="{Binding RemoteDesktop_OverridePort}" Style="{StaticResource DefaultCheckBox}" />
    361  - <TextBox Grid.Column="2" Grid.Row="14" x:Name="TextBoxRemoteDesktopPort" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExamplePort3389}" IsEnabled="{Binding RemoteDesktop_OverridePort}" Style="{StaticResource DefaultTextBox}">
     389 + <CheckBox Grid.Column="0" Grid.Row="14" Content="{x:Static localization:Strings.ColorDepthBit}" IsChecked="{Binding RemoteDesktop_OverrideColorDepth}" Style="{StaticResource DefaultCheckBox}" />
     390 + <ComboBox Grid.Column="2" Grid.Row="14" ItemsSource="{Binding RemoteDesktop_ColorDepths}" SelectedItem="{Binding RemoteDesktop_SelectedColorDepth}" IsEnabled="{Binding RemoteDesktop_OverrideColorDepth}"/>
     391 + <CheckBox Grid.Column="0" Grid.Row="16" Content="{x:Static localization:Strings.Port}" IsChecked="{Binding RemoteDesktop_OverridePort}" Style="{StaticResource DefaultCheckBox}" />
     392 + <TextBox Grid.Column="2" Grid.Row="16" x:Name="TextBoxRemoteDesktopPort" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExamplePort3389}" IsEnabled="{Binding RemoteDesktop_OverridePort}" Style="{StaticResource DefaultTextBox}">
    362 393   <TextBox.Text>
    363 394   <Binding Path="RemoteDesktop_Port" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
    364 395   <Binding.ValidationRules>
    skipped 3 lines
    368 399   </Binding>
    369 400   </TextBox.Text>
    370 401   </TextBox>
    371  - <CheckBox Grid.Column="0" Grid.Row="16" Content="{x:Static localization:Strings.CredentialSecuritySupportProvider}" IsChecked="{Binding RemoteDesktop_OverrideCredSspSupport}" Style="{StaticResource DefaultCheckBox}" />
    372  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="16" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_EnableCredSspSupport}" IsEnabled="{Binding RemoteDesktop_OverrideCredSspSupport}" />
    373  - <CheckBox Grid.Column="0" Grid.Row="18" Content="{x:Static localization:Strings.AuthenticationLevel}" IsChecked="{Binding RemoteDesktop_OverrideAuthenticationLevel}" Style="{StaticResource DefaultCheckBox}" />
    374  - <mah:NumericUpDown Grid.Column="2" Grid.Row="18" Value="{Binding RemoteDesktop_AuthenticationLevel}" Maximum="3" Minimum="0" Interval="1" IsEnabled="{Binding RemoteDesktop_OverrideAuthenticationLevel}" />
    375  - <Rectangle Grid.Column="3" Grid.Row="18" Width="24" Height="24" ToolTip="{x:Static localization:Strings.HelpMessage_RDPAuthenticationLevel}" Style="{StaticResource HelpImageRectangle}" Margin="10,0,0,0">
     402 + <CheckBox Grid.Column="0" Grid.Row="18" Content="{x:Static localization:Strings.CredentialSecuritySupportProvider}" IsChecked="{Binding RemoteDesktop_OverrideCredSspSupport}" Style="{StaticResource DefaultCheckBox}" />
     403 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="18" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_EnableCredSspSupport}" IsEnabled="{Binding RemoteDesktop_OverrideCredSspSupport}" />
     404 + <CheckBox Grid.Column="0" Grid.Row="20" Content="{x:Static localization:Strings.AuthenticationLevel}" IsChecked="{Binding RemoteDesktop_OverrideAuthenticationLevel}" Style="{StaticResource DefaultCheckBox}" />
     405 + <mah:NumericUpDown Grid.Column="2" Grid.Row="20" Value="{Binding RemoteDesktop_AuthenticationLevel}" Maximum="3" Minimum="0" Interval="1" IsEnabled="{Binding RemoteDesktop_OverrideAuthenticationLevel}" />
     406 + <Rectangle Grid.Column="3" Grid.Row="20" Width="24" Height="24" ToolTip="{x:Static localization:Strings.HelpMessage_RDPAuthenticationLevel}" Style="{StaticResource HelpImageRectangle}" Margin="10,0,0,0">
     407 + <Rectangle.Resources>
     408 + <Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource HelpToolTip}" />
     409 + </Rectangle.Resources>
     410 + </Rectangle>
     411 + <CheckBox Grid.Column="0" Grid.Row="22" Content="{x:Static localization:Strings.EnableGatewayServer}" IsChecked="{Binding RemoteDesktop_OverrideGatewayServer}" Style="{StaticResource DefaultCheckBox}" />
     412 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="22" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_EnableGatewayServer}" IsEnabled="{Binding RemoteDesktop_OverrideGatewayServer}" />
     413 + <TextBlock Grid.Column="0" Grid.Row="24" Text="{x:Static localization:Strings.ServerName}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     414 + <TextBox x:Name="TextBoxRemoteDesktopGatewayServerHostname" Grid.Column="2" Grid.Row="24" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleGatewayDomain}">
     415 + <TextBox.Style>
     416 + <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultTextBox}">
     417 + <Setter Property="IsEnabled" Value="False" />
     418 + <Style.Triggers>
     419 + <MultiDataTrigger>
     420 + <MultiDataTrigger.Conditions>
     421 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     422 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     423 + </MultiDataTrigger.Conditions>
     424 + <MultiDataTrigger.Setters>
     425 + <Setter Property="IsEnabled" Value="True" />
     426 + </MultiDataTrigger.Setters>
     427 + </MultiDataTrigger>
     428 + </Style.Triggers>
     429 + </Style>
     430 + </TextBox.Style>
     431 + <TextBox.Text>
     432 + <Binding Path="RemoteDesktop_GatewayServerHostname" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     433 + <Binding.ValidationRules>
     434 + <validators:EmptyValidator ValidatesOnTargetUpdated="True" />
     435 + <validators:RemoteDesktopHostnameAndPortValidator ValidatesOnTargetUpdated="True" />
     436 + </Binding.ValidationRules>
     437 + </Binding>
     438 + </TextBox.Text>
     439 + </TextBox>
     440 + <TextBlock Grid.Column="0" Grid.Row="26" Text="{x:Static localization:Strings.BypassForLocalAddresses}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     441 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="26" Content="" OnContent="" IsOn="{Binding RemoteDesktop_GatewayServerBypassLocalAddresses}">
     442 + <mah:ToggleSwitch.Style>
     443 + <Style TargetType="{x:Type mah:ToggleSwitch}" BasedOn="{StaticResource DefaultToggleSwitch}">
     444 + <Setter Property="IsEnabled" Value="False" />
     445 + <Style.Triggers>
     446 + <MultiDataTrigger>
     447 + <MultiDataTrigger.Conditions>
     448 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     449 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     450 + </MultiDataTrigger.Conditions>
     451 + <MultiDataTrigger.Setters>
     452 + <Setter Property="IsEnabled" Value="True" />
     453 + </MultiDataTrigger.Setters>
     454 + </MultiDataTrigger>
     455 + </Style.Triggers>
     456 + </Style>
     457 + </mah:ToggleSwitch.Style>
     458 + </mah:ToggleSwitch>
     459 + <TextBlock Grid.Column="0" Grid.Row="28" Text="{x:Static localization:Strings.LogonMethod}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     460 + <ComboBox Grid.Column="2" Grid.Row="28" ItemsSource="{Binding RemoteDesktop_GatewayServerLogonMethods}" SelectedItem="{Binding RemoteDesktop_GatewayServerLogonMethod}">
     461 + <ComboBox.Style>
     462 + <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource DefaultComboBox}">
     463 + <Setter Property="IsEnabled" Value="False" />
     464 + <Style.Triggers>
     465 + <MultiDataTrigger>
     466 + <MultiDataTrigger.Conditions>
     467 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     468 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     469 + </MultiDataTrigger.Conditions>
     470 + <MultiDataTrigger.Setters>
     471 + <Setter Property="IsEnabled" Value="True" />
     472 + </MultiDataTrigger.Setters>
     473 + </MultiDataTrigger>
     474 + </Style.Triggers>
     475 + </Style>
     476 + </ComboBox.Style>
     477 + <ComboBox.ItemTemplate>
     478 + <DataTemplate>
     479 + <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopGatewayServerLogonMethodToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
     480 + </DataTemplate>
     481 + </ComboBox.ItemTemplate>
     482 + </ComboBox>
     483 + <TextBlock Grid.Column="0" Grid.Row="30" Text="{x:Static localization:Strings.ShareGatewayCredentialsWithRemoteComputer}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     484 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="30" Content="" OnContent="" IsOn="{Binding RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer}">
     485 + <mah:ToggleSwitch.Style>
     486 + <Style TargetType="{x:Type mah:ToggleSwitch}" BasedOn="{StaticResource DefaultToggleSwitch}">
     487 + <Setter Property="IsEnabled" Value="False" />
     488 + <Style.Triggers>
     489 + <MultiDataTrigger>
     490 + <MultiDataTrigger.Conditions>
     491 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     492 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     493 + </MultiDataTrigger.Conditions>
     494 + <MultiDataTrigger.Setters>
     495 + <Setter Property="IsEnabled" Value="True" />
     496 + </MultiDataTrigger.Setters>
     497 + </MultiDataTrigger>
     498 + </Style.Triggers>
     499 + </Style>
     500 + </mah:ToggleSwitch.Style>
     501 + </mah:ToggleSwitch>
     502 + <TextBlock Grid.Column="0" Grid.Row="32" Text="{x:Static localization:Strings.UseGatewayCredentials}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     503 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="32" Content="" OnContent="" IsOn="{Binding RemoteDesktop_UseGatewayServerCredentials}">
     504 + <mah:ToggleSwitch.Style>
     505 + <Style TargetType="{x:Type mah:ToggleSwitch}" BasedOn="{StaticResource DefaultToggleSwitch}">
     506 + <Setter Property="IsEnabled" Value="False" />
     507 + <Style.Triggers>
     508 + <MultiDataTrigger>
     509 + <MultiDataTrigger.Conditions>
     510 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     511 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     512 + </MultiDataTrigger.Conditions>
     513 + <MultiDataTrigger.Setters>
     514 + <Setter Property="IsEnabled" Value="True" />
     515 + </MultiDataTrigger.Setters>
     516 + </MultiDataTrigger>
     517 + </Style.Triggers>
     518 + </Style>
     519 + </mah:ToggleSwitch.Style>
     520 + </mah:ToggleSwitch>
     521 + <TextBlock Grid.Column="0" Grid.Row="34" Text="{x:Static localization:Strings.Username}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     522 + <TextBox Grid.Column="2" Grid.Row="34" x:Name="TextBoxRemoteDesktopGatewayServerUsername" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleUsername}">
     523 + <TextBox.Style>
     524 + <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultTextBox}">
     525 + <Setter Property="IsEnabled" Value="False" />
     526 + <Style.Triggers>
     527 + <MultiDataTrigger>
     528 + <MultiDataTrigger.Conditions>
     529 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     530 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     531 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     532 + </MultiDataTrigger.Conditions>
     533 + <MultiDataTrigger.Setters>
     534 + <Setter Property="IsEnabled" Value="True" />
     535 + </MultiDataTrigger.Setters>
     536 + </MultiDataTrigger>
     537 + </Style.Triggers>
     538 + </Style>
     539 + </TextBox.Style>
     540 + <TextBox.Text>
     541 + <Binding Path="RemoteDesktop_GatewayServerUsername" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     542 + <Binding.ValidationRules>
     543 + <validators:EmptyValidator ValidatesOnTargetUpdated="True" />
     544 + <validators:NoSpacesValidator ValidatesOnTargetUpdated="True" />
     545 + </Binding.ValidationRules>
     546 + </Binding>
     547 + </TextBox.Text>
     548 + </TextBox>
     549 + <TextBlock Grid.Column="0" Grid.Row="36" Text="{x:Static localization:Strings.Domain}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     550 + <TextBox Grid.Column="2" Grid.Row="36" x:Name="TextBoxRemoteDesktopGatewayServerDomain" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleDomain}">
     551 + <TextBox.Style>
     552 + <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultTextBox}">
     553 + <Setter Property="IsEnabled" Value="False" />
     554 + <Style.Triggers>
     555 + <MultiDataTrigger>
     556 + <MultiDataTrigger.Conditions>
     557 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     558 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     559 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     560 + </MultiDataTrigger.Conditions>
     561 + <MultiDataTrigger.Setters>
     562 + <Setter Property="IsEnabled" Value="True" />
     563 + </MultiDataTrigger.Setters>
     564 + </MultiDataTrigger>
     565 + </Style.Triggers>
     566 + </Style>
     567 + </TextBox.Style>
     568 + <TextBox.Text>
     569 + <Binding Path="RemoteDesktop_GatewayServerDomain" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     570 + <Binding.ValidationRules>
     571 + <validators:EmptyOrWindowsDomainValidator ValidatesOnTargetUpdated="True" />
     572 + </Binding.ValidationRules>
     573 + </Binding>
     574 + </TextBox.Text>
     575 + </TextBox>
     576 + <TextBlock Grid.Column="0" Grid.Row="38" Text="{x:Static localization:Strings.Password}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     577 + <PasswordBox Grid.Column="2" Grid.Row="38" x:Name="PasswordBoxRemoteDesktopGatewayServerPassword">
     578 + <PasswordBox.Style>
     579 + <Style TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource DefaultPasswordBox}">
     580 + <Setter Property="IsEnabled" Value="False" />
     581 + <Setter Property="mah:TextBoxHelper.Watermark" Value="{x:Static localization:Strings.NotChanged}" />
     582 + <Style.Triggers>
     583 + <DataTrigger Binding="{Binding RemoteDesktop_GatewayServerPasswordChanged}" Value="true">
     584 + <Setter Property="mah:TextBoxHelper.Watermark" Value="" />
     585 + </DataTrigger>
     586 + <DataTrigger Binding="{Binding RemoteDesktop_IsGatewayServerPasswordEmpty}" Value="true">
     587 + <Setter Property="mah:TextBoxHelper.Watermark" Value="" />
     588 + </DataTrigger>
     589 + <MultiDataTrigger>
     590 + <MultiDataTrigger.Conditions>
     591 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     592 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     593 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     594 + </MultiDataTrigger.Conditions>
     595 + <MultiDataTrigger.Setters>
     596 + <Setter Property="IsEnabled" Value="True" />
     597 + </MultiDataTrigger.Setters>
     598 + </MultiDataTrigger>
     599 + </Style.Triggers>
     600 + </Style>
     601 + </PasswordBox.Style>
     602 + <interactivity:Interaction.Behaviors>
     603 + <wpfHelpers:PasswordBoxBindingBehavior Password="{Binding RemoteDesktop_GatewayServerPassword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
     604 + </interactivity:Interaction.Behaviors>
     605 + <interactivity:Interaction.Triggers>
     606 + <interactivity:EventTrigger EventName="PasswordChanged">
     607 + <interactivity:InvokeCommandAction Command="{Binding RemoteDesktopPasswordChangedCommand}" />
     608 + </interactivity:EventTrigger>
     609 + </interactivity:Interaction.Triggers>
     610 + </PasswordBox>
     611 + <Rectangle Width="24" Height="24" Grid.Column="3" Grid.Row="38" ToolTip="{x:Static localization:Strings.WarningMessage_ProfileFileNotEncryptedStoringPasswords}" Visibility="{Binding IsProfileFileEncrypted, Converter={StaticResource BooleanReverseToVisibilityCollapsedConverter}}" Style="{StaticResource WarnImageRectangle}" Margin="10,0,0,0">
    376 612   <Rectangle.Resources>
    377 613   <Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource HelpToolTip}" />
    378 614   </Rectangle.Resources>
    379 615   </Rectangle>
    380  - <CheckBox Grid.Column="0" Grid.Row="20" Content="{x:Static localization:Strings.RemoteAudioPlayback}" IsChecked="{Binding RemoteDesktop_OverrideAudioRedirectionMode}" Style="{StaticResource DefaultCheckBox}" />
    381  - <ComboBox Grid.Column="2" Grid.Row="20" ItemsSource="{Binding RemoteDesktop_AudioRedirectionModes}" SelectedItem="{Binding RemoteDesktop_AudioRedirectionMode}" IsEnabled="{Binding RemoteDesktop_OverrideAudioRedirectionMode}">
     616 + <CheckBox Grid.Column="0" Grid.Row="40" Content="{x:Static localization:Strings.RemoteAudioPlayback}" IsChecked="{Binding RemoteDesktop_OverrideAudioRedirectionMode}" Style="{StaticResource DefaultCheckBox}" />
     617 + <ComboBox Grid.Column="2" Grid.Row="40" ItemsSource="{Binding RemoteDesktop_AudioRedirectionModes}" SelectedItem="{Binding RemoteDesktop_AudioRedirectionMode}" IsEnabled="{Binding RemoteDesktop_OverrideAudioRedirectionMode}">
    382 618   <ComboBox.ItemTemplate>
    383 619   <DataTemplate>
    384 620   <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopAudioRedirectionModeToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
    385 621   </DataTemplate>
    386 622   </ComboBox.ItemTemplate>
    387 623   </ComboBox>
    388  - <CheckBox Grid.Column="0" Grid.Row="22" Content="{x:Static localization:Strings.RemoteAudioRecording}" IsChecked="{Binding RemoteDesktop_OverrideAudioCaptureRedirectionMode}" Style="{StaticResource DefaultCheckBox}" />
    389  - <ComboBox Grid.Column="2" Grid.Row="22" ItemsSource="{Binding RemoteDesktop_AudioCaptureRedirectionModes}" SelectedItem="{Binding RemoteDesktop_AudioCaptureRedirectionMode}" IsEnabled="{Binding RemoteDesktop_OverrideAudioCaptureRedirectionMode}">
     624 + <CheckBox Grid.Column="0" Grid.Row="42" Content="{x:Static localization:Strings.RemoteAudioRecording}" IsChecked="{Binding RemoteDesktop_OverrideAudioCaptureRedirectionMode}" Style="{StaticResource DefaultCheckBox}" />
     625 + <ComboBox Grid.Column="2" Grid.Row="42" ItemsSource="{Binding RemoteDesktop_AudioCaptureRedirectionModes}" SelectedItem="{Binding RemoteDesktop_AudioCaptureRedirectionMode}" IsEnabled="{Binding RemoteDesktop_OverrideAudioCaptureRedirectionMode}">
    390 626   <ComboBox.ItemTemplate>
    391 627   <DataTemplate>
    392 628   <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopAudioCaptureRedirectionModeToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
    393 629   </DataTemplate>
    394 630   </ComboBox.ItemTemplate>
    395 631   </ComboBox>
    396  - <CheckBox Grid.Column="0" Grid.Row="24" Content="{x:Static localization:Strings.ApplyWindowsKeyCombinations}" IsChecked="{Binding RemoteDesktop_OverrideApplyWindowsKeyCombinations}" Style="{StaticResource DefaultCheckBox}" />
    397  - <ComboBox Grid.Column="2" Grid.Row="24" ItemsSource="{Binding RemoteDesktop_KeyboardHookModes}" SelectedItem="{Binding RemoteDesktop_KeyboardHookMode}" IsEnabled="{Binding RemoteDesktop_OverrideApplyWindowsKeyCombinations}">
     632 + <CheckBox Grid.Column="0" Grid.Row="44" Content="{x:Static localization:Strings.ApplyWindowsKeyCombinations}" IsChecked="{Binding RemoteDesktop_OverrideApplyWindowsKeyCombinations}" Style="{StaticResource DefaultCheckBox}" />
     633 + <ComboBox Grid.Column="2" Grid.Row="44" ItemsSource="{Binding RemoteDesktop_KeyboardHookModes}" SelectedItem="{Binding RemoteDesktop_KeyboardHookMode}" IsEnabled="{Binding RemoteDesktop_OverrideApplyWindowsKeyCombinations}">
    398 634   <ComboBox.ItemTemplate>
    399 635   <DataTemplate>
    400 636   <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopKeyboardHookModeToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
    401 637   </DataTemplate>
    402 638   </ComboBox.ItemTemplate>
    403 639   </ComboBox>
    404  - <CheckBox Grid.Column="0" Grid.Row="26" Content="{x:Static localization:Strings.RedirectClipboard}" IsChecked="{Binding RemoteDesktop_OverrideRedirectClipboard}" Style="{StaticResource DefaultCheckBox}" />
    405  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="26" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectClipboard}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectClipboard}" />
    406  - <CheckBox Grid.Column="0" Grid.Row="28" Content="{x:Static localization:Strings.RedirectDevices}" IsChecked="{Binding RemoteDesktop_OverrideRedirectDevices}" Style="{StaticResource DefaultCheckBox}" />
    407  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="28" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectDevices}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectDevices}" />
    408  - <CheckBox Grid.Column="0" Grid.Row="30" Content="{x:Static localization:Strings.RedirectDrives}" IsChecked="{Binding RemoteDesktop_OverrideRedirectDrives}" Style="{StaticResource DefaultCheckBox}" />
    409  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="30" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectDrives}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectDrives}"/>
    410  - <CheckBox Grid.Column="0" Grid.Row="32" Content="{x:Static localization:Strings.RedirectPorts}" IsChecked="{Binding RemoteDesktop_OverrideRedirectPorts}" Style="{StaticResource DefaultCheckBox}" />
    411  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="32" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectPorts}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectPorts}" />
    412  - <CheckBox Grid.Column="0" Grid.Row="34" Content="{x:Static localization:Strings.RedirectSmartcards}" IsChecked="{Binding RemoteDesktop_OverrideRedirectSmartcards}" Style="{StaticResource DefaultCheckBox}" />
    413  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="34" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectSmartCards}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectSmartcards}" />
    414  - <CheckBox Grid.Column="0" Grid.Row="36" Content="{x:Static localization:Strings.RedirectPrinters}" IsChecked="{Binding RemoteDesktop_OverrideRedirectPrinters}" Style="{StaticResource DefaultCheckBox}" />
    415  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="36" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectPrinters}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectPrinters}" />
    416  - <CheckBox Grid.Column="0" Grid.Row="38" Content="{x:Static localization:Strings.PersistentBitmapCaching}" IsChecked="{Binding RemoteDesktop_OverridePersistentBitmapCaching}" Style="{StaticResource DefaultCheckBox}" />
    417  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="38" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_PersistentBitmapCaching}" IsEnabled="{Binding RemoteDesktop_OverridePersistentBitmapCaching}" />
    418  - <CheckBox Grid.Column="0" Grid.Row="40" Content="{x:Static localization:Strings.ReconnectIfTheConnectionIsDropped}" IsChecked="{Binding RemoteDesktop_OverrideReconnectIfTheConnectionIsDropped}" Style="{StaticResource DefaultCheckBox}" />
    419  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="40" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_ReconnectIfTheConnectionIsDropped}" IsEnabled="{Binding RemoteDesktop_OverrideReconnectIfTheConnectionIsDropped}" />
    420  - <CheckBox Grid.Column="0" Grid.Row="42" Content="{x:Static localization:Strings.NetworkConnectionType}" IsChecked="{Binding RemoteDesktop_OverrideNetworkConnectionType}" Style="{StaticResource DefaultCheckBox}" />
    421  - <ComboBox Grid.Column="2" Grid.Row="42" ItemsSource="{Binding RemoteDesktop_NetworkConnectionTypes}" SelectedItem="{Binding RemoteDesktop_NetworkConnectionType}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}">
     640 + <CheckBox Grid.Column="0" Grid.Row="46" Content="{x:Static localization:Strings.RedirectClipboard}" IsChecked="{Binding RemoteDesktop_OverrideRedirectClipboard}" Style="{StaticResource DefaultCheckBox}" />
     641 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="46" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectClipboard}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectClipboard}" />
     642 + <CheckBox Grid.Column="0" Grid.Row="48" Content="{x:Static localization:Strings.RedirectDevices}" IsChecked="{Binding RemoteDesktop_OverrideRedirectDevices}" Style="{StaticResource DefaultCheckBox}" />
     643 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="48" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectDevices}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectDevices}" />
     644 + <CheckBox Grid.Column="0" Grid.Row="50" Content="{x:Static localization:Strings.RedirectDrives}" IsChecked="{Binding RemoteDesktop_OverrideRedirectDrives}" Style="{StaticResource DefaultCheckBox}" />
     645 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="50" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectDrives}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectDrives}"/>
     646 + <CheckBox Grid.Column="0" Grid.Row="52" Content="{x:Static localization:Strings.RedirectPorts}" IsChecked="{Binding RemoteDesktop_OverrideRedirectPorts}" Style="{StaticResource DefaultCheckBox}" />
     647 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="52" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectPorts}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectPorts}" />
     648 + <CheckBox Grid.Column="0" Grid.Row="54" Content="{x:Static localization:Strings.RedirectSmartcards}" IsChecked="{Binding RemoteDesktop_OverrideRedirectSmartcards}" Style="{StaticResource DefaultCheckBox}" />
     649 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="54" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectSmartCards}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectSmartcards}" />
     650 + <CheckBox Grid.Column="0" Grid.Row="56" Content="{x:Static localization:Strings.RedirectPrinters}" IsChecked="{Binding RemoteDesktop_OverrideRedirectPrinters}" Style="{StaticResource DefaultCheckBox}" />
     651 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="56" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectPrinters}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectPrinters}" />
     652 + <CheckBox Grid.Column="0" Grid.Row="58" Content="{x:Static localization:Strings.PersistentBitmapCaching}" IsChecked="{Binding RemoteDesktop_OverridePersistentBitmapCaching}" Style="{StaticResource DefaultCheckBox}" />
     653 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="58" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_PersistentBitmapCaching}" IsEnabled="{Binding RemoteDesktop_OverridePersistentBitmapCaching}" />
     654 + <CheckBox Grid.Column="0" Grid.Row="60" Content="{x:Static localization:Strings.ReconnectIfTheConnectionIsDropped}" IsChecked="{Binding RemoteDesktop_OverrideReconnectIfTheConnectionIsDropped}" Style="{StaticResource DefaultCheckBox}" />
     655 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="60" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_ReconnectIfTheConnectionIsDropped}" IsEnabled="{Binding RemoteDesktop_OverrideReconnectIfTheConnectionIsDropped}" />
     656 + <CheckBox Grid.Column="0" Grid.Row="62" Content="{x:Static localization:Strings.NetworkConnectionType}" IsChecked="{Binding RemoteDesktop_OverrideNetworkConnectionType}" Style="{StaticResource DefaultCheckBox}" />
     657 + <ComboBox Grid.Column="2" Grid.Row="62" ItemsSource="{Binding RemoteDesktop_NetworkConnectionTypes}" SelectedItem="{Binding RemoteDesktop_NetworkConnectionType}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}">
    422 658   <ComboBox.ItemTemplate>
    423 659   <DataTemplate>
    424 660   <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopNetworkConnectionTypeToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
    425 661   </DataTemplate>
    426 662   </ComboBox.ItemTemplate>
    427 663   </ComboBox>
    428  - <TextBlock Grid.Column="0" Grid.Row="44" Text="{x:Static localization:Strings.DesktopBackground}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    429  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="44" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_DesktopBackground}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    430  - <TextBlock Grid.Column="0" Grid.Row="46" Text="{x:Static localization:Strings.FontSmoothing}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    431  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="46" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_FontSmoothing}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    432  - <TextBlock Grid.Column="0" Grid.Row="48" Text="{x:Static localization:Strings.DesktopComposition}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    433  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="48" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_DesktopComposition}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    434  - <TextBlock Grid.Column="0" Grid.Row="50" Text="{x:Static localization:Strings.ShowWindowContentsWhileDragging}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    435  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="50" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_ShowWindowContentsWhileDragging}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    436  - <TextBlock Grid.Column="0" Grid.Row="52" Text="{x:Static localization:Strings.MenuAndWindowAnimation}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    437  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="52" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_MenuAndWindowAnimation}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    438  - <TextBlock Grid.Column="0" Grid.Row="54" Text="{x:Static localization:Strings.VisualStyles}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    439  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="54" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_VisualStyles}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     664 + <TextBlock Grid.Column="0" Grid.Row="64" Text="{x:Static localization:Strings.DesktopBackground}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     665 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="64" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_DesktopBackground}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     666 + <TextBlock Grid.Column="0" Grid.Row="66" Text="{x:Static localization:Strings.FontSmoothing}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     667 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="66" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_FontSmoothing}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     668 + <TextBlock Grid.Column="0" Grid.Row="68" Text="{x:Static localization:Strings.DesktopComposition}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     669 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="68" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_DesktopComposition}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     670 + <TextBlock Grid.Column="0" Grid.Row="70" Text="{x:Static localization:Strings.ShowWindowContentsWhileDragging}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     671 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="70" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_ShowWindowContentsWhileDragging}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     672 + <TextBlock Grid.Column="0" Grid.Row="72" Text="{x:Static localization:Strings.MenuAndWindowAnimation}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     673 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="72" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_MenuAndWindowAnimation}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     674 + <TextBlock Grid.Column="0" Grid.Row="74" Text="{x:Static localization:Strings.VisualStyles}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     675 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="74" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_VisualStyles}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    440 676   </Grid>
    441 677   </StackPanel>
    442 678   </ScrollViewer>
    skipped 248 lines
    691 927   <MultiDataTrigger>
    692 928   <MultiDataTrigger.Conditions>
    693 929   <Condition Binding="{Binding RemoteDesktop_UseCredentials}" Value="True" />
     930 + <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopDomain, Path=(Validation.HasError)}" Value="True" />
     931 + </MultiDataTrigger.Conditions>
     932 + <MultiDataTrigger.Setters>
     933 + <Setter Property="IsEnabled" Value="False" />
     934 + </MultiDataTrigger.Setters>
     935 + </MultiDataTrigger>
     936 + <MultiDataTrigger>
     937 + <MultiDataTrigger.Conditions>
     938 + <Condition Binding="{Binding RemoteDesktop_UseCredentials}" Value="True" />
    694 939   <Condition Binding="{Binding RemoteDesktop_IsPasswordEmpty}" Value="True" />
    695 940   </MultiDataTrigger.Conditions>
    696 941   <MultiDataTrigger.Setters>
    skipped 4 lines
    701 946   <MultiDataTrigger.Conditions>
    702 947   <Condition Binding="{Binding RemoteDesktop_OverridePort}" Value="True"/>
    703 948   <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopPort, Path=(Validation.HasError)}" Value="True" />
     949 + </MultiDataTrigger.Conditions>
     950 + <MultiDataTrigger.Setters>
     951 + <Setter Property="IsEnabled" Value="False" />
     952 + </MultiDataTrigger.Setters>
     953 + </MultiDataTrigger>
     954 + <MultiDataTrigger>
     955 + <MultiDataTrigger.Conditions>
     956 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True"/>
     957 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True"/>
     958 + <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopGatewayServerHostname, Path=(Validation.HasError)}" Value="True" />
     959 + </MultiDataTrigger.Conditions>
     960 + <MultiDataTrigger.Setters>
     961 + <Setter Property="IsEnabled" Value="False" />
     962 + </MultiDataTrigger.Setters>
     963 + </MultiDataTrigger>
     964 + <MultiDataTrigger>
     965 + <MultiDataTrigger.Conditions>
     966 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True"/>
     967 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True"/>
     968 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     969 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     970 + <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopGatewayServerUsername, Path=(Validation.HasError)}" Value="True" />
     971 + </MultiDataTrigger.Conditions>
     972 + <MultiDataTrigger.Setters>
     973 + <Setter Property="IsEnabled" Value="False" />
     974 + </MultiDataTrigger.Setters>
     975 + </MultiDataTrigger>
     976 + <MultiDataTrigger>
     977 + <MultiDataTrigger.Conditions>
     978 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True"/>
     979 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True"/>
     980 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     981 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     982 + <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopGatewayServerDomain, Path=(Validation.HasError)}" Value="True" />
     983 + </MultiDataTrigger.Conditions>
     984 + <MultiDataTrigger.Setters>
     985 + <Setter Property="IsEnabled" Value="False" />
     986 + </MultiDataTrigger.Setters>
     987 + </MultiDataTrigger>
     988 + <MultiDataTrigger>
     989 + <MultiDataTrigger.Conditions>
     990 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True"/>
     991 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True"/>
     992 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     993 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     994 + <Condition Binding="{Binding RemoteDesktop_IsGatewayServerPasswordEmpty}" Value="True" />
    704 995   </MultiDataTrigger.Conditions>
    705 996   <MultiDataTrigger.Setters>
    706 997   <Setter Property="IsEnabled" Value="False" />
    skipped 76 lines
  • ■ ■ ■ ■ ■
    Source/NETworkManager/Views/ProfileDialog.xaml
    skipped 20 lines
    21 21   <converters:RemoteDesktopAudioCaptureRedirectionModeToStringConverter x:Key="RemoteDesktopAudioCaptureRedirectionModeToStringConverter" />
    22 22   <converters:RemoteDesktopAudioRedirectionModeToStringConverter x:Key="RemoteDesktopAudioRedirectionModeToStringConverter" />
    23 23   <converters:RemoteDesktopKeyboardHookModeToStringConverter x:Key="RemoteDesktopKeyboardHookModeToStringConverter" />
     24 + <converters:RemoteDesktopGatewayServerLogonMethodToStringConverter x:Key="RemoteDesktopGatewayServerLogonMethodToStringConverter" />
    24 25   <converters:RemoteDesktopNetworkConnectionTypeToStringConverter x:Key="RemoteDesktopNetworkConnectionTypeToStringConverter" />
    25 26   <converters:ProfileViewNameToTranslatedStringConverter x:Key="ProfileViewNameToTranslatedStringConverter" />
    26 27   <converters:PuTTYLogModeToStringConverter x:Key="PuTTYLogModeToStringConverter" />
    skipped 696 lines
    723 724   <RowDefinition Height="Auto" />
    724 725   <RowDefinition Height="10" />
    725 726   <RowDefinition Height="Auto" />
     727 + <RowDefinition Height="10" />
     728 + <RowDefinition Height="Auto" />
     729 + <RowDefinition Height="10" />
     730 + <RowDefinition Height="Auto" />
     731 + <RowDefinition Height="10" />
     732 + <RowDefinition Height="Auto" />
     733 + <RowDefinition Height="10" />
     734 + <RowDefinition Height="Auto" />
     735 + <RowDefinition Height="10" />
     736 + <RowDefinition Height="Auto" />
     737 + <RowDefinition Height="10" />
     738 + <RowDefinition Height="Auto" />
     739 + <RowDefinition Height="10" />
     740 + <RowDefinition Height="Auto" />
     741 + <RowDefinition Height="10" />
     742 + <RowDefinition Height="Auto" />
     743 + <RowDefinition Height="10" />
     744 + <RowDefinition Height="Auto" />
     745 + <RowDefinition Height="10" />
     746 + <RowDefinition Height="Auto" />
    726 747   </Grid.RowDefinitions>
    727 748   <Grid.ColumnDefinitions>
    728 749   <ColumnDefinition Width="1*" />
    skipped 44 lines
    773 794   </Binding>
    774 795   </TextBox.Text>
    775 796   </TextBox>
    776  - <TextBlock Grid.Column="0" Grid.Row="8" Text="{x:Static localization:Strings.Password}" />
    777  - <PasswordBox Grid.Column="2" Grid.Row="8" x:Name="PasswordBoxRemoteDesktopPassword" IsEnabled="{Binding RemoteDesktop_UseCredentials}">
     797 + <TextBlock Grid.Column="0" Grid.Row="8" Text="{x:Static localization:Strings.Domain}" />
     798 + <TextBox Grid.Column="2" Grid.Row="8" x:Name="TextBoxRemoteDesktopDomain" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleDomain}" IsEnabled="{Binding RemoteDesktop_UseCredentials}" Style="{StaticResource DefaultTextBox}">
     799 + <TextBox.Text>
     800 + <Binding Path="RemoteDesktop_Domain" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     801 + <Binding.ValidationRules>
     802 + <validators:EmptyOrWindowsDomainValidator ValidatesOnTargetUpdated="True" />
     803 + </Binding.ValidationRules>
     804 + </Binding>
     805 + </TextBox.Text>
     806 + </TextBox>
     807 + <TextBlock Grid.Column="0" Grid.Row="10" Text="{x:Static localization:Strings.Password}" />
     808 + <PasswordBox Grid.Column="2" Grid.Row="10" x:Name="PasswordBoxRemoteDesktopPassword" IsEnabled="{Binding RemoteDesktop_UseCredentials}">
    778 809   <PasswordBox.Style>
    779 810   <Style TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource DefaultPasswordBox}">
    780 811   <Setter Property="mah:TextBoxHelper.Watermark" Value="{x:Static localization:Strings.NotChanged}" />
    skipped 16 lines
    797 828   </interactivity:EventTrigger>
    798 829   </interactivity:Interaction.Triggers>
    799 830   </PasswordBox>
    800  - <Rectangle Width="24" Height="24" Grid.Column="3" Grid.Row="8" ToolTip="{x:Static localization:Strings.WarningMessage_ProfileFileNotEncryptedStoringPasswords}" Visibility="{Binding IsProfileFileEncrypted, Converter={StaticResource BooleanReverseToVisibilityCollapsedConverter}}" Style="{StaticResource WarnImageRectangle}" Margin="10,0,0,0">
     831 + <Rectangle Width="24" Height="24" Grid.Column="3" Grid.Row="10" ToolTip="{x:Static localization:Strings.WarningMessage_ProfileFileNotEncryptedStoringPasswords}" Visibility="{Binding IsProfileFileEncrypted, Converter={StaticResource BooleanReverseToVisibilityCollapsedConverter}}" Style="{StaticResource WarnImageRectangle}" Margin="10,0,0,0">
    801 832   <Rectangle.Resources>
    802 833   <Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource HelpToolTip}" />
    803 834   </Rectangle.Resources>
    804 835   </Rectangle>
    805  - <TextBlock Grid.Column="0" Grid.Row="10" Grid.ColumnSpan="4" Text="{x:Static localization:Strings.OverrideDefaultSettings}" Style="{StaticResource HeaderTextBlock}" Margin="0,10,0,0"/>
    806  - <Separator Grid.Column="0" Grid.Row="12" Grid.ColumnSpan="4" Background="{DynamicResource MahApps.Brushes.Gray8}" Margin="0,0,0,10" />
    807  - <CheckBox Grid.Column="0" Grid.Row="14" VerticalAlignment="Top" Content="{x:Static localization:Strings.Display}" IsChecked="{Binding RemoteDesktop_OverrideDisplay}" Style="{StaticResource DefaultCheckBox}" />
    808  - <StackPanel Grid.Column="2" Grid.Row="14" IsEnabled="{Binding RemoteDesktop_OverrideDisplay}">
     836 + <TextBlock Grid.Column="0" Grid.Row="12" Grid.ColumnSpan="4" Text="{x:Static localization:Strings.OverrideDefaultSettings}" Style="{StaticResource HeaderTextBlock}" Margin="0,10,0,0"/>
     837 + <Separator Grid.Column="0" Grid.Row="14" Grid.ColumnSpan="4" Background="{DynamicResource MahApps.Brushes.Gray8}" Margin="0,0,0,10" />
     838 + <CheckBox Grid.Column="0" Grid.Row="16" VerticalAlignment="Top" Content="{x:Static localization:Strings.Display}" IsChecked="{Binding RemoteDesktop_OverrideDisplay}" Style="{StaticResource DefaultCheckBox}" />
     839 + <StackPanel Grid.Column="2" Grid.Row="16" IsEnabled="{Binding RemoteDesktop_OverrideDisplay}">
    809 840   <RadioButton x:Name="RadioButtonAdjustScreenAutomatically" Content="{x:Static localization:Strings.AdjustScreenAutomatically}" IsChecked="{Binding RemoteDesktop_AdjustScreenAutomatically}" Margin="0,0,0,10" />
    810 841   <RadioButton x:Name="RadioButtonUseCurrentViewSize" Content="{x:Static localization:Strings.UseCurrentViewSize}" IsChecked="{Binding RemoteDesktop_UseCurrentViewSize}" Margin="0,0,0,10" />
    811 842   <RadioButton x:Name="RadioButtonFixedScreenSize" Content="{x:Static localization:Strings.FixedScreenSize}" IsChecked="{Binding RemoteDesktop_UseFixedScreenSize}" Margin="0,0,0,10" />
    skipped 41 lines
    853 884   </Grid>
    854 885   </GroupBox>
    855 886   </StackPanel>
    856  - <CheckBox Grid.Column="0" Grid.Row="16" Content="{x:Static localization:Strings.ColorDepthBit}" IsChecked="{Binding RemoteDesktop_OverrideColorDepth}" Style="{StaticResource DefaultCheckBox}" />
    857  - <ComboBox Grid.Column="2" Grid.Row="16" ItemsSource="{Binding RemoteDesktop_ColorDepths}" SelectedItem="{Binding RemoteDesktop_SelectedColorDepth}" IsEnabled="{Binding RemoteDesktop_OverrideColorDepth}"/>
    858  - <CheckBox Grid.Column="0" Grid.Row="18" Content="{x:Static localization:Strings.Port}" IsChecked="{Binding RemoteDesktop_OverridePort}" Style="{StaticResource DefaultCheckBox}" />
    859  - <TextBox Grid.Column="2" Grid.Row="18" x:Name="TextBoxRemoteDesktopPort" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExamplePort3389}" IsEnabled="{Binding RemoteDesktop_OverridePort}" Style="{StaticResource DefaultTextBox}">
     887 + <CheckBox Grid.Column="0" Grid.Row="18" Content="{x:Static localization:Strings.ColorDepthBit}" IsChecked="{Binding RemoteDesktop_OverrideColorDepth}" Style="{StaticResource DefaultCheckBox}" />
     888 + <ComboBox Grid.Column="2" Grid.Row="18" ItemsSource="{Binding RemoteDesktop_ColorDepths}" SelectedItem="{Binding RemoteDesktop_SelectedColorDepth}" IsEnabled="{Binding RemoteDesktop_OverrideColorDepth}"/>
     889 + <CheckBox Grid.Column="0" Grid.Row="20" Content="{x:Static localization:Strings.Port}" IsChecked="{Binding RemoteDesktop_OverridePort}" Style="{StaticResource DefaultCheckBox}" />
     890 + <TextBox Grid.Column="2" Grid.Row="20" x:Name="TextBoxRemoteDesktopPort" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExamplePort3389}" IsEnabled="{Binding RemoteDesktop_OverridePort}" Style="{StaticResource DefaultTextBox}">
    860 891   <TextBox.Text>
    861 892   <Binding Path="RemoteDesktop_Port" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
    862 893   <Binding.ValidationRules>
    skipped 3 lines
    866 897   </Binding>
    867 898   </TextBox.Text>
    868 899   </TextBox>
    869  - <CheckBox Grid.Column="0" Grid.Row="20" Content="{x:Static localization:Strings.CredentialSecuritySupportProvider}" IsChecked="{Binding RemoteDesktop_OverrideCredSspSupport}" Style="{StaticResource DefaultCheckBox}" />
    870  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="20" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_EnableCredSspSupport}" IsEnabled="{Binding RemoteDesktop_OverrideCredSspSupport}" />
    871  - <CheckBox Grid.Column="0" Grid.Row="22" Content="{x:Static localization:Strings.AuthenticationLevel}" IsChecked="{Binding RemoteDesktop_OverrideAuthenticationLevel}" Style="{StaticResource DefaultCheckBox}" />
    872  - <mah:NumericUpDown Grid.Column="2" Grid.Row="22" Value="{Binding RemoteDesktop_AuthenticationLevel}" Maximum="3" Minimum="0" Interval="1" IsEnabled="{Binding RemoteDesktop_OverrideAuthenticationLevel}" />
    873  - <Rectangle Grid.Column="3" Grid.Row="22" Width="24" Height="24" ToolTip="{x:Static localization:Strings.HelpMessage_RDPAuthenticationLevel}" Style="{StaticResource HelpImageRectangle}" Margin="10,0,0,0">
     900 + <CheckBox Grid.Column="0" Grid.Row="22" Content="{x:Static localization:Strings.CredentialSecuritySupportProvider}" IsChecked="{Binding RemoteDesktop_OverrideCredSspSupport}" Style="{StaticResource DefaultCheckBox}" />
     901 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="22" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_EnableCredSspSupport}" IsEnabled="{Binding RemoteDesktop_OverrideCredSspSupport}" />
     902 + <CheckBox Grid.Column="0" Grid.Row="24" Content="{x:Static localization:Strings.AuthenticationLevel}" IsChecked="{Binding RemoteDesktop_OverrideAuthenticationLevel}" Style="{StaticResource DefaultCheckBox}" />
     903 + <mah:NumericUpDown Grid.Column="2" Grid.Row="24" Value="{Binding RemoteDesktop_AuthenticationLevel}" Maximum="3" Minimum="0" Interval="1" IsEnabled="{Binding RemoteDesktop_OverrideAuthenticationLevel}" />
     904 + <Rectangle Grid.Column="3" Grid.Row="24" Width="24" Height="24" ToolTip="{x:Static localization:Strings.HelpMessage_RDPAuthenticationLevel}" Style="{StaticResource HelpImageRectangle}" Margin="10,0,0,0">
    874 905   <Rectangle.Resources>
    875 906   <Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource HelpToolTip}" />
    876 907   </Rectangle.Resources>
    877 908   </Rectangle>
    878  - <CheckBox Grid.Column="0" Grid.Row="24" Content="{x:Static localization:Strings.RemoteAudioPlayback}" IsChecked="{Binding RemoteDesktop_OverrideAudioRedirectionMode}" Style="{StaticResource DefaultCheckBox}" />
    879  - <ComboBox Grid.Column="2" Grid.Row="24" ItemsSource="{Binding RemoteDesktop_AudioRedirectionModes}" SelectedItem="{Binding RemoteDesktop_AudioRedirectionMode}" IsEnabled="{Binding RemoteDesktop_OverrideAudioRedirectionMode}">
     909 + <CheckBox Grid.Column="0" Grid.Row="26" Content="{x:Static localization:Strings.EnableGatewayServer}" IsChecked="{Binding RemoteDesktop_OverrideGatewayServer}" Style="{StaticResource DefaultCheckBox}" />
     910 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="26" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_EnableGatewayServer}" IsEnabled="{Binding RemoteDesktop_OverrideGatewayServer}" />
     911 + <TextBlock Grid.Column="0" Grid.Row="28" Text="{x:Static localization:Strings.ServerName}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     912 + <TextBox x:Name="TextBoxRemoteDesktopGatewayServerHostname" Grid.Column="2" Grid.Row="28" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleGatewayDomain}">
     913 + <TextBox.Style>
     914 + <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultTextBox}">
     915 + <Setter Property="IsEnabled" Value="False" />
     916 + <Style.Triggers>
     917 + <MultiDataTrigger>
     918 + <MultiDataTrigger.Conditions>
     919 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     920 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     921 + </MultiDataTrigger.Conditions>
     922 + <MultiDataTrigger.Setters>
     923 + <Setter Property="IsEnabled" Value="True" />
     924 + </MultiDataTrigger.Setters>
     925 + </MultiDataTrigger>
     926 + </Style.Triggers>
     927 + </Style>
     928 + </TextBox.Style>
     929 + <TextBox.Text>
     930 + <Binding Path="RemoteDesktop_GatewayServerHostname" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     931 + <Binding.ValidationRules>
     932 + <validators:EmptyValidator ValidatesOnTargetUpdated="True" />
     933 + <validators:RemoteDesktopHostnameAndPortValidator ValidatesOnTargetUpdated="True" />
     934 + </Binding.ValidationRules>
     935 + </Binding>
     936 + </TextBox.Text>
     937 + </TextBox>
     938 + <TextBlock Grid.Column="0" Grid.Row="30" Text="{x:Static localization:Strings.BypassForLocalAddresses}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     939 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="30" Content="" OnContent="" IsOn="{Binding RemoteDesktop_GatewayServerBypassLocalAddresses}">
     940 + <mah:ToggleSwitch.Style>
     941 + <Style TargetType="{x:Type mah:ToggleSwitch}" BasedOn="{StaticResource DefaultToggleSwitch}">
     942 + <Setter Property="IsEnabled" Value="False" />
     943 + <Style.Triggers>
     944 + <MultiDataTrigger>
     945 + <MultiDataTrigger.Conditions>
     946 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     947 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     948 + </MultiDataTrigger.Conditions>
     949 + <MultiDataTrigger.Setters>
     950 + <Setter Property="IsEnabled" Value="True" />
     951 + </MultiDataTrigger.Setters>
     952 + </MultiDataTrigger>
     953 + </Style.Triggers>
     954 + </Style>
     955 + </mah:ToggleSwitch.Style>
     956 + </mah:ToggleSwitch>
     957 + <TextBlock Grid.Column="0" Grid.Row="32" Text="{x:Static localization:Strings.LogonMethod}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     958 + <ComboBox Grid.Column="2" Grid.Row="32" ItemsSource="{Binding RemoteDesktop_GatewayServerLogonMethods}" SelectedItem="{Binding RemoteDesktop_GatewayServerLogonMethod}">
     959 + <ComboBox.Style>
     960 + <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource DefaultComboBox}">
     961 + <Setter Property="IsEnabled" Value="False" />
     962 + <Style.Triggers>
     963 + <MultiDataTrigger>
     964 + <MultiDataTrigger.Conditions>
     965 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     966 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     967 + </MultiDataTrigger.Conditions>
     968 + <MultiDataTrigger.Setters>
     969 + <Setter Property="IsEnabled" Value="True" />
     970 + </MultiDataTrigger.Setters>
     971 + </MultiDataTrigger>
     972 + </Style.Triggers>
     973 + </Style>
     974 + </ComboBox.Style>
     975 + <ComboBox.ItemTemplate>
     976 + <DataTemplate>
     977 + <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopGatewayServerLogonMethodToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
     978 + </DataTemplate>
     979 + </ComboBox.ItemTemplate>
     980 + </ComboBox>
     981 + <TextBlock Grid.Column="0" Grid.Row="34" Text="{x:Static localization:Strings.ShareGatewayCredentialsWithRemoteComputer}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     982 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="34" Content="" OnContent="" IsOn="{Binding RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer}">
     983 + <mah:ToggleSwitch.Style>
     984 + <Style TargetType="{x:Type mah:ToggleSwitch}" BasedOn="{StaticResource DefaultToggleSwitch}">
     985 + <Setter Property="IsEnabled" Value="False" />
     986 + <Style.Triggers>
     987 + <MultiDataTrigger>
     988 + <MultiDataTrigger.Conditions>
     989 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     990 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     991 + </MultiDataTrigger.Conditions>
     992 + <MultiDataTrigger.Setters>
     993 + <Setter Property="IsEnabled" Value="True" />
     994 + </MultiDataTrigger.Setters>
     995 + </MultiDataTrigger>
     996 + </Style.Triggers>
     997 + </Style>
     998 + </mah:ToggleSwitch.Style>
     999 + </mah:ToggleSwitch>
     1000 + <TextBlock Grid.Column="0" Grid.Row="36" Text="{x:Static localization:Strings.UseGatewayCredentials}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1001 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="36" Content="" OnContent="" IsOn="{Binding RemoteDesktop_UseGatewayServerCredentials}">
     1002 + <mah:ToggleSwitch.Style>
     1003 + <Style TargetType="{x:Type mah:ToggleSwitch}" BasedOn="{StaticResource DefaultToggleSwitch}">
     1004 + <Setter Property="IsEnabled" Value="False" />
     1005 + <Style.Triggers>
     1006 + <MultiDataTrigger>
     1007 + <MultiDataTrigger.Conditions>
     1008 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True" />
     1009 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     1010 + </MultiDataTrigger.Conditions>
     1011 + <MultiDataTrigger.Setters>
     1012 + <Setter Property="IsEnabled" Value="True" />
     1013 + </MultiDataTrigger.Setters>
     1014 + </MultiDataTrigger>
     1015 + </Style.Triggers>
     1016 + </Style>
     1017 + </mah:ToggleSwitch.Style>
     1018 + </mah:ToggleSwitch>
     1019 + <TextBlock Grid.Column="0" Grid.Row="38" Text="{x:Static localization:Strings.Username}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1020 + <TextBox Grid.Column="2" Grid.Row="38" x:Name="TextBoxRemoteDesktopGatewayServerUsername" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleUsername}">
     1021 + <TextBox.Style>
     1022 + <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultTextBox}">
     1023 + <Setter Property="IsEnabled" Value="False" />
     1024 + <Style.Triggers>
     1025 + <MultiDataTrigger>
     1026 + <MultiDataTrigger.Conditions>
     1027 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     1028 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     1029 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     1030 + </MultiDataTrigger.Conditions>
     1031 + <MultiDataTrigger.Setters>
     1032 + <Setter Property="IsEnabled" Value="True" />
     1033 + </MultiDataTrigger.Setters>
     1034 + </MultiDataTrigger>
     1035 + </Style.Triggers>
     1036 + </Style>
     1037 + </TextBox.Style>
     1038 + <TextBox.Text>
     1039 + <Binding Path="RemoteDesktop_GatewayServerUsername" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     1040 + <Binding.ValidationRules>
     1041 + <validators:EmptyValidator ValidatesOnTargetUpdated="True" />
     1042 + <validators:NoSpacesValidator ValidatesOnTargetUpdated="True" />
     1043 + </Binding.ValidationRules>
     1044 + </Binding>
     1045 + </TextBox.Text>
     1046 + </TextBox>
     1047 + <TextBlock Grid.Column="0" Grid.Row="40" Text="{x:Static localization:Strings.Domain}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1048 + <TextBox Grid.Column="2" Grid.Row="40" x:Name="TextBoxRemoteDesktopGatewayServerDomain" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleDomain}">
     1049 + <TextBox.Style>
     1050 + <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultTextBox}">
     1051 + <Setter Property="IsEnabled" Value="False" />
     1052 + <Style.Triggers>
     1053 + <MultiDataTrigger>
     1054 + <MultiDataTrigger.Conditions>
     1055 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     1056 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     1057 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     1058 + </MultiDataTrigger.Conditions>
     1059 + <MultiDataTrigger.Setters>
     1060 + <Setter Property="IsEnabled" Value="True" />
     1061 + </MultiDataTrigger.Setters>
     1062 + </MultiDataTrigger>
     1063 + </Style.Triggers>
     1064 + </Style>
     1065 + </TextBox.Style>
     1066 + <TextBox.Text>
     1067 + <Binding Path="RemoteDesktop_GatewayServerDomain" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     1068 + <Binding.ValidationRules>
     1069 + <validators:EmptyOrWindowsDomainValidator ValidatesOnTargetUpdated="True" />
     1070 + </Binding.ValidationRules>
     1071 + </Binding>
     1072 + </TextBox.Text>
     1073 + </TextBox>
     1074 + <TextBlock Grid.Column="0" Grid.Row="42" Text="{x:Static localization:Strings.Password}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1075 + <PasswordBox Grid.Column="2" Grid.Row="42" x:Name="PasswordBoxRemoteDesktopGatewayServerPassword">
     1076 + <PasswordBox.Style>
     1077 + <Style TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource DefaultPasswordBox}">
     1078 + <Setter Property="IsEnabled" Value="False" />
     1079 + <Setter Property="mah:TextBoxHelper.Watermark" Value="{x:Static localization:Strings.NotChanged}" />
     1080 + <Style.Triggers>
     1081 + <DataTrigger Binding="{Binding RemoteDesktop_GatewayServerPasswordChanged}" Value="true">
     1082 + <Setter Property="mah:TextBoxHelper.Watermark" Value="" />
     1083 + </DataTrigger>
     1084 + <DataTrigger Binding="{Binding RemoteDesktop_IsGatewayServerPasswordEmpty}" Value="true">
     1085 + <Setter Property="mah:TextBoxHelper.Watermark" Value="" />
     1086 + </DataTrigger>
     1087 + <MultiDataTrigger>
     1088 + <MultiDataTrigger.Conditions>
     1089 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True" />
     1090 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     1091 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     1092 + </MultiDataTrigger.Conditions>
     1093 + <MultiDataTrigger.Setters>
     1094 + <Setter Property="IsEnabled" Value="True" />
     1095 + </MultiDataTrigger.Setters>
     1096 + </MultiDataTrigger>
     1097 + </Style.Triggers>
     1098 + </Style>
     1099 + </PasswordBox.Style>
     1100 + <interactivity:Interaction.Behaviors>
     1101 + <wpfHelpers:PasswordBoxBindingBehavior Password="{Binding RemoteDesktop_GatewayServerPassword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
     1102 + </interactivity:Interaction.Behaviors>
     1103 + <interactivity:Interaction.Triggers>
     1104 + <interactivity:EventTrigger EventName="PasswordChanged">
     1105 + <interactivity:InvokeCommandAction Command="{Binding RemoteDesktopPasswordChangedCommand}" />
     1106 + </interactivity:EventTrigger>
     1107 + </interactivity:Interaction.Triggers>
     1108 + </PasswordBox>
     1109 + <Rectangle Width="24" Height="24" Grid.Column="3" Grid.Row="42" ToolTip="{x:Static localization:Strings.WarningMessage_ProfileFileNotEncryptedStoringPasswords}" Visibility="{Binding IsProfileFileEncrypted, Converter={StaticResource BooleanReverseToVisibilityCollapsedConverter}}" Style="{StaticResource WarnImageRectangle}" Margin="10,0,0,0">
     1110 + <Rectangle.Resources>
     1111 + <Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource HelpToolTip}" />
     1112 + </Rectangle.Resources>
     1113 + </Rectangle>
     1114 + <CheckBox Grid.Column="0" Grid.Row="44" Content="{x:Static localization:Strings.RemoteAudioPlayback}" IsChecked="{Binding RemoteDesktop_OverrideAudioRedirectionMode}" Style="{StaticResource DefaultCheckBox}" />
     1115 + <ComboBox Grid.Column="2" Grid.Row="44" ItemsSource="{Binding RemoteDesktop_AudioRedirectionModes}" SelectedItem="{Binding RemoteDesktop_AudioRedirectionMode}" IsEnabled="{Binding RemoteDesktop_OverrideAudioRedirectionMode}">
    880 1116   <ComboBox.ItemTemplate>
    881 1117   <DataTemplate>
    882 1118   <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopAudioRedirectionModeToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
    883 1119   </DataTemplate>
    884 1120   </ComboBox.ItemTemplate>
    885 1121   </ComboBox>
    886  - <CheckBox Grid.Column="0" Grid.Row="26" Content="{x:Static localization:Strings.RemoteAudioRecording}" IsChecked="{Binding RemoteDesktop_OverrideAudioCaptureRedirectionMode}" Style="{StaticResource DefaultCheckBox}" />
    887  - <ComboBox Grid.Column="2" Grid.Row="26" ItemsSource="{Binding RemoteDesktop_AudioCaptureRedirectionModes}" SelectedItem="{Binding RemoteDesktop_AudioCaptureRedirectionMode}" IsEnabled="{Binding RemoteDesktop_OverrideAudioCaptureRedirectionMode}">
     1122 + <CheckBox Grid.Column="0" Grid.Row="46" Content="{x:Static localization:Strings.RemoteAudioRecording}" IsChecked="{Binding RemoteDesktop_OverrideAudioCaptureRedirectionMode}" Style="{StaticResource DefaultCheckBox}" />
     1123 + <ComboBox Grid.Column="2" Grid.Row="46" ItemsSource="{Binding RemoteDesktop_AudioCaptureRedirectionModes}" SelectedItem="{Binding RemoteDesktop_AudioCaptureRedirectionMode}" IsEnabled="{Binding RemoteDesktop_OverrideAudioCaptureRedirectionMode}">
    888 1124   <ComboBox.ItemTemplate>
    889 1125   <DataTemplate>
    890 1126   <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopAudioCaptureRedirectionModeToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
    891 1127   </DataTemplate>
    892 1128   </ComboBox.ItemTemplate>
    893 1129   </ComboBox>
    894  - <CheckBox Grid.Column="0" Grid.Row="28" Content="{x:Static localization:Strings.ApplyWindowsKeyCombinations}" IsChecked="{Binding RemoteDesktop_OverrideApplyWindowsKeyCombinations}" Style="{StaticResource DefaultCheckBox}" />
    895  - <ComboBox Grid.Column="2" Grid.Row="28" ItemsSource="{Binding RemoteDesktop_KeyboardHookModes}" SelectedItem="{Binding RemoteDesktop_KeyboardHookMode}" IsEnabled="{Binding RemoteDesktop_OverrideApplyWindowsKeyCombinations}">
     1130 + <CheckBox Grid.Column="0" Grid.Row="48" Content="{x:Static localization:Strings.ApplyWindowsKeyCombinations}" IsChecked="{Binding RemoteDesktop_OverrideApplyWindowsKeyCombinations}" Style="{StaticResource DefaultCheckBox}" />
     1131 + <ComboBox Grid.Column="2" Grid.Row="48" ItemsSource="{Binding RemoteDesktop_KeyboardHookModes}" SelectedItem="{Binding RemoteDesktop_KeyboardHookMode}" IsEnabled="{Binding RemoteDesktop_OverrideApplyWindowsKeyCombinations}">
    896 1132   <ComboBox.ItemTemplate>
    897 1133   <DataTemplate>
    898 1134   <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopKeyboardHookModeToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
    899 1135   </DataTemplate>
    900 1136   </ComboBox.ItemTemplate>
    901 1137   </ComboBox>
    902  - <CheckBox Grid.Column="0" Grid.Row="30" Content="{x:Static localization:Strings.RedirectClipboard}" IsChecked="{Binding RemoteDesktop_OverrideRedirectClipboard}" Style="{StaticResource DefaultCheckBox}" />
    903  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="30" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectClipboard}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectClipboard}" />
    904  - <CheckBox Grid.Column="0" Grid.Row="32" Content="{x:Static localization:Strings.RedirectDevices}" IsChecked="{Binding RemoteDesktop_OverrideRedirectDevices}" Style="{StaticResource DefaultCheckBox}" />
    905  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="32" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectDevices}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectDevices}" />
    906  - <CheckBox Grid.Column="0" Grid.Row="34" Content="{x:Static localization:Strings.RedirectDrives}" IsChecked="{Binding RemoteDesktop_OverrideRedirectDrives}" Style="{StaticResource DefaultCheckBox}" />
    907  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="34" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectDrives}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectDrives}"/>
    908  - <CheckBox Grid.Column="0" Grid.Row="36" Content="{x:Static localization:Strings.RedirectPorts}" IsChecked="{Binding RemoteDesktop_OverrideRedirectPorts}" Style="{StaticResource DefaultCheckBox}" />
    909  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="36" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectPorts}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectPorts}" />
    910  - <CheckBox Grid.Column="0" Grid.Row="38" Content="{x:Static localization:Strings.RedirectSmartcards}" IsChecked="{Binding RemoteDesktop_OverrideRedirectSmartcards}" Style="{StaticResource DefaultCheckBox}" />
    911  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="38" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectSmartCards}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectSmartcards}" />
    912  - <CheckBox Grid.Column="0" Grid.Row="40" Content="{x:Static localization:Strings.RedirectPrinters}" IsChecked="{Binding RemoteDesktop_OverrideRedirectPrinters}" Style="{StaticResource DefaultCheckBox}" />
    913  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="40" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectPrinters}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectPrinters}" />
    914  - <CheckBox Grid.Column="0" Grid.Row="42" Content="{x:Static localization:Strings.PersistentBitmapCaching}" IsChecked="{Binding RemoteDesktop_OverridePersistentBitmapCaching}" Style="{StaticResource DefaultCheckBox}" />
    915  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="42" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_PersistentBitmapCaching}" IsEnabled="{Binding RemoteDesktop_OverridePersistentBitmapCaching}" />
    916  - <CheckBox Grid.Column="0" Grid.Row="44" Content="{x:Static localization:Strings.ReconnectIfTheConnectionIsDropped}" IsChecked="{Binding RemoteDesktop_OverrideReconnectIfTheConnectionIsDropped}" Style="{StaticResource DefaultCheckBox}" />
    917  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="44" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_ReconnectIfTheConnectionIsDropped}" IsEnabled="{Binding RemoteDesktop_OverrideReconnectIfTheConnectionIsDropped}" />
    918  - <CheckBox Grid.Column="0" Grid.Row="46" Content="{x:Static localization:Strings.NetworkConnectionType}" IsChecked="{Binding RemoteDesktop_OverrideNetworkConnectionType}" Style="{StaticResource DefaultCheckBox}" />
    919  - <ComboBox Grid.Column="2" Grid.Row="46" ItemsSource="{Binding RemoteDesktop_NetworkConnectionTypes}" SelectedItem="{Binding RemoteDesktop_NetworkConnectionType}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}">
     1138 + <CheckBox Grid.Column="0" Grid.Row="50" Content="{x:Static localization:Strings.RedirectClipboard}" IsChecked="{Binding RemoteDesktop_OverrideRedirectClipboard}" Style="{StaticResource DefaultCheckBox}" />
     1139 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="50" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectClipboard}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectClipboard}" />
     1140 + <CheckBox Grid.Column="0" Grid.Row="52" Content="{x:Static localization:Strings.RedirectDevices}" IsChecked="{Binding RemoteDesktop_OverrideRedirectDevices}" Style="{StaticResource DefaultCheckBox}" />
     1141 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="52" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectDevices}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectDevices}" />
     1142 + <CheckBox Grid.Column="0" Grid.Row="54" Content="{x:Static localization:Strings.RedirectDrives}" IsChecked="{Binding RemoteDesktop_OverrideRedirectDrives}" Style="{StaticResource DefaultCheckBox}" />
     1143 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="54" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectDrives}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectDrives}"/>
     1144 + <CheckBox Grid.Column="0" Grid.Row="56" Content="{x:Static localization:Strings.RedirectPorts}" IsChecked="{Binding RemoteDesktop_OverrideRedirectPorts}" Style="{StaticResource DefaultCheckBox}" />
     1145 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="56" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectPorts}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectPorts}" />
     1146 + <CheckBox Grid.Column="0" Grid.Row="58" Content="{x:Static localization:Strings.RedirectSmartcards}" IsChecked="{Binding RemoteDesktop_OverrideRedirectSmartcards}" Style="{StaticResource DefaultCheckBox}" />
     1147 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="58" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectSmartCards}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectSmartcards}" />
     1148 + <CheckBox Grid.Column="0" Grid.Row="60" Content="{x:Static localization:Strings.RedirectPrinters}" IsChecked="{Binding RemoteDesktop_OverrideRedirectPrinters}" Style="{StaticResource DefaultCheckBox}" />
     1149 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="60" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_RedirectPrinters}" IsEnabled="{Binding RemoteDesktop_OverrideRedirectPrinters}" />
     1150 + <CheckBox Grid.Column="0" Grid.Row="62" Content="{x:Static localization:Strings.PersistentBitmapCaching}" IsChecked="{Binding RemoteDesktop_OverridePersistentBitmapCaching}" Style="{StaticResource DefaultCheckBox}" />
     1151 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="62" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_PersistentBitmapCaching}" IsEnabled="{Binding RemoteDesktop_OverridePersistentBitmapCaching}" />
     1152 + <CheckBox Grid.Column="0" Grid.Row="64" Content="{x:Static localization:Strings.ReconnectIfTheConnectionIsDropped}" IsChecked="{Binding RemoteDesktop_OverrideReconnectIfTheConnectionIsDropped}" Style="{StaticResource DefaultCheckBox}" />
     1153 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="64" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_ReconnectIfTheConnectionIsDropped}" IsEnabled="{Binding RemoteDesktop_OverrideReconnectIfTheConnectionIsDropped}" />
     1154 + <CheckBox Grid.Column="0" Grid.Row="66" Content="{x:Static localization:Strings.NetworkConnectionType}" IsChecked="{Binding RemoteDesktop_OverrideNetworkConnectionType}" Style="{StaticResource DefaultCheckBox}" />
     1155 + <ComboBox Grid.Column="2" Grid.Row="66" ItemsSource="{Binding RemoteDesktop_NetworkConnectionTypes}" SelectedItem="{Binding RemoteDesktop_NetworkConnectionType}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}">
    920 1156   <ComboBox.ItemTemplate>
    921 1157   <DataTemplate>
    922 1158   <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopNetworkConnectionTypeToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
    923 1159   </DataTemplate>
    924 1160   </ComboBox.ItemTemplate>
    925 1161   </ComboBox>
    926  - <TextBlock Grid.Column="0" Grid.Row="48" Text="{x:Static localization:Strings.DesktopBackground}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    927  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="48" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_DesktopBackground}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    928  - <TextBlock Grid.Column="0" Grid.Row="50" Text="{x:Static localization:Strings.FontSmoothing}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    929  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="50" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_FontSmoothing}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    930  - <TextBlock Grid.Column="0" Grid.Row="52" Text="{x:Static localization:Strings.DesktopComposition}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    931  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="52" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_DesktopComposition}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    932  - <TextBlock Grid.Column="0" Grid.Row="54" Text="{x:Static localization:Strings.ShowWindowContentsWhileDragging}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    933  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="54" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_ShowWindowContentsWhileDragging}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    934  - <TextBlock Grid.Column="0" Grid.Row="56" Text="{x:Static localization:Strings.MenuAndWindowAnimation}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    935  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="56" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_MenuAndWindowAnimation}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    936  - <TextBlock Grid.Column="0" Grid.Row="58" Text="{x:Static localization:Strings.VisualStyles}" Margin="24,0,0,0" Style="{StaticResource DisabledTextBlock}" />
    937  - <mah:ToggleSwitch Grid.Column="2" Grid.Row="58" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_VisualStyles}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     1162 + <TextBlock Grid.Column="0" Grid.Row="68" Text="{x:Static localization:Strings.DesktopBackground}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1163 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="68" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_DesktopBackground}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     1164 + <TextBlock Grid.Column="0" Grid.Row="70" Text="{x:Static localization:Strings.FontSmoothing}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1165 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="70" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_FontSmoothing}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     1166 + <TextBlock Grid.Column="0" Grid.Row="72" Text="{x:Static localization:Strings.DesktopComposition}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1167 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="72" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_DesktopComposition}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     1168 + <TextBlock Grid.Column="0" Grid.Row="74" Text="{x:Static localization:Strings.ShowWindowContentsWhileDragging}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1169 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="74" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_ShowWindowContentsWhileDragging}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     1170 + <TextBlock Grid.Column="0" Grid.Row="76" Text="{x:Static localization:Strings.MenuAndWindowAnimation}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1171 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="76" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_MenuAndWindowAnimation}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
     1172 + <TextBlock Grid.Column="0" Grid.Row="78" Text="{x:Static localization:Strings.VisualStyles}" Margin="24,0,0,0" VerticalAlignment="Center" Style="{StaticResource DisabledTextBlock}" />
     1173 + <mah:ToggleSwitch Grid.Column="2" Grid.Row="78" OffContent="" OnContent="" IsOn="{Binding RemoteDesktop_VisualStyles}" IsEnabled="{Binding RemoteDesktop_OverrideNetworkConnectionType}" />
    938 1174   </Grid>
    939 1175   </StackPanel>
    940 1176   </ScrollViewer>
    skipped 749 lines
    1690 1926   <Condition Binding="{Binding RemoteDesktop_Enabled}" Value="True"/>
    1691 1927   <Condition Binding="{Binding RemoteDesktop_OverridePort}" Value="True"/>
    1692 1928   <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopPort, Path=(Validation.HasError)}" Value="True" />
     1929 + </MultiDataTrigger.Conditions>
     1930 + <MultiDataTrigger.Setters>
     1931 + <Setter Property="IsEnabled" Value="False" />
     1932 + </MultiDataTrigger.Setters>
     1933 + </MultiDataTrigger>
     1934 + <MultiDataTrigger>
     1935 + <MultiDataTrigger.Conditions>
     1936 + <Condition Binding="{Binding RemoteDesktop_Enabled}" Value="True"/>
     1937 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True"/>
     1938 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True"/>
     1939 + <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopGatewayServerHostname, Path=(Validation.HasError)}" Value="True" />
     1940 + </MultiDataTrigger.Conditions>
     1941 + <MultiDataTrigger.Setters>
     1942 + <Setter Property="IsEnabled" Value="False" />
     1943 + </MultiDataTrigger.Setters>
     1944 + </MultiDataTrigger>
     1945 + <MultiDataTrigger>
     1946 + <MultiDataTrigger.Conditions>
     1947 + <Condition Binding="{Binding RemoteDesktop_Enabled}" Value="True"/>
     1948 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True"/>
     1949 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True"/>
     1950 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     1951 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     1952 + <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopGatewayServerUsername, Path=(Validation.HasError)}" Value="True" />
     1953 + </MultiDataTrigger.Conditions>
     1954 + <MultiDataTrigger.Setters>
     1955 + <Setter Property="IsEnabled" Value="False" />
     1956 + </MultiDataTrigger.Setters>
     1957 + </MultiDataTrigger>
     1958 + <MultiDataTrigger>
     1959 + <MultiDataTrigger.Conditions>
     1960 + <Condition Binding="{Binding RemoteDesktop_Enabled}" Value="True"/>
     1961 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True"/>
     1962 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True"/>
     1963 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     1964 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     1965 + <Condition Binding="{Binding ElementName=TextBoxRemoteDesktopGatewayServerDomain, Path=(Validation.HasError)}" Value="True" />
     1966 + </MultiDataTrigger.Conditions>
     1967 + <MultiDataTrigger.Setters>
     1968 + <Setter Property="IsEnabled" Value="False" />
     1969 + </MultiDataTrigger.Setters>
     1970 + </MultiDataTrigger>
     1971 + <MultiDataTrigger>
     1972 + <MultiDataTrigger.Conditions>
     1973 + <Condition Binding="{Binding RemoteDesktop_Enabled}" Value="True"/>
     1974 + <Condition Binding="{Binding RemoteDesktop_OverrideGatewayServer}" Value="True"/>
     1975 + <Condition Binding="{Binding RemoteDesktop_EnableGatewayServer}" Value="True"/>
     1976 + <Condition Binding="{Binding RemoteDesktop_GatewayServerLogonMethod}" Value="Userpass" />
     1977 + <Condition Binding="{Binding RemoteDesktop_UseGatewayServerCredentials}" Value="True" />
     1978 + <Condition Binding="{Binding RemoteDesktop_IsGatewayServerPasswordEmpty}" Value="True" />
    1693 1979   </MultiDataTrigger.Conditions>
    1694 1980   <MultiDataTrigger.Setters>
    1695 1981   <Setter Property="IsEnabled" Value="False" />
    skipped 205 lines
  • ■ ■ ■ ■
    Source/NETworkManager/Views/RemoteDesktopConnectDialog.xaml
    skipped 49 lines
    50 50   </TextBox.Text>
    51 51   </TextBox>
    52 52   <TextBlock Grid.Column="0" Grid.Row="1" Text="{x:Static localization:Strings.Host}" />
    53  - <ComboBox x:Name="ComboBoxHost" Grid.Column="2" Grid.Row="1" ItemsSource="{Binding HostHistoryView}" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleHostname}" IsEnabled="{Binding ConnectAs, Converter={StaticResource BooleanReverseConverter}}" Style="{StaticResource EditableComboBox}">
     53 + <ComboBox x:Name="ComboBoxHost" Grid.Column="2" Grid.Row="1" ItemsSource="{Binding HostHistoryView}" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleHostWithRDPPort}" IsEnabled="{Binding ConnectAs, Converter={StaticResource BooleanReverseConverter}}" Style="{StaticResource EditableComboBox}">
    54 54   <ComboBox.Text>
    55 55   <Binding Path="Host" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
    56 56   <Binding.ValidationRules>
    skipped 70 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager/Views/RemoteDesktopSettingsView.xaml
    skipped 11 lines
    12 12   <UserControl.Resources>
    13 13   <converters:RemoteDesktopAudioCaptureRedirectionModeToStringConverter x:Key="RemoteDesktopAudioCaptureRedirectionModeToStringConverter" />
    14 14   <converters:RemoteDesktopAudioRedirectionModeToStringConverter x:Key="RemoteDesktopAudioRedirectionModeToStringConverter" />
     15 + <converters:RemoteDesktopKeyboardHookModeToStringConverter x:Key="RemoteDesktopKeyboardHookModeToStringConverter" />
    15 16   <converters:RemoteDesktopNetworkConnectionTypeToStringConverter x:Key="RemoteDesktopNetworkConnectionTypeToStringConverter"/>
    16  - <converters:RemoteDesktopKeyboardHookModeToStringConverter x:Key="RemoteDesktopKeyboardHookModeToStringConverter" />
     17 + <converters:RemoteDesktopGatewayServerLogonMethodToStringConverter x:Key="RemoteDesktopGatewayServerLogonMethodToStringConverter" />
    17 18   </UserControl.Resources>
    18 19   <StackPanel>
    19 20   <TextBlock Text="{x:Static localization:Strings.Display}" Style="{StaticResource HeaderTextBlock}" />
    skipped 67 lines
    87 88   <Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource HelpToolTip}" />
    88 89   </Rectangle.Resources>
    89 90   </Rectangle>
     91 + </StackPanel>
     92 + <TextBlock Text="{x:Static localization:Strings.GatewayServer}" Style="{StaticResource HeaderTextBlock}" />
     93 + <mah:ToggleSwitch Header="{x:Static localization:Strings.EnableGatewayServer}" IsOn="{Binding EnableGatewayServer}" Margin="0,0,0,10" />
     94 + <StackPanel IsEnabled="{Binding EnableGatewayServer}" Margin="0,0,0,20">
     95 + <TextBlock Text="{x:Static localization:Strings.ServerName}" Style="{DynamicResource DefaultTextBlock}" Margin="0,0,0,10" />
     96 + <TextBox Width="250" HorizontalAlignment="Left" mah:TextBoxHelper.Watermark="{x:Static localization:StaticStrings.ExampleGatewayDomain}" Style="{StaticResource DefaultTextBox}" Margin="0,0,0,10">
     97 + <TextBox.Text>
     98 + <Binding Path="GatewayServerHostname" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
     99 + <Binding.ValidationRules>
     100 + <validators:EmptyValidator ValidatesOnTargetUpdated="True" />
     101 + <validators:RemoteDesktopHostnameAndPortValidator ValidatesOnTargetUpdated="True" />
     102 + </Binding.ValidationRules>
     103 + </Binding>
     104 + </TextBox.Text>
     105 + </TextBox>
     106 + <mah:ToggleSwitch Header="{x:Static localization:Strings.BypassForLocalAddresses}" IsOn="{Binding GatewayServerBypassLocalAddresses}" Margin="0,0,0,10" />
     107 + <TextBlock Text="{x:Static localization:Strings.LogonMethod}" Style="{DynamicResource DefaultTextBlock}" Margin="0,0,0,10" />
     108 + <ComboBox ItemsSource="{Binding GatewayServerLogonMethods}" SelectedItem="{Binding GatewayServerLogonMethod}" MinWidth="250" Width="Auto" HorizontalAlignment="Left" Margin="0,0,0,10">
     109 + <ComboBox.ItemTemplate>
     110 + <DataTemplate>
     111 + <TextBlock Text="{Binding Converter={StaticResource RemoteDesktopGatewayServerLogonMethodToStringConverter}}" Style="{StaticResource DefaultTextBlock}"/>
     112 + </DataTemplate>
     113 + </ComboBox.ItemTemplate>
     114 + </ComboBox>
     115 + <mah:ToggleSwitch Header="{x:Static localization:Strings.ShareGatewayCredentialsWithRemoteComputer}" IsOn="{Binding GatewayServerShareCredentialsWithRemoteComputer}" />
    90 116   </StackPanel>
    91 117   <TextBlock Text="{x:Static localization:Strings.RemoteAudio}" Style="{StaticResource HeaderTextBlock}" />
    92 118   <TextBlock Text="{x:Static localization:Strings.RemoteAudioPlayback}" Style="{DynamicResource DefaultTextBlock}" Margin="0,0,0,10" />
    skipped 64 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Converters/RemoteDesktopGatewayServerLogonMethodToStringConverter.cs
     1 +using NETworkManager.Localization.Translators;
     2 +using NETworkManager.Models.RemoteDesktop;
     3 +using System;
     4 +using System.Globalization;
     5 +using System.Windows.Data;
     6 + 
     7 +namespace NETworkManager.Converters;
     8 + 
     9 +/// <summary>
     10 +/// Convert <see cref="GatewayUserSelectedCredsSource"/> to translated <see cref="string"/> or wise versa.
     11 +/// </summary>
     12 +public sealed class RemoteDesktopGatewayServerLogonMethodToStringConverter : IValueConverter
     13 +{
     14 + /// <summary>
     15 + /// Convert <see cref="GatewayUserSelectedCredsSource"/> to translated <see cref="string"/>.
     16 + /// </summary>
     17 + /// <param name="value">Object from type <see cref="GatewayUserSelectedCredsSource"/>.</param>
     18 + /// <param name="targetType"></param>
     19 + /// <param name="parameter"></param>
     20 + /// <param name="culture"></param>
     21 + /// <returns>Translated <see cref="GatewayUserSelectedCredsSource"/>.</returns>
     22 + public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
     23 + {
     24 + if (value is not GatewayUserSelectedCredsSource gatewayUserSelectedCredsSource)
     25 + return "-/-";
     26 + 
     27 + return RemoteDesktopGatewayServerLogonMethodTranslator.GetInstance().Translate(gatewayUserSelectedCredsSource);
     28 + }
     29 + 
     30 + /// <summary>
     31 + /// !!! Method not implemented !!!
     32 + /// </summary>
     33 + /// <param name="value"></param>
     34 + /// <param name="targetType"></param>
     35 + /// <param name="parameter"></param>
     36 + /// <param name="culture"></param>
     37 + /// <returns></returns>
     38 + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     39 + {
     40 + throw new NotImplementedException();
     41 + }
     42 +}
     43 + 
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Localization/Resources/StaticStrings.Designer.cs
    skipped 141 lines
    142 142   }
    143 143  
    144 144   /// <summary>
     145 + /// Sucht eine lokalisierte Zeichenfolge, die gw.example.com ähnelt.
     146 + /// </summary>
     147 + public static string ExampleGatewayDomain {
     148 + get {
     149 + return ResourceManager.GetString("ExampleGatewayDomain", resourceCulture);
     150 + }
     151 + }
     152 +
     153 + /// <summary>
    145 154   /// Sucht eine lokalisierte Zeichenfolge, die Servers ähnelt.
    146 155   /// </summary>
    147 156   public static string ExampleGroupServers {
    skipped 8 lines
    156 165   public static string ExampleGroupSwitche {
    157 166   get {
    158 167   return ResourceManager.GetString("ExampleGroupSwitche", resourceCulture);
     168 + }
     169 + }
     170 +
     171 + /// <summary>
     172 + /// Sucht eine lokalisierte Zeichenfolge, die server-01.example.com ähnelt.
     173 + /// </summary>
     174 + public static string ExampleHostFQDN {
     175 + get {
     176 + return ResourceManager.GetString("ExampleHostFQDN", resourceCulture);
    159 177   }
    160 178   }
    161 179  
    skipped 39 lines
    201 219   public static string ExampleHostRange {
    202 220   get {
    203 221   return ResourceManager.GetString("ExampleHostRange", resourceCulture);
     222 + }
     223 + }
     224 +
     225 + /// <summary>
     226 + /// Sucht eine lokalisierte Zeichenfolge, die server-01.example.com:3389 ähnelt.
     227 + /// </summary>
     228 + public static string ExampleHostWithRDPPort {
     229 + get {
     230 + return ResourceManager.GetString("ExampleHostWithRDPPort", resourceCulture);
    204 231   }
    205 232   }
    206 233  
    skipped 479 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Localization/Resources/StaticStrings.resx
    skipped 323 lines
    324 324   <data name="ExamplePuTTYProfile" xml:space="preserve">
    325 325   <value>NETworkManager</value>
    326 326   </data>
     327 + <data name="ExampleHostFQDN" xml:space="preserve">
     328 + <value>server-01.example.com</value>
     329 + </data>
     330 + <data name="ExampleGatewayDomain" xml:space="preserve">
     331 + <value>gw.example.com</value>
     332 + </data>
     333 + <data name="ExampleHostWithRDPPort" xml:space="preserve">
     334 + <value>server-01.example.com:3389</value>
     335 + </data>
    327 336  </root>
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Localization/Resources/Strings.Designer.cs
    skipped 1266 lines
    1267 1267   }
    1268 1268  
    1269 1269   /// <summary>
     1270 + /// Sucht eine lokalisierte Zeichenfolge, die Bypass for local addresses ähnelt.
     1271 + /// </summary>
     1272 + public static string BypassForLocalAddresses {
     1273 + get {
     1274 + return ResourceManager.GetString("BypassForLocalAddresses", resourceCulture);
     1275 + }
     1276 + }
     1277 +
     1278 + /// <summary>
    1270 1279   /// Sucht eine lokalisierte Zeichenfolge, die Bytes ähnelt.
    1271 1280   /// </summary>
    1272 1281   public static string Bytes {
    skipped 1643 lines
    2916 2925   }
    2917 2926  
    2918 2927   /// <summary>
     2928 + /// Sucht eine lokalisierte Zeichenfolge, die Enable gateway server ähnelt.
     2929 + /// </summary>
     2930 + public static string EnableGatewayServer {
     2931 + get {
     2932 + return ResourceManager.GetString("EnableGatewayServer", resourceCulture);
     2933 + }
     2934 + }
     2935 +
     2936 + /// <summary>
    2919 2937   /// Sucht eine lokalisierte Zeichenfolge, die Enable log ähnelt.
    2920 2938   /// </summary>
    2921 2939   public static string EnableLog {
    skipped 617 lines
    3539 3557   }
    3540 3558  
    3541 3559   /// <summary>
     3560 + /// Sucht eine lokalisierte Zeichenfolge, die Gateway server ähnelt.
     3561 + /// </summary>
     3562 + public static string GatewayServer {
     3563 + get {
     3564 + return ResourceManager.GetString("GatewayServer", resourceCulture);
     3565 + }
     3566 + }
     3567 +
     3568 + /// <summary>
    3542 3569   /// Sucht eine lokalisierte Zeichenfolge, die General ähnelt.
    3543 3570   /// </summary>
    3544 3571   public static string General {
    skipped 1251 lines
    4796 4823   public static string LogMode {
    4797 4824   get {
    4798 4825   return ResourceManager.GetString("LogMode", resourceCulture);
     4826 + }
     4827 + }
     4828 +
     4829 + /// <summary>
     4830 + /// Sucht eine lokalisierte Zeichenfolge, die Logon method ähnelt.
     4831 + /// </summary>
     4832 + public static string LogonMethod {
     4833 + get {
     4834 + return ResourceManager.GetString("LogonMethod", resourceCulture);
    4799 4835   }
    4800 4836   }
    4801 4837  
    skipped 1786 lines
    6588 6624   }
    6589 6625  
    6590 6626   /// <summary>
     6627 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer due to one of the following reasons: 1) The requested Remote Desktop Gateway server address and the server SSL certificate subject name do not match. 2) The certificate is expired or revoked. 3) The certificate root authority does not trust the certificate. Contact your network administrator for assistance. ähnelt.
     6628 + /// </summary>
     6629 + public static string RemoteDesktopDisconnectReason_50331651 {
     6630 + get {
     6631 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331651", resourceCulture);
     6632 + }
     6633 + }
     6634 +
     6635 + /// <summary>
     6636 + /// Sucht eine lokalisierte Zeichenfolge, die This computer can&apos;t verify the identity of the RD Gateway &quot;&quot;. It&apos;s not safe to connect to servers that can&apos;t be identified. Contact your network administrator for assistance. ähnelt.
     6637 + /// </summary>
     6638 + public static string RemoteDesktopDisconnectReason_50331653 {
     6639 + get {
     6640 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331653", resourceCulture);
     6641 + }
     6642 + }
     6643 +
     6644 + /// <summary>
     6645 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server address requested and the certificate subject name do not match. Contact your network administrator for assistance. ähnelt.
     6646 + /// </summary>
     6647 + public static string RemoteDesktopDisconnectReason_50331654 {
     6648 + get {
     6649 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331654", resourceCulture);
     6650 + }
     6651 + }
     6652 +
     6653 + /// <summary>
     6654 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server&apos;s certificate has expired or has been revoked. Contact your network administrator for assistance. ähnelt.
     6655 + /// </summary>
     6656 + public static string RemoteDesktopDisconnectReason_50331655 {
     6657 + get {
     6658 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331655", resourceCulture);
     6659 + }
     6660 + }
     6661 +
     6662 + /// <summary>
     6663 + /// Sucht eine lokalisierte Zeichenfolge, die An error occurred while sending data to the Remote Desktop Gateway server. The server is temporarily unavailable or a network connection is down. Try again later, or contact your network administrator for assistance. ähnelt.
     6664 + /// </summary>
     6665 + public static string RemoteDesktopDisconnectReason_50331657 {
     6666 + get {
     6667 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331657", resourceCulture);
     6668 + }
     6669 + }
     6670 +
     6671 + /// <summary>
     6672 + /// Sucht eine lokalisierte Zeichenfolge, die An error occurred while receiving data from the Remote Desktop Gateway server. Either the server is temporarily unavailable or a network connection is down. Try again later, or contact your network administrator for assistance. ähnelt.
     6673 + /// </summary>
     6674 + public static string RemoteDesktopDisconnectReason_50331658 {
     6675 + get {
     6676 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331658", resourceCulture);
     6677 + }
     6678 + }
     6679 +
     6680 + /// <summary>
     6681 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server address is unreachable or incorrect. Type a valid Remote Desktop Gateway server address. ähnelt.
     6682 + /// </summary>
     6683 + public static string RemoteDesktopDisconnectReason_50331660 {
     6684 + get {
     6685 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331660", resourceCulture);
     6686 + }
     6687 + }
     6688 +
     6689 + /// <summary>
     6690 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server is temporarily unavailable. Try reconnecting later or contact your network administrator for assistance. ähnelt.
     6691 + /// </summary>
     6692 + public static string RemoteDesktopDisconnectReason_50331661 {
     6693 + get {
     6694 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331661", resourceCulture);
     6695 + }
     6696 + }
     6697 +
     6698 + /// <summary>
     6699 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server is running low on server resources and is temporarily unavailable. Try reconnecting later or contact your network administrator for assistance. ähnelt.
     6700 + /// </summary>
     6701 + public static string RemoteDesktopDisconnectReason_50331663 {
     6702 + get {
     6703 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331663", resourceCulture);
     6704 + }
     6705 + }
     6706 +
     6707 + /// <summary>
     6708 + /// Sucht eine lokalisierte Zeichenfolge, die The Remote Desktop Gateway server has ended the connection. Try reconnecting later or contact your network administrator for assistance. ähnelt.
     6709 + /// </summary>
     6710 + public static string RemoteDesktopDisconnectReason_50331672 {
     6711 + get {
     6712 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331672", resourceCulture);
     6713 + }
     6714 + }
     6715 +
     6716 + /// <summary>
     6717 + /// Sucht eine lokalisierte Zeichenfolge, die The Remote Desktop Gateway server administrator has ended the connection. Try reconnecting later or contact your network administrator for assistance. ähnelt.
     6718 + /// </summary>
     6719 + public static string RemoteDesktopDisconnectReason_50331673 {
     6720 + get {
     6721 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331673", resourceCulture);
     6722 + }
     6723 + }
     6724 +
     6725 + /// <summary>
     6726 + /// Sucht eine lokalisierte Zeichenfolge, die Remote Desktop can&apos;t connect to the remote computer &quot;&quot; for one of these reasons: 1) Your user account is not listed in the RD Gateway&apos;s permission list 2) You might have specified the remote computer in NetBIOS format (for example, computer1), but the RD Gateway is expecting an FQDN or IP address format (for example, computer1.fabrikam.com or 157.60.0.1). Contact your network administrator for assistance. ähnelt.
     6727 + /// </summary>
     6728 + public static string RemoteDesktopDisconnectReason_50331675 {
     6729 + get {
     6730 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331675", resourceCulture);
     6731 + }
     6732 + }
     6733 +
     6734 + /// <summary>
     6735 + /// Sucht eine lokalisierte Zeichenfolge, die Remote Desktop can&apos;t connect to the remote computer &quot;&quot; for one of these reasons: 1) Your user account is not authorized to access the RD Gateway &quot;&quot; 2) Your computer is not authorized to access the RD Gateway &quot;&quot; 3) You are using an incompatible authentication method (for example, the RD Gateway might be expecting a smart card but you provided a password) Contact your network administrator for assistance. ähnelt.
     6736 + /// </summary>
     6737 + public static string RemoteDesktopDisconnectReason_50331676 {
     6738 + get {
     6739 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331676", resourceCulture);
     6740 + }
     6741 + }
     6742 +
     6743 + /// <summary>
     6744 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because your network administrator has restricted access to this RD Gateway server. Contact your network administrator for assistance. ähnelt.
     6745 + /// </summary>
     6746 + public static string RemoteDesktopDisconnectReason_50331679 {
     6747 + get {
     6748 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331679", resourceCulture);
     6749 + }
     6750 + }
     6751 +
     6752 + /// <summary>
     6753 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the web proxy server requires authentication. To allow unauthenticated traffic to an RD Gateway server through your web proxy server, contact your network administrator. ähnelt.
     6754 + /// </summary>
     6755 + public static string RemoteDesktopDisconnectReason_50331680 {
     6756 + get {
     6757 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331680", resourceCulture);
     6758 + }
     6759 + }
     6760 +
     6761 + /// <summary>
     6762 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server reached its maximum allowed connections. Try reconnecting later or contact your network administrator for assistance. ähnelt.
     6763 + /// </summary>
     6764 + public static string RemoteDesktopDisconnectReason_50331682 {
     6765 + get {
     6766 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331682", resourceCulture);
     6767 + }
     6768 + }
     6769 +
     6770 + /// <summary>
     6771 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server does not support the request. Contact your network administrator for assistance. ähnelt.
     6772 + /// </summary>
     6773 + public static string RemoteDesktopDisconnectReason_50331683 {
     6774 + get {
     6775 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331683", resourceCulture);
     6776 + }
     6777 + }
     6778 +
     6779 + /// <summary>
     6780 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the client does not support one of the Remote Desktop Gateway&apos;s capabilities. Contact your network administrator for assistance. ähnelt.
     6781 + /// </summary>
     6782 + public static string RemoteDesktopDisconnectReason_50331684 {
     6783 + get {
     6784 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331684", resourceCulture);
     6785 + }
     6786 + }
     6787 +
     6788 + /// <summary>
     6789 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server and this computer are incompatible. Contact your network administrator for assistance. ähnelt.
     6790 + /// </summary>
     6791 + public static string RemoteDesktopDisconnectReason_50331685 {
     6792 + get {
     6793 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331685", resourceCulture);
     6794 + }
     6795 + }
     6796 +
     6797 + /// <summary>
     6798 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because no certificate was configured to use at the Remote Desktop Gateway server. Contact your network administrator for assistance. ähnelt.
     6799 + /// </summary>
     6800 + public static string RemoteDesktopDisconnectReason_50331688 {
     6801 + get {
     6802 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331688", resourceCulture);
     6803 + }
     6804 + }
     6805 +
     6806 + /// <summary>
     6807 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the RD Gateway server that you are trying to connect to is not allowed by your computer administrator. If you are the administrator, add this Remote Desktop Gateway server name to the trusted Remote Desktop Gateway server list on your computer and then try connecting again. ähnelt.
     6808 + /// </summary>
     6809 + public static string RemoteDesktopDisconnectReason_50331689 {
     6810 + get {
     6811 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331689", resourceCulture);
     6812 + }
     6813 + }
     6814 +
     6815 + /// <summary>
     6816 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because your computer or device did not meet the Network Access Protection requirements set by your network administrator, for one of the following reasons: 1) The Remote Desktop Gateway server name and the server&apos;s public key certificate subject name do not match. 2) The certificate has expired or has been revoked. 3) The certificate root authority does not trust the certificate. 4) The certificate key extension does not support encryption. 5) Your comput [Rest der Zeichenfolge wurde abgeschnitten]&quot;; ähnelt.
     6817 + /// </summary>
     6818 + public static string RemoteDesktopDisconnectReason_50331690 {
     6819 + get {
     6820 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331690", resourceCulture);
     6821 + }
     6822 + }
     6823 +
     6824 + /// <summary>
     6825 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because a user name and password are required to authenticate to the Remote Desktop Gateway server instead of smart card credentials. ähnelt.
     6826 + /// </summary>
     6827 + public static string RemoteDesktopDisconnectReason_50331691 {
     6828 + get {
     6829 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331691", resourceCulture);
     6830 + }
     6831 + }
     6832 +
     6833 + /// <summary>
     6834 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because smart card credentials are required to authenticate to the Remote Desktop Gateway server instead of a user name and password. ähnelt.
     6835 + /// </summary>
     6836 + public static string RemoteDesktopDisconnectReason_50331692 {
     6837 + get {
     6838 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331692", resourceCulture);
     6839 + }
     6840 + }
     6841 +
     6842 + /// <summary>
     6843 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because an invalid cookie was sent to the Remote Desktop Gateway server. Contact your network administrator for assistance. ähnelt.
     6844 + /// </summary>
     6845 + public static string RemoteDesktopDisconnectReason_50331700 {
     6846 + get {
     6847 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331700", resourceCulture);
     6848 + }
     6849 + }
     6850 +
     6851 + /// <summary>
     6852 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the cookie was rejected by the Remote Desktop Gateway server. Contact your network administrator for assistance. ähnelt.
     6853 + /// </summary>
     6854 + public static string RemoteDesktopDisconnectReason_50331701 {
     6855 + get {
     6856 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331701", resourceCulture);
     6857 + }
     6858 + }
     6859 +
     6860 + /// <summary>
     6861 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway server is expecting an authentication method different from the one attempted. Contact your network administrator for assistance. ähnelt.
     6862 + /// </summary>
     6863 + public static string RemoteDesktopDisconnectReason_50331703 {
     6864 + get {
     6865 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331703", resourceCulture);
     6866 + }
     6867 + }
     6868 +
     6869 + /// <summary>
     6870 + /// Sucht eine lokalisierte Zeichenfolge, die The RD Gateway connection ended because periodic user authentication failed. Try reconnecting with a correct user name and password. If the reconnection fails, contact your network administrator for further assistance. ähnelt.
     6871 + /// </summary>
     6872 + public static string RemoteDesktopDisconnectReason_50331704 {
     6873 + get {
     6874 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331704", resourceCulture);
     6875 + }
     6876 + }
     6877 +
     6878 + /// <summary>
     6879 + /// Sucht eine lokalisierte Zeichenfolge, die The RD Gateway connection ended because periodic user authorization failed. Try reconnecting with a correct user name and password. If the reconnection fails, contact your network administrator for further assistance. ähnelt.
     6880 + /// </summary>
     6881 + public static string RemoteDesktopDisconnectReason_50331705 {
     6882 + get {
     6883 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331705", resourceCulture);
     6884 + }
     6885 + }
     6886 +
     6887 + /// <summary>
     6888 + /// Sucht eine lokalisierte Zeichenfolge, die Your computer can&apos;t connect to the remote computer because the Remote Desktop Gateway and the remote computer are unable to exchange policies. This could happen due to one of the following reasons: 1. The remote computer is not capable of exchanging policies with the Remote Desktop Gateway. 2. The remote computer&apos;s configuration does not permit a new connection. 3. The connection between the Remote Desktop Gateway and the remote computer ended. Contact your network administrator for assistanc [Rest der Zeichenfolge wurde abgeschnitten]&quot;; ähnelt.
     6889 + /// </summary>
     6890 + public static string RemoteDesktopDisconnectReason_50331707 {
     6891 + get {
     6892 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331707", resourceCulture);
     6893 + }
     6894 + }
     6895 +
     6896 + /// <summary>
     6897 + /// Sucht eine lokalisierte Zeichenfolge, die The RD Gateway connection ended because periodic user authorization failed. Your computer or device didn&apos;t pass the Network Access Protection (NAP) requirements set by your network administrator. Contact your network administrator for assistance. ähnelt.
     6898 + /// </summary>
     6899 + public static string RemoteDesktopDisconnectReason_50331713 {
     6900 + get {
     6901 + return ResourceManager.GetString("RemoteDesktopDisconnectReason_50331713", resourceCulture);
     6902 + }
     6903 + }
     6904 +
     6905 + /// <summary>
    6591 6906   /// Sucht eine lokalisierte Zeichenfolge, die Socket closed. ähnelt.
    6592 6907   /// </summary>
    6593 6908   public static string RemoteDesktopDisconnectReason_AtClientWinsockFDCLOSE {
    skipped 435 lines
    7029 7344   }
    7030 7345  
    7031 7346   /// <summary>
     7347 + /// Sucht eine lokalisierte Zeichenfolge, die Allow me to select later ähnelt.
     7348 + /// </summary>
     7349 + public static string RemoteDesktopGatewayServerLogonMethod_Any {
     7350 + get {
     7351 + return ResourceManager.GetString("RemoteDesktopGatewayServerLogonMethod_Any", resourceCulture);
     7352 + }
     7353 + }
     7354 +
     7355 + /// <summary>
     7356 + /// Sucht eine lokalisierte Zeichenfolge, die Smart card ähnelt.
     7357 + /// </summary>
     7358 + public static string RemoteDesktopGatewayServerLogonMethod_Smartcard {
     7359 + get {
     7360 + return ResourceManager.GetString("RemoteDesktopGatewayServerLogonMethod_Smartcard", resourceCulture);
     7361 + }
     7362 + }
     7363 +
     7364 + /// <summary>
     7365 + /// Sucht eine lokalisierte Zeichenfolge, die Ask for password (NTLM) ähnelt.
     7366 + /// </summary>
     7367 + public static string RemoteDesktopGatewayServerLogonMethod_Userpass {
     7368 + get {
     7369 + return ResourceManager.GetString("RemoteDesktopGatewayServerLogonMethod_Userpass", resourceCulture);
     7370 + }
     7371 + }
     7372 +
     7373 + /// <summary>
    7032 7374   /// Sucht eine lokalisierte Zeichenfolge, die On the remote computer ähnelt.
    7033 7375   /// </summary>
    7034 7376   public static string RemoteDesktopKeyboardHookMode_OnTheRemoteComputer {
    skipped 642 lines
    7677 8019   }
    7678 8020  
    7679 8021   /// <summary>
     8022 + /// Sucht eine lokalisierte Zeichenfolge, die Server name ähnelt.
     8023 + /// </summary>
     8024 + public static string ServerName {
     8025 + get {
     8026 + return ResourceManager.GetString("ServerName", resourceCulture);
     8027 + }
     8028 + }
     8029 +
     8030 + /// <summary>
    7680 8031   /// Sucht eine lokalisierte Zeichenfolge, die Server(s) ähnelt.
    7681 8032   /// </summary>
    7682 8033   public static string Servers {
    skipped 192 lines
    7875 8226   public static string SettingsViewName_Window {
    7876 8227   get {
    7877 8228   return ResourceManager.GetString("SettingsViewName_Window", resourceCulture);
     8229 + }
     8230 + }
     8231 +
     8232 + /// <summary>
     8233 + /// Sucht eine lokalisierte Zeichenfolge, die Share Gateway credentials with remote computer ähnelt.
     8234 + /// </summary>
     8235 + public static string ShareGatewayCredentialsWithRemoteComputer {
     8236 + get {
     8237 + return ResourceManager.GetString("ShareGatewayCredentialsWithRemoteComputer", resourceCulture);
    7878 8238   }
    7879 8239   }
    7880 8240  
    skipped 1263 lines
    9144 9504   public static string UseCustomThemes {
    9145 9505   get {
    9146 9506   return ResourceManager.GetString("UseCustomThemes", resourceCulture);
     9507 + }
     9508 + }
     9509 +
     9510 + /// <summary>
     9511 + /// Sucht eine lokalisierte Zeichenfolge, die Use gateway credentials ähnelt.
     9512 + /// </summary>
     9513 + public static string UseGatewayCredentials {
     9514 + get {
     9515 + return ResourceManager.GetString("UseGatewayCredentials", resourceCulture);
    9147 9516   }
    9148 9517   }
    9149 9518  
    skipped 454 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Localization/Resources/Strings.resx
    skipped 3327 lines
    3328 3328   <data name="WarnMessage_MultipleInstances" xml:space="preserve">
    3329 3329   <value>Enabling this setting is not recommended. Multiple instances of the application share the same settings and profile files. The last instance to be closed may overwrite changes made by other instances.</value>
    3330 3330   </data>
     3331 + <data name="BypassForLocalAddresses" xml:space="preserve">
     3332 + <value>Bypass for local addresses</value>
     3333 + </data>
     3334 + <data name="EnableGatewayServer" xml:space="preserve">
     3335 + <value>Enable gateway server</value>
     3336 + </data>
     3337 + <data name="LogonMethod" xml:space="preserve">
     3338 + <value>Logon method</value>
     3339 + </data>
     3340 + <data name="GatewayServer" xml:space="preserve">
     3341 + <value>Gateway server</value>
     3342 + </data>
     3343 + <data name="ServerName" xml:space="preserve">
     3344 + <value>Server name</value>
     3345 + </data>
     3346 + <data name="ShareGatewayCredentialsWithRemoteComputer" xml:space="preserve">
     3347 + <value>Share Gateway credentials with remote computer</value>
     3348 + </data>
     3349 + <data name="RemoteDesktopGatewayServerLogonMethod_Any" xml:space="preserve">
     3350 + <value>Allow me to select later</value>
     3351 + </data>
     3352 + <data name="RemoteDesktopGatewayServerLogonMethod_Smartcard" xml:space="preserve">
     3353 + <value>Smart card</value>
     3354 + </data>
     3355 + <data name="RemoteDesktopGatewayServerLogonMethod_Userpass" xml:space="preserve">
     3356 + <value>Ask for password (NTLM)</value>
     3357 + </data>
     3358 + <data name="UseGatewayCredentials" xml:space="preserve">
     3359 + <value>Use gateway credentials</value>
     3360 + </data>
     3361 + <data name="RemoteDesktopDisconnectReason_50331661" xml:space="preserve">
     3362 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server is temporarily unavailable. Try reconnecting later or contact your network administrator for assistance.</value>
     3363 + </data>
     3364 + <data name="RemoteDesktopDisconnectReason_50331651" xml:space="preserve">
     3365 + <value>Your computer can't connect to the remote computer due to one of the following reasons: 1) The requested Remote Desktop Gateway server address and the server SSL certificate subject name do not match. 2) The certificate is expired or revoked. 3) The certificate root authority does not trust the certificate. Contact your network administrator for assistance.</value>
     3366 + </data>
     3367 + <data name="RemoteDesktopDisconnectReason_50331653" xml:space="preserve">
     3368 + <value>This computer can't verify the identity of the RD Gateway "". It's not safe to connect to servers that can't be identified. Contact your network administrator for assistance.</value>
     3369 + </data>
     3370 + <data name="RemoteDesktopDisconnectReason_50331654" xml:space="preserve">
     3371 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server address requested and the certificate subject name do not match. Contact your network administrator for assistance.</value>
     3372 + </data>
     3373 + <data name="RemoteDesktopDisconnectReason_50331655" xml:space="preserve">
     3374 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server's certificate has expired or has been revoked. Contact your network administrator for assistance.</value>
     3375 + </data>
     3376 + <data name="RemoteDesktopDisconnectReason_50331657" xml:space="preserve">
     3377 + <value>An error occurred while sending data to the Remote Desktop Gateway server. The server is temporarily unavailable or a network connection is down. Try again later, or contact your network administrator for assistance.</value>
     3378 + </data>
     3379 + <data name="RemoteDesktopDisconnectReason_50331658" xml:space="preserve">
     3380 + <value>An error occurred while receiving data from the Remote Desktop Gateway server. Either the server is temporarily unavailable or a network connection is down. Try again later, or contact your network administrator for assistance.</value>
     3381 + </data>
     3382 + <data name="RemoteDesktopDisconnectReason_50331660" xml:space="preserve">
     3383 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server address is unreachable or incorrect. Type a valid Remote Desktop Gateway server address.</value>
     3384 + </data>
     3385 + <data name="RemoteDesktopDisconnectReason_50331663" xml:space="preserve">
     3386 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server is running low on server resources and is temporarily unavailable. Try reconnecting later or contact your network administrator for assistance.</value>
     3387 + </data>
     3388 + <data name="RemoteDesktopDisconnectReason_50331672" xml:space="preserve">
     3389 + <value>The Remote Desktop Gateway server has ended the connection. Try reconnecting later or contact your network administrator for assistance.</value>
     3390 + </data>
     3391 + <data name="RemoteDesktopDisconnectReason_50331673" xml:space="preserve">
     3392 + <value>The Remote Desktop Gateway server administrator has ended the connection. Try reconnecting later or contact your network administrator for assistance.</value>
     3393 + </data>
     3394 + <data name="RemoteDesktopDisconnectReason_50331675" xml:space="preserve">
     3395 + <value>Remote Desktop can't connect to the remote computer "" for one of these reasons: 1) Your user account is not listed in the RD Gateway's permission list 2) You might have specified the remote computer in NetBIOS format (for example, computer1), but the RD Gateway is expecting an FQDN or IP address format (for example, computer1.fabrikam.com or 157.60.0.1). Contact your network administrator for assistance.</value>
     3396 + </data>
     3397 + <data name="RemoteDesktopDisconnectReason_50331676" xml:space="preserve">
     3398 + <value>Remote Desktop can't connect to the remote computer "" for one of these reasons: 1) Your user account is not authorized to access the RD Gateway "" 2) Your computer is not authorized to access the RD Gateway "" 3) You are using an incompatible authentication method (for example, the RD Gateway might be expecting a smart card but you provided a password) Contact your network administrator for assistance.</value>
     3399 + </data>
     3400 + <data name="RemoteDesktopDisconnectReason_50331679" xml:space="preserve">
     3401 + <value>Your computer can't connect to the remote computer because your network administrator has restricted access to this RD Gateway server. Contact your network administrator for assistance.</value>
     3402 + </data>
     3403 + <data name="RemoteDesktopDisconnectReason_50331680" xml:space="preserve">
     3404 + <value>Your computer can't connect to the remote computer because the web proxy server requires authentication. To allow unauthenticated traffic to an RD Gateway server through your web proxy server, contact your network administrator.</value>
     3405 + </data>
     3406 + <data name="RemoteDesktopDisconnectReason_50331682" xml:space="preserve">
     3407 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server reached its maximum allowed connections. Try reconnecting later or contact your network administrator for assistance.</value>
     3408 + </data>
     3409 + <data name="RemoteDesktopDisconnectReason_50331683" xml:space="preserve">
     3410 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server does not support the request. Contact your network administrator for assistance.</value>
     3411 + </data>
     3412 + <data name="RemoteDesktopDisconnectReason_50331684" xml:space="preserve">
     3413 + <value>Your computer can't connect to the remote computer because the client does not support one of the Remote Desktop Gateway's capabilities. Contact your network administrator for assistance.</value>
     3414 + </data>
     3415 + <data name="RemoteDesktopDisconnectReason_50331685" xml:space="preserve">
     3416 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server and this computer are incompatible. Contact your network administrator for assistance.</value>
     3417 + </data>
     3418 + <data name="RemoteDesktopDisconnectReason_50331688" xml:space="preserve">
     3419 + <value>Your computer can't connect to the remote computer because no certificate was configured to use at the Remote Desktop Gateway server. Contact your network administrator for assistance.</value>
     3420 + </data>
     3421 + <data name="RemoteDesktopDisconnectReason_50331689" xml:space="preserve">
     3422 + <value>Your computer can't connect to the remote computer because the RD Gateway server that you are trying to connect to is not allowed by your computer administrator. If you are the administrator, add this Remote Desktop Gateway server name to the trusted Remote Desktop Gateway server list on your computer and then try connecting again.</value>
     3423 + </data>
     3424 + <data name="RemoteDesktopDisconnectReason_50331690" xml:space="preserve">
     3425 + <value>Your computer can't connect to the remote computer because your computer or device did not meet the Network Access Protection requirements set by your network administrator, for one of the following reasons: 1) The Remote Desktop Gateway server name and the server's public key certificate subject name do not match. 2) The certificate has expired or has been revoked. 3) The certificate root authority does not trust the certificate. 4) The certificate key extension does not support encryption. 5) Your computer cannot verify the certificate revocation list. Contact your network administrator for assistance.</value>
     3426 + </data>
     3427 + <data name="RemoteDesktopDisconnectReason_50331691" xml:space="preserve">
     3428 + <value>Your computer can't connect to the remote computer because a user name and password are required to authenticate to the Remote Desktop Gateway server instead of smart card credentials.</value>
     3429 + </data>
     3430 + <data name="RemoteDesktopDisconnectReason_50331692" xml:space="preserve">
     3431 + <value>Your computer can't connect to the remote computer because smart card credentials are required to authenticate to the Remote Desktop Gateway server instead of a user name and password.</value>
     3432 + </data>
     3433 + <data name="RemoteDesktopDisconnectReason_50331700" xml:space="preserve">
     3434 + <value>Your computer can't connect to the remote computer because an invalid cookie was sent to the Remote Desktop Gateway server. Contact your network administrator for assistance.</value>
     3435 + </data>
     3436 + <data name="RemoteDesktopDisconnectReason_50331701" xml:space="preserve">
     3437 + <value>Your computer can't connect to the remote computer because the cookie was rejected by the Remote Desktop Gateway server. Contact your network administrator for assistance.</value>
     3438 + </data>
     3439 + <data name="RemoteDesktopDisconnectReason_50331703" xml:space="preserve">
     3440 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway server is expecting an authentication method different from the one attempted. Contact your network administrator for assistance.</value>
     3441 + </data>
     3442 + <data name="RemoteDesktopDisconnectReason_50331704" xml:space="preserve">
     3443 + <value>The RD Gateway connection ended because periodic user authentication failed. Try reconnecting with a correct user name and password. If the reconnection fails, contact your network administrator for further assistance.</value>
     3444 + </data>
     3445 + <data name="RemoteDesktopDisconnectReason_50331705" xml:space="preserve">
     3446 + <value>The RD Gateway connection ended because periodic user authorization failed. Try reconnecting with a correct user name and password. If the reconnection fails, contact your network administrator for further assistance.</value>
     3447 + </data>
     3448 + <data name="RemoteDesktopDisconnectReason_50331707" xml:space="preserve">
     3449 + <value>Your computer can't connect to the remote computer because the Remote Desktop Gateway and the remote computer are unable to exchange policies. This could happen due to one of the following reasons: 1. The remote computer is not capable of exchanging policies with the Remote Desktop Gateway. 2. The remote computer's configuration does not permit a new connection. 3. The connection between the Remote Desktop Gateway and the remote computer ended. Contact your network administrator for assistance.</value>
     3450 + </data>
     3451 + <data name="RemoteDesktopDisconnectReason_50331713" xml:space="preserve">
     3452 + <value>The RD Gateway connection ended because periodic user authorization failed. Your computer or device didn't pass the Network Access Protection (NAP) requirements set by your network administrator. Contact your network administrator for assistance.</value>
     3453 + </data>
    3331 3454  </root>
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Localization/Translators/RemoteDesktopGatewayServerLogonMethodTranslator.cs
     1 +using NETworkManager.Models.RemoteDesktop;
     2 +using NETworkManager.Utilities;
     3 + 
     4 +namespace NETworkManager.Localization.Translators;
     5 + 
     6 +/// <summary>
     7 +/// Class to translate <see cref="GatewayUserSelectedCredsSource"/>.
     8 +/// </summary>
     9 +public class RemoteDesktopGatewayServerLogonMethodTranslator : SingletonBase<RemoteDesktopGatewayServerLogonMethodTranslator>, ILocalizationStringTranslator
     10 +{
     11 + /// <summary>
     12 + /// Constant to identify the strings in the language files.
     13 + /// </summary>
     14 + private const string _identifier = "RemoteDesktopGatewayServerLogonMethod_";
     15 + 
     16 + /// <summary>
     17 + /// Method to translate <see cref="GatewayUserSelectedCredsSource"/>.
     18 + /// </summary>
     19 + /// <param name="value"><see cref="GatewayUserSelectedCredsSource"/>.</param>
     20 + /// <returns>Translated <see cref="GatewayUserSelectedCredsSource"/>.</returns>
     21 + public string Translate(string value)
     22 + {
     23 + var translation = Resources.Strings.ResourceManager.GetString(_identifier + value, LocalizationManager.GetInstance().Culture);
     24 + 
     25 + return string.IsNullOrEmpty(translation) ? value : translation;
     26 + }
     27 + 
     28 + /// <summary>
     29 + /// Method to translate <see cref="GatewayUserSelectedCredsSource"/>.
     30 + /// </summary>
     31 + /// <param name="gatewayUserSelectedCredsSource"><see cref="GatewayUserSelectedCredsSource"/>.</param>
     32 + /// <returns>Translated <see cref="GatewayUserSelectedCredsSource"/>.</returns>
     33 + public string Translate(GatewayUserSelectedCredsSource gatewayUserSelectedCredsSource)
     34 + {
     35 + return Translate(gatewayUserSelectedCredsSource.ToString());
     36 + }
     37 +}
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Models/RemoteDesktop/GatewayProfileUsageMethod.cs
     1 +namespace NETworkManager.Models.RemoteDesktop
     2 +{
     3 + /// <summary>
     4 + /// The RD Gateway profile usage method.
     5 + /// </summary>
     6 + public enum GatewayProfileUsageMethod : uint
     7 + {
     8 + /// <summary>
     9 + /// Use the default profile mode, as specified by the administrator.
     10 + /// </summary>
     11 + Default = 0,
     12 + 
     13 + /// <summary>
     14 + /// Use explicit settings, as specified by the user.
     15 + /// </summary>
     16 + Explicit = 1,
     17 + }
     18 +}
     19 + 
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Models/RemoteDesktop/GatewayUsageMethod.cs
     1 +namespace NETworkManager.Models.RemoteDesktop
     2 +{
     3 + /// <summary>
     4 + /// Specifies the RD Gateway server usage method.
     5 + /// Docs: https://learn.microsoft.com/en-us/windows/win32/termserv/imsrdpclienttransportsettings-gatewayusagemethod
     6 + /// </summary>
     7 + public enum GatewayUsageMethod : uint
     8 + {
     9 + /// <summary>
     10 + /// Do not use an RD Gateway server. In the Remote Desktop Connection (RDC) client UI,
     11 + /// the Bypass RD Gateway server for local addresses check box is cleared.
     12 + /// </summary>
     13 + NoneDirect = 0,
     14 + 
     15 + /// <summary>
     16 + /// Always use an RD Gateway server. In the RDC client UI, the Bypass RD Gateway server
     17 + /// for local addresses check box is cleared.
     18 + /// </summary>
     19 + Direct = 1,
     20 + 
     21 + /// <summary>
     22 + /// Use an RD Gateway server if a direct connection cannot be made to the RD Session
     23 + /// Host server. In the RDC client UI, the Bypass RD Gateway server for local addresses
     24 + /// check box is selected.
     25 + /// </summary>
     26 + Detect = 2,
     27 + 
     28 + /// <summary>
     29 + /// Use the default RD Gateway server settings.
     30 + /// </summary>
     31 + Default = 3,
     32 + 
     33 + /// <summary>
     34 + /// Do not use an RD Gateway server. In the RDC client UI, the Bypass RD Gateway server
     35 + /// for local addresses check box is selected.
     36 + /// </summary>
     37 + NoneDetect = 4
     38 + }
     39 +}
     40 + 
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Models/RemoteDesktop/GatewayUserSelectedCredsSource.cs
     1 +namespace NETworkManager.Models.RemoteDesktop
     2 +{
     3 + /// <summary>
     4 + /// Specifies the RD Gateway authentication method.
     5 + /// Docs: https://learn.microsoft.com/en-us/windows/win32/termserv/imsrdpclienttransportsettings-gatewayuserselectedcredssource
     6 + /// </summary>
     7 + public enum GatewayUserSelectedCredsSource : uint
     8 + {
     9 + /// <summary>
     10 + /// Use a password (NTLM) as the authentication method for RD Gateway.
     11 + /// </summary>
     12 + Userpass,
     13 + 
     14 + /// <summary>
     15 + /// Use a smart card as the authentication method for RD Gateway.
     16 + /// </summary>
     17 + Smartcard,
     18 + 
     19 + /// <summary>
     20 + /// Use any authentication method for RD Gateway.
     21 + /// </summary>
     22 + Any
     23 + }
     24 +}
     25 + 
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Models/RemoteDesktop/RemoteDesktop.cs
    skipped 3 lines
    4 4   
    5 5  public static class RemoteDesktop
    6 6  {
    7  - public static List<string> ScreenResolutions => new List<string>
     7 + public static List<string> ScreenResolutions => new()
    8 8   {
    9 9   "640x480",
    10 10   "800x600",
    skipped 9 lines
    20 20   "1920x1080"
    21 21   };
    22 22   
    23  - public static List<int> ColorDepths => new List<int>
     23 + public static List<int> ColorDepths => new()
    24 24   {
    25 25   15,
    26 26   16,
    skipped 3 lines
    30 30   
    31 31   public static RemoteDesktopKeystrokeInfo GetKeystroke(Keystroke keystroke)
    32 32   {
    33  - RemoteDesktopKeystrokeInfo info = new RemoteDesktopKeystrokeInfo();
     33 + RemoteDesktopKeystrokeInfo info = new();
    34 34   
    35 35   switch (keystroke)
    36 36   {
    skipped 10 lines
  • ■ ■ ■ ■ ■
    Source/NETworkManager.Models/RemoteDesktop/RemoteDesktopSessionInfo.cs
    skipped 4 lines
    5 5  public class RemoteDesktopSessionInfo
    6 6  {
    7 7   public string Hostname { get; set; }
    8  - public int Port { get; set; }
    9  - public bool CustomCredentials { get; set; }
     8 + public bool UseCredentials { get; set; }
    10 9   public string Username { get; set; }
     10 + public string Domain { get; set; }
    11 11   public SecureString Password { get; set; }
     12 + public int Port { get; set; }
    12 13   public bool AdjustScreenAutomatically { get; set; }
    13 14   public bool UseCurrentViewSize { get; set; }
    14 15   public int DesktopWidth { get; set; }
    skipped 1 lines
    16 17   public int ColorDepth { get; set; }
    17 18   public bool EnableCredSspSupport { get; set; }
    18 19   public uint AuthenticationLevel { get; set; }
     20 + public bool EnableGatewayServer { get; set; }
     21 + public string GatewayServerHostname { get; set; }
     22 + public bool GatewayServerBypassLocalAddresses { get; set; }
     23 + public GatewayUserSelectedCredsSource GatewayServerLogonMethod { get; set; }
     24 + public bool GatewayServerShareCredentialsWithRemoteComputer { get; set; }
     25 + public bool UseGatewayServerCredentials { get; set; }
     26 + public string GatewayServerUsername { get; set; }
     27 + public string GatewayServerDomain { get; set; }
     28 + public SecureString GatewayServerPassword { get; set; }
    19 29   public AudioRedirectionMode AudioRedirectionMode { get; set; }
    20 30   public AudioCaptureRedirectionMode AudioCaptureRedirectionMode { get; set; }
    21 31   public KeyboardHookMode KeyboardHookMode { get; set; }
    skipped 22 lines
  • ■ ■ ■ ■ ■
    Source/NETworkManager.Profiles/Application/RemoteDesktop.cs
    skipped 25 lines
    26 26   EnableCredSspSupport = SettingsManager.Current.RemoteDesktop_EnableCredSspSupport,
    27 27   AuthenticationLevel = SettingsManager.Current.RemoteDesktop_AuthenticationLevel,
    28 28   
     29 + // Gateway server
     30 + EnableGatewayServer = SettingsManager.Current.RemoteDesktop_EnableGatewayServer,
     31 + GatewayServerHostname = SettingsManager.Current.RemoteDesktop_GatewayServerHostname,
     32 + GatewayServerBypassLocalAddresses = SettingsManager.Current.RemoteDesktop_GatewayServerBypassLocalAddresses,
     33 + GatewayServerLogonMethod = SettingsManager.Current.RemoteDesktop_GatewayServerLogonMethod,
     34 + GatewayServerShareCredentialsWithRemoteComputer = SettingsManager.Current.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer,
     35 +
    29 36   // Remote audio
    30 37   AudioRedirectionMode = SettingsManager.Current.RemoteDesktop_AudioRedirectionMode,
    31 38   AudioCaptureRedirectionMode = SettingsManager.Current.RemoteDesktop_AudioCaptureRedirectionMode,
    skipped 34 lines
    66 73   // Override hostname
    67 74   info.Hostname = profile.RemoteDesktop_Host;
    68 75   
     76 + // Set credentials
     77 + if (profile.RemoteDesktop_UseCredentials)
     78 + {
     79 + info.UseCredentials = true;
     80 + 
     81 + info.Username = profile.RemoteDesktop_Username;
     82 + info.Domain = profile.RemoteDesktop_Domain;
     83 + info.Password = profile.RemoteDesktop_Password;
     84 + }
     85 + else if (group.RemoteDesktop_UseCredentials)
     86 + {
     87 + info.UseCredentials = true;
     88 + 
     89 + info.Username = group.RemoteDesktop_Username;
     90 + info.Domain = group.RemoteDesktop_Domain;
     91 + info.Password = group.RemoteDesktop_Password;
     92 + }
     93 + 
    69 94   // Network
    70 95   if (profile.RemoteDesktop_OverridePort)
    71 96   info.Port = profile.RemoteDesktop_Port;
    skipped 29 lines
    101 126   else if (group.RemoteDesktop_OverrideAuthenticationLevel)
    102 127   info.AuthenticationLevel = group.RemoteDesktop_AuthenticationLevel;
    103 128   
     129 + // Gateway server
     130 + if (profile.RemoteDesktop_OverrideGatewayServer)
     131 + {
     132 + info.EnableGatewayServer = profile.RemoteDesktop_EnableGatewayServer;
     133 + info.GatewayServerHostname = profile.RemoteDesktop_GatewayServerHostname;
     134 + info.GatewayServerBypassLocalAddresses = profile.RemoteDesktop_GatewayServerBypassLocalAddresses;
     135 + info.GatewayServerLogonMethod = profile.RemoteDesktop_GatewayServerLogonMethod;
     136 + info.GatewayServerShareCredentialsWithRemoteComputer = profile.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     137 + info.UseGatewayServerCredentials = profile.RemoteDesktop_UseGatewayServerCredentials;
     138 + info.GatewayServerUsername = profile.RemoteDesktop_GatewayServerUsername;
     139 + info.GatewayServerDomain = profile.RemoteDesktop_GatewayServerDomain;
     140 + info.GatewayServerPassword = profile.RemoteDesktop_GatewayServerPassword;
     141 + }
     142 + else if (group.RemoteDesktop_OverrideGatewayServer)
     143 + {
     144 + info.EnableGatewayServer = group.RemoteDesktop_EnableGatewayServer;
     145 + info.GatewayServerHostname = group.RemoteDesktop_GatewayServerHostname;
     146 + info.GatewayServerBypassLocalAddresses = group.RemoteDesktop_GatewayServerBypassLocalAddresses;
     147 + info.GatewayServerLogonMethod = group.RemoteDesktop_GatewayServerLogonMethod;
     148 + info.GatewayServerShareCredentialsWithRemoteComputer = group.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     149 + info.UseGatewayServerCredentials = group.RemoteDesktop_UseGatewayServerCredentials;
     150 + info.GatewayServerUsername = group.RemoteDesktop_GatewayServerUsername;
     151 + info.GatewayServerDomain = group.RemoteDesktop_GatewayServerDomain;
     152 + info.GatewayServerPassword = group.RemoteDesktop_GatewayServerPassword;
     153 + }
     154 + 
    104 155   // Remote audio
    105 156   if (profile.RemoteDesktop_OverrideAudioRedirectionMode)
    106 157   info.AudioRedirectionMode = profile.RemoteDesktop_AudioRedirectionMode;
    skipped 88 lines
    195 246   info.VisualStyles = profile.RemoteDesktop_VisualStyles;
    196 247   else if (group.RemoteDesktop_OverrideVisualStyles)
    197 248   info.VisualStyles = group.RemoteDesktop_VisualStyles;
    198  - 
    199  - // Set credentials
    200  - if (profile.RemoteDesktop_UseCredentials)
    201  - {
    202  - info.CustomCredentials = true;
    203  - 
    204  - info.Username = profile.RemoteDesktop_Username;
    205  - info.Password = profile.RemoteDesktop_Password;
    206  - }
    207  - else if (group.RemoteDesktop_UseCredentials)
    208  - {
    209  - info.CustomCredentials = true;
    210  - 
    211  - info.Username = group.RemoteDesktop_Username;
    212  - info.Password = group.RemoteDesktop_Password;
    213  - }
    214 249  
    215 250   return info;
    216 251   }
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Profiles/GroupInfo.cs
    skipped 24 lines
    25 25   
    26 26   public bool RemoteDesktop_UseCredentials { get; set; }
    27 27   public string RemoteDesktop_Username { get; set; }
     28 + public string RemoteDesktop_Domain { get; set; }
    28 29   
    29 30   [XmlIgnore]
    30 31   public SecureString RemoteDesktop_Password { get; set; }
    skipped 14 lines
    45 46   public bool RemoteDesktop_EnableCredSspSupport { get; set; }
    46 47   public bool RemoteDesktop_OverrideAuthenticationLevel { get; set; }
    47 48   public uint RemoteDesktop_AuthenticationLevel { get; set; } = GlobalStaticConfiguration.RemoteDesktop_AuthenticationLevel;
     49 + public bool RemoteDesktop_OverrideGatewayServer { get; set; }
     50 + public bool RemoteDesktop_EnableGatewayServer { get; set; }
     51 + public string RemoteDesktop_GatewayServerHostname { get; set; }
     52 + public bool RemoteDesktop_GatewayServerBypassLocalAddresses { get; set; } = GlobalStaticConfiguration.RemoteDesktop_GatewayServerBypassLocalAddresses;
     53 + public GatewayUserSelectedCredsSource RemoteDesktop_GatewayServerLogonMethod { get; set; } = GlobalStaticConfiguration.RemoteDesktop_GatewayServerLogonMethod;
     54 + public bool RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer { get; set; } = GlobalStaticConfiguration.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     55 + public bool RemoteDesktop_UseGatewayServerCredentials { get; set; }
     56 + public string RemoteDesktop_GatewayServerUsername { get; set; }
     57 + public string RemoteDesktop_GatewayServerDomain { get; set; }
     58 + 
     59 + [XmlIgnore]
     60 + public SecureString RemoteDesktop_GatewayServerPassword { get; set; }
    48 61   public bool RemoteDesktop_OverrideAudioRedirectionMode { get; set; }
    49 62   public AudioRedirectionMode RemoteDesktop_AudioRedirectionMode { get; set; } = GlobalStaticConfiguration.RemoteDesktop_AudioRedirectionMode;
    50 63   public bool RemoteDesktop_OverrideAudioCaptureRedirectionMode { get; set; }
    skipped 90 lines
    141 154   // Remote Desktop
    142 155   RemoteDesktop_UseCredentials = group.RemoteDesktop_UseCredentials;
    143 156   RemoteDesktop_Username = group.RemoteDesktop_Username;
     157 + RemoteDesktop_Domain = group.RemoteDesktop_Domain;
    144 158   RemoteDesktop_Password = group.RemoteDesktop_Password;
    145 159   RemoteDesktop_OverrideDisplay = group.RemoteDesktop_OverrideDisplay;
    146 160   RemoteDesktop_AdjustScreenAutomatically = group.RemoteDesktop_AdjustScreenAutomatically;
    skipped 12 lines
    159 173   RemoteDesktop_EnableCredSspSupport = group.RemoteDesktop_EnableCredSspSupport;
    160 174   RemoteDesktop_OverrideAuthenticationLevel = group.RemoteDesktop_OverrideAuthenticationLevel;
    161 175   RemoteDesktop_AuthenticationLevel = group.RemoteDesktop_AuthenticationLevel;
     176 + RemoteDesktop_OverrideGatewayServer = group.RemoteDesktop_OverrideGatewayServer;
     177 + RemoteDesktop_EnableGatewayServer = group.RemoteDesktop_EnableGatewayServer;
     178 + RemoteDesktop_GatewayServerHostname = group.RemoteDesktop_GatewayServerHostname;
     179 + RemoteDesktop_GatewayServerBypassLocalAddresses = group.RemoteDesktop_GatewayServerBypassLocalAddresses;
     180 + RemoteDesktop_GatewayServerLogonMethod = group.RemoteDesktop_GatewayServerLogonMethod;
     181 + RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = group.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     182 + RemoteDesktop_UseGatewayServerCredentials = group.RemoteDesktop_UseGatewayServerCredentials;
     183 + RemoteDesktop_GatewayServerUsername = group.RemoteDesktop_GatewayServerUsername;
     184 + RemoteDesktop_GatewayServerDomain = group.RemoteDesktop_GatewayServerDomain;
     185 + RemoteDesktop_GatewayServerPassword = group.RemoteDesktop_GatewayServerPassword;
    162 186   RemoteDesktop_OverrideAudioRedirectionMode = group.RemoteDesktop_OverrideAudioRedirectionMode;
    163 187   RemoteDesktop_AudioRedirectionMode = group.RemoteDesktop_AudioRedirectionMode;
    164 188   RemoteDesktop_OverrideAudioCaptureRedirectionMode = group.RemoteDesktop_OverrideAudioCaptureRedirectionMode;
    skipped 72 lines
  • ■ ■ ■ ■ ■
    Source/NETworkManager.Profiles/GroupInfoSerializable.cs
    skipped 13 lines
    14 14   /// </summary>
    15 15   public new string RemoteDesktop_Password { get; set; }
    16 16   
     17 + /// <summary>
     18 + /// Override the default remote desktop gateway password to make it serializable.
     19 + /// </summary>
     20 + public new string RemoteDesktop_GatewayServerPassword { get; set; }
     21 + 
    17 22   public GroupInfoSerializable()
    18 23   {
    19 24   
    skipped 8 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Profiles/ProfileInfo.cs
    skipped 69 lines
    70 70   public bool RemoteDesktop_Enabled { get; set; }
    71 71   public bool RemoteDesktop_InheritHost { get; set; } = true;
    72 72   public string RemoteDesktop_Host { get; set; }
    73  - 
    74 73   public bool RemoteDesktop_UseCredentials { get; set; }
    75  - 
    76 74   public string RemoteDesktop_Username { get; set; }
     75 + public string RemoteDesktop_Domain { get; set; }
    77 76  
    78 77   [XmlIgnore]
    79 78   public SecureString RemoteDesktop_Password { get; set; }
    skipped 14 lines
    94 93   public bool RemoteDesktop_EnableCredSspSupport { get; set; }
    95 94   public bool RemoteDesktop_OverrideAuthenticationLevel { get; set; }
    96 95   public uint RemoteDesktop_AuthenticationLevel { get; set; } = GlobalStaticConfiguration.RemoteDesktop_AuthenticationLevel;
     96 + public bool RemoteDesktop_OverrideGatewayServer { get; set; }
     97 + public bool RemoteDesktop_EnableGatewayServer { get; set; }
     98 + public string RemoteDesktop_GatewayServerHostname { get; set; }
     99 + public bool RemoteDesktop_GatewayServerBypassLocalAddresses { get; set; } = GlobalStaticConfiguration.RemoteDesktop_GatewayServerBypassLocalAddresses;
     100 + public GatewayUserSelectedCredsSource RemoteDesktop_GatewayServerLogonMethod { get; set; } = GlobalStaticConfiguration.RemoteDesktop_GatewayServerLogonMethod;
     101 + public bool RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer { get; set; } = GlobalStaticConfiguration.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     102 + public bool RemoteDesktop_UseGatewayServerCredentials { get; set; }
     103 + public string RemoteDesktop_GatewayServerUsername { get; set; }
     104 + public string RemoteDesktop_GatewayServerDomain { get; set; }
     105 + 
     106 + [XmlIgnore]
     107 + public SecureString RemoteDesktop_GatewayServerPassword { get; set; }
    97 108   public bool RemoteDesktop_OverrideAudioRedirectionMode { get; set; }
    98 109   public AudioRedirectionMode RemoteDesktop_AudioRedirectionMode { get; set; } = GlobalStaticConfiguration.RemoteDesktop_AudioRedirectionMode;
    99 110   public bool RemoteDesktop_OverrideAudioCaptureRedirectionMode { get; set; }
    skipped 155 lines
    255 266   RemoteDesktop_Host = profile.RemoteDesktop_Host;
    256 267   RemoteDesktop_UseCredentials = profile.RemoteDesktop_UseCredentials;
    257 268   RemoteDesktop_Username = profile.RemoteDesktop_Username;
     269 + RemoteDesktop_Domain = profile.RemoteDesktop_Domain;
    258 270   RemoteDesktop_Password = profile.RemoteDesktop_Password;
    259 271   RemoteDesktop_OverrideDisplay = profile.RemoteDesktop_OverrideDisplay;
    260 272   RemoteDesktop_AdjustScreenAutomatically = profile.RemoteDesktop_AdjustScreenAutomatically;
    skipped 12 lines
    273 285   RemoteDesktop_EnableCredSspSupport = profile.RemoteDesktop_EnableCredSspSupport;
    274 286   RemoteDesktop_OverrideAuthenticationLevel = profile.RemoteDesktop_OverrideAuthenticationLevel;
    275 287   RemoteDesktop_AuthenticationLevel = profile.RemoteDesktop_AuthenticationLevel;
     288 + RemoteDesktop_OverrideGatewayServer = profile.RemoteDesktop_OverrideGatewayServer;
     289 + RemoteDesktop_EnableGatewayServer = profile.RemoteDesktop_EnableGatewayServer;
     290 + RemoteDesktop_GatewayServerHostname = profile.RemoteDesktop_GatewayServerHostname;
     291 + RemoteDesktop_GatewayServerBypassLocalAddresses = profile.RemoteDesktop_GatewayServerBypassLocalAddresses;
     292 + RemoteDesktop_GatewayServerLogonMethod = profile.RemoteDesktop_GatewayServerLogonMethod;
     293 + RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = profile.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     294 + RemoteDesktop_UseGatewayServerCredentials = profile.RemoteDesktop_UseGatewayServerCredentials;
     295 + RemoteDesktop_GatewayServerUsername = profile.RemoteDesktop_GatewayServerUsername;
     296 + RemoteDesktop_GatewayServerDomain = profile.RemoteDesktop_GatewayServerDomain;
     297 + RemoteDesktop_GatewayServerPassword = profile.RemoteDesktop_GatewayServerPassword;
    276 298   RemoteDesktop_OverrideAudioRedirectionMode = profile.RemoteDesktop_OverrideAudioRedirectionMode;
    277 299   RemoteDesktop_AudioRedirectionMode = profile.RemoteDesktop_AudioRedirectionMode;
    278 300   RemoteDesktop_OverrideAudioCaptureRedirectionMode = profile.RemoteDesktop_OverrideAudioCaptureRedirectionMode;
    skipped 105 lines
  • ■ ■ ■ ■ ■
    Source/NETworkManager.Profiles/ProfileInfoSerializable.cs
    skipped 6 lines
    7 7   /// </summary>
    8 8   public new string RemoteDesktop_Password { get; set; }
    9 9   
     10 + /// <summary>
     11 + /// Override the default remote desktop gateway password to make it serializable.
     12 + /// </summary>
     13 + public new string RemoteDesktop_GatewayServerPassword { get; set; }
     14 +
    10 15   public ProfileInfoSerializable()
    11 16   {
    12 17   
    skipped 8 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Profiles/ProfileManager.cs
    skipped 542 lines
    543 543   {
    544 544   List<GroupInfoSerializable> groupsSerializable = new();
    545 545   
    546  - string groupRemoteDesktopPassword = string.Empty;
    547  - 
    548 546   foreach (GroupInfo group in groups)
    549 547   {
    550 548   // Don't save temp groups
    skipped 2 lines
    553 551   
    554 552   List<ProfileInfoSerializable> profilesSerializable = new();
    555 553   
    556  - string profileRemoteDesktopPassword = string.Empty;
    557  - 
    558 554   foreach (ProfileInfo profile in group.Profiles)
    559 555   {
    560 556   if (profile.IsDynamic)
    561 557   continue;
    562 558   
    563  - if (profile.RemoteDesktop_Password != null)
    564  - profileRemoteDesktopPassword = SecureStringHelper.ConvertToString(profile.RemoteDesktop_Password);
    565  - 
    566 559   profilesSerializable.Add(new ProfileInfoSerializable(profile)
    567 560   {
    568  - RemoteDesktop_Password = profileRemoteDesktopPassword
     561 + RemoteDesktop_Password = profile.RemoteDesktop_Password != null ? SecureStringHelper.ConvertToString(profile.RemoteDesktop_Password) : string.Empty,
     562 + RemoteDesktop_GatewayServerPassword = profile.RemoteDesktop_GatewayServerPassword != null ? SecureStringHelper.ConvertToString(profile.RemoteDesktop_GatewayServerPassword) : string.Empty,
    569 563   });
    570 564   }
    571 565   
    572  - if (group.RemoteDesktop_Password != null)
    573  - groupRemoteDesktopPassword = SecureStringHelper.ConvertToString(group.RemoteDesktop_Password);
    574  - 
    575 566   groupsSerializable.Add(new GroupInfoSerializable(group)
    576 567   {
    577 568   Profiles = profilesSerializable,
    578  - RemoteDesktop_Password = groupRemoteDesktopPassword
    579  - });
     569 + RemoteDesktop_Password = group.RemoteDesktop_Password != null ? SecureStringHelper.ConvertToString(group.RemoteDesktop_Password) : string.Empty,
     570 + RemoteDesktop_GatewayServerPassword = group.RemoteDesktop_GatewayServerPassword != null ? SecureStringHelper.ConvertToString(group.RemoteDesktop_GatewayServerPassword) : string.Empty,
     571 + }) ;
    580 572   }
    581 573   
    582 574   return groupsSerializable;
    skipped 42 lines
    625 617   {
    626 618   ProfileInfo profile = new(profileSerializable)
    627 619   {
    628  - RemoteDesktop_Password = !string.IsNullOrEmpty(profileSerializable.RemoteDesktop_Password) ? SecureStringHelper.ConvertToSecureString(profileSerializable.RemoteDesktop_Password) : null
     620 + RemoteDesktop_Password = !string.IsNullOrEmpty(profileSerializable.RemoteDesktop_Password) ? SecureStringHelper.ConvertToSecureString(profileSerializable.RemoteDesktop_Password) : null,
     621 + RemoteDesktop_GatewayServerPassword = !string.IsNullOrEmpty(profileSerializable.RemoteDesktop_GatewayServerPassword) ? SecureStringHelper.ConvertToSecureString(profileSerializable.RemoteDesktop_GatewayServerPassword) : null,
    629 622   };
    630 623   
    631 624   profiles.Add(profile);
    skipped 4 lines
    636 629   Profiles = profiles,
    637 630   
    638 631   // Convert passwort to secure string
    639  - RemoteDesktop_Password = !string.IsNullOrEmpty(groupSerializable.RemoteDesktop_Password) ? SecureStringHelper.ConvertToSecureString(groupSerializable.RemoteDesktop_Password) : null
     632 + RemoteDesktop_Password = !string.IsNullOrEmpty(groupSerializable.RemoteDesktop_Password) ? SecureStringHelper.ConvertToSecureString(groupSerializable.RemoteDesktop_Password) : null,
     633 + RemoteDesktop_GatewayServerPassword = !string.IsNullOrEmpty(groupSerializable.RemoteDesktop_GatewayServerPassword) ? SecureStringHelper.ConvertToSecureString(groupSerializable.RemoteDesktop_GatewayServerPassword) : null
    640 634   });
    641 635   }
    642 636   
    skipped 182 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Settings/GlobalStaticConfiguration.cs
    skipped 14 lines
    15 15   
    16 16  public static class GlobalStaticConfiguration
    17 17  {
     18 + #region Global settings
    18 19   // Type to search (average type speed --> 187 chars/min)
    19 20   public static TimeSpan SearchDispatcherTimerTimeSpan => new(0, 0, 0, 0, 750);
    20 21   
    21 22   // Status window delay in ms
    22 23   public static int StatusWindowDelayBeforeOpen => 5000;
    23 24   
     25 + // Profile config
     26 + public static bool Profile_ExpandProfileView => true;
     27 + public static double Profile_WidthCollapsed => 40;
     28 + public static double Profile_DefaultWidthExpanded => 250;
     29 + public static double Profile_MaxWidthExpanded => 500;
     30 + public static double Profile_FloatPointFix => 1.0;
     31 + public static int Profile_EncryptionKeySize => 256;
     32 + public static int Profile_EncryptionIterations => 1000000;
    24 33   
    25  - // Filter
     34 + // Filter for file dialog
    26 35   public static string ApplicationFileExtensionFilter => "Application (*.exe)|*.exe";
    27 36   public static string PuTTYPrivateKeyFileExtensionFilter => "PuTTY Private Key Files (*.ppk)|*.ppk";
    28 37   public static string ZipFileExtensionFilter => "ZIP Archive (*.zip)|*.zip";
    29 38   public static string XmlFileExtensionFilter => "XML-File (*.xml)|*.xml";
     39 + #endregion
    30 40   
    31  - // Settings
     41 + #region Default settings
     42 + // Settings: General
    32 43   public static ApplicationName General_DefaultApplicationViewName => ApplicationName.Dashboard;
    33 44   public static int General_BackgroundJobInterval => 5;
    34 45   public static int General_ThreadPoolAdditionalMinThreads => 512;
    35 46   public static int General_HistoryListEntries => 10;
     47 + 
     48 + // Settings: Window
    36 49   public static bool SplashScreen_Enabled => true;
     50 + 
     51 + // Settings: Appearance
    37 52   public static string Appearance_Theme => "Dark";
    38 53   public static string Appearance_Accent => "Lime";
    39 54   public static bool Appearance_UseCustomTheme => false;
     55 + 
     56 + // Settings: Network
    40 57   public static bool Network_ResolveHostnamePreferIPv4 => true;
     58 + 
     59 + // Settings: Status
    41 60   public static bool Status_ShowWindowOnNetworkChange => true;
    42 61   public static int Status_WindowCloseTime => 10;
    43  - public static string Status_IPAddressToDetectLocalIPAddressBasedOnRouting => "1.1.1.1";
    44  - 
    45  - // Fixes
    46  - public static double FloatPointFix => 1.0;
    47 62   
    48 63   // HotKey
    49 64   public static int HotKey_ShowWindowKey => 79;
    50 65   public static int HotKey_ShowWindowModifier => 3;
    51 66   
    52  - // Profile
    53  - public static double Profile_WidthCollapsed => 40;
    54  - public static double Profile_DefaultWidthExpanded => 250;
    55  - public static double Profile_MaxWidthExpanded => 350;
    56  - public static int Profile_EncryptionKeySize => 256;
    57  - public static int Profile_EncryptionIterations => 1000000;
     67 + // Update
     68 + public static bool Update_CheckForUpdatesAtStartup => true;
     69 + public static bool Update_CheckForPreReleases => false;
    58 70   
    59 71   // Application: Dashboard
    60 72   public static string Dashboard_PublicIPv4Address => "1.1.1.1";
    skipped 54 lines
    115 127   
    116 128   public static int RemoteDesktop_ColorDepth = 32;
    117 129   public static int RemoteDesktop_Port => 3389;
     130 + public static bool RemoteDesktop_GatewayServerBypassLocalAddresses => true;
     131 + public static GatewayUserSelectedCredsSource RemoteDesktop_GatewayServerLogonMethod => GatewayUserSelectedCredsSource.Any;
     132 + public static bool RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer => true;
    118 133   public static AudioRedirectionMode RemoteDesktop_AudioRedirectionMode => AudioRedirectionMode.PlayOnThisComputer;
    119 134   public static AudioCaptureRedirectionMode RemoteDesktop_AudioCaptureRedirectionMode => AudioCaptureRedirectionMode.DoNotRecord;
    120 135   public static KeyboardHookMode RemoteDesktop_KeyboardHookMode => KeyboardHookMode.OnTheRemoteComputer;
     136 + public static bool RemoteDesktop_RedirectClipboard => true;
     137 + public static bool RemoteDesktop_EnableCredSspSupport => true;
    121 138   public static uint RemoteDesktop_AuthenticationLevel => 2;
    122 139   
    123 140   public static NetworkConnectionType RemoteDesktop_NetworkConnectionType => NetworkConnectionType.DetectAutomatically;
    skipped 76 lines
    200 217   // Application: ARP Table
    201 218   public static ExportFileType ARPTable_ExportFileType => ExportFileType.CSV;
    202 219   public static AutoRefreshTimeInfo ARPTable_AutoRefreshTime => AutoRefreshTime.GetDefaults.First(x => x.Value == 30 && x.TimeUnit == TimeUnit.Second);
     220 + #endregion
    203 221  }
     222 + 
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Settings/SettingsInfo.cs
    skipped 455 lines
    456 456   }
    457 457   
    458 458   // Update
    459  - private bool _update_CheckForUpdatesAtStartup = true;
     459 + private bool _update_CheckForUpdatesAtStartup = GlobalStaticConfiguration.Update_CheckForUpdatesAtStartup;
    460 460   public bool Update_CheckForUpdatesAtStartup
    461 461   {
    462 462   get => _update_CheckForUpdatesAtStartup;
    skipped 8 lines
    471 471   }
    472 472   }
    473 473   
    474  - private bool _update_CheckForPreReleases;
     474 + private bool _update_CheckForPreReleases = GlobalStaticConfiguration.Update_CheckForPreReleases;
    475 475   public bool Update_CheckForPreReleases
    476 476   {
    477 477   get => _update_CheckForPreReleases;
    skipped 9 lines
    487 487   }
    488 488   
    489 489   // Profiles
    490  - private string _profiles_CustomProfilesLocation;
    491  - public string Profiles_CustomProfilesLocation
    492  - {
    493  - get => _profiles_CustomProfilesLocation;
    494  - set
    495  - {
    496  - if (value == _profiles_CustomProfilesLocation)
    497  - return;
    498  - 
    499  - _profiles_CustomProfilesLocation = value;
    500  - OnPropertyChanged();
    501  - SettingsChanged = true;
    502  - }
    503  - }
    504  - 
    505 490   private string _profiles_LastSelected;
    506 491   public string Profiles_LastSelected
    507 492   {
    skipped 151 lines
    659 644   }
    660 645   }
    661 646   
    662  - private bool _networkInterface_ExpandProfileView = true;
     647 + private bool _networkInterface_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    663 648   public bool NetworkInterface_ExpandProfileView
    664 649   {
    665 650   get => _networkInterface_ExpandProfileView;
    skipped 14 lines
    680 665   get => _networkInterface_ProfileWidth;
    681 666   set
    682 667   {
    683  - if (Math.Abs(value - _networkInterface_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     668 + if (Math.Abs(value - _networkInterface_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    684 669   return;
    685 670   
    686 671   _networkInterface_ProfileWidth = value;
    skipped 324 lines
    1011 996   }
    1012 997   }
    1013 998   
    1014  - private bool _ipScanner_ExpandProfileView = true;
     999 + private bool _ipScanner_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    1015 1000   public bool IPScanner_ExpandProfileView
    1016 1001   {
    1017 1002   get => _ipScanner_ExpandProfileView;
    skipped 14 lines
    1032 1017   get => _ipScanner_ProfileWidth;
    1033 1018   set
    1034 1019   {
    1035  - if (Math.Abs(value - _ipScanner_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     1020 + if (Math.Abs(value - _ipScanner_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    1036 1021   return;
    1037 1022   
    1038 1023   _ipScanner_ProfileWidth = value;
    skipped 153 lines
    1192 1177   }
    1193 1178   }
    1194 1179   
    1195  - private bool _portScanner_ExpandProfileView = true;
     1180 + private bool _portScanner_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    1196 1181   public bool PortScanner_ExpandProfileView
    1197 1182   {
    1198 1183   get => _portScanner_ExpandProfileView;
    skipped 14 lines
    1213 1198   get => _portScanner_ProfileWidth;
    1214 1199   set
    1215 1200   {
    1216  - if (Math.Abs(value - _portScanner_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     1201 + if (Math.Abs(value - _portScanner_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    1217 1202   return;
    1218 1203   
    1219 1204   _portScanner_ProfileWidth = value;
    skipped 154 lines
    1374 1359   }
    1375 1360   }
    1376 1361   
    1377  - private bool _pingMonitor_ExpandProfileView = true;
     1362 + private bool _pingMonitor_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    1378 1363   public bool PingMonitor_ExpandProfileView
    1379 1364   {
    1380 1365   get => _pingMonitor_ExpandProfileView;
    skipped 14 lines
    1395 1380   get => _pingMonitor_ProfileWidth;
    1396 1381   set
    1397 1382   {
    1398  - if (Math.Abs(value - _pingMonitor_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     1383 + if (Math.Abs(value - _pingMonitor_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    1399 1384   return;
    1400 1385   
    1401 1386   _pingMonitor_ProfileWidth = value;
    skipped 79 lines
    1481 1466   }
    1482 1467   }
    1483 1468   
    1484  - private bool _traceroute_ExpandProfileView = true;
     1469 + private bool _traceroute_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    1485 1470   public bool Traceroute_ExpandProfileView
    1486 1471   {
    1487 1472   get => _traceroute_ExpandProfileView;
    skipped 14 lines
    1502 1487   get => _traceroute_ProfileWidth;
    1503 1488   set
    1504 1489   {
    1505  - if (Math.Abs(value - _traceroute_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     1490 + if (Math.Abs(value - _traceroute_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    1506 1491   return;
    1507 1492   
    1508 1493   _traceroute_ProfileWidth = value;
    skipped 244 lines
    1753 1738   }
    1754 1739   }
    1755 1740   
    1756  - private bool _dnsLookup_ExpandProfileView = true;
     1741 + private bool _dnsLookup_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    1757 1742   public bool DNSLookup_ExpandProfileView
    1758 1743   {
    1759 1744   get => _dnsLookup_ExpandProfileView;
    skipped 14 lines
    1774 1759   get => _dnsLookup_ProfileWidth;
    1775 1760   set
    1776 1761   {
    1777  - if (Math.Abs(value - _dnsLookup_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     1762 + if (Math.Abs(value - _dnsLookup_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    1778 1763   return;
    1779 1764   
    1780 1765   _dnsLookup_ProfileWidth = value;
    skipped 199 lines
    1980 1965   }
    1981 1966   }
    1982 1967   
    1983  - private bool _remoteDesktop_EnableCredSspSupport = true;
     1968 + private bool _remoteDesktop_EnableCredSspSupport = GlobalStaticConfiguration.RemoteDesktop_EnableCredSspSupport;
    1984 1969   public bool RemoteDesktop_EnableCredSspSupport
    1985 1970   {
    1986 1971   get => _remoteDesktop_EnableCredSspSupport;
    skipped 23 lines
    2010 1995   }
    2011 1996   }
    2012 1997   
     1998 + private bool _remoteDesktop_EnableGatewayServer;
     1999 + public bool RemoteDesktop_EnableGatewayServer
     2000 + {
     2001 + get => _remoteDesktop_EnableGatewayServer;
     2002 + set
     2003 + {
     2004 + if (value == _remoteDesktop_EnableGatewayServer)
     2005 + return;
     2006 + 
     2007 + _remoteDesktop_EnableGatewayServer = value;
     2008 + OnPropertyChanged();
     2009 + SettingsChanged = true;
     2010 + }
     2011 + }
     2012 + 
     2013 + private string _remoteDesktop_GatewayServerHostname;
     2014 + public string RemoteDesktop_GatewayServerHostname
     2015 + {
     2016 + get => _remoteDesktop_GatewayServerHostname;
     2017 + set
     2018 + {
     2019 + if (value == _remoteDesktop_GatewayServerHostname)
     2020 + return;
     2021 + 
     2022 + _remoteDesktop_GatewayServerHostname = value;
     2023 + OnPropertyChanged();
     2024 + SettingsChanged = true;
     2025 + }
     2026 + }
     2027 + 
     2028 + private bool _remoteDesktop_GatewayServerBypassLocalAddresses = GlobalStaticConfiguration.RemoteDesktop_GatewayServerBypassLocalAddresses;
     2029 + public bool RemoteDesktop_GatewayServerBypassLocalAddresses
     2030 + {
     2031 + get => _remoteDesktop_GatewayServerBypassLocalAddresses;
     2032 + set
     2033 + {
     2034 + if (value == _remoteDesktop_GatewayServerBypassLocalAddresses)
     2035 + return;
     2036 + 
     2037 + _remoteDesktop_GatewayServerBypassLocalAddresses = value;
     2038 + OnPropertyChanged();
     2039 + SettingsChanged = true;
     2040 + }
     2041 + }
     2042 + 
     2043 + private GatewayUserSelectedCredsSource _remoteDesktop_GatewayServerLogonMethod = GlobalStaticConfiguration.RemoteDesktop_GatewayServerLogonMethod;
     2044 + public GatewayUserSelectedCredsSource RemoteDesktop_GatewayServerLogonMethod
     2045 + {
     2046 + get => _remoteDesktop_GatewayServerLogonMethod;
     2047 + set
     2048 + {
     2049 + if (value == _remoteDesktop_GatewayServerLogonMethod)
     2050 + return;
     2051 + 
     2052 + _remoteDesktop_GatewayServerLogonMethod = value;
     2053 + OnPropertyChanged();
     2054 + SettingsChanged = true;
     2055 + }
     2056 + }
     2057 + 
     2058 + private bool _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = GlobalStaticConfiguration.RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     2059 + public bool RemoteDesktop_GatewayServerShareCredentialsWithRemoteComputer
     2060 + {
     2061 + get => _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer;
     2062 + set
     2063 + {
     2064 + if (value == _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer)
     2065 + return;
     2066 + 
     2067 + _remoteDesktop_GatewayServerShareCredentialsWithRemoteComputer = value;
     2068 + OnPropertyChanged();
     2069 + SettingsChanged = true;
     2070 + }
     2071 + }
     2072 + 
    2013 2073   private AudioRedirectionMode _remoteDesktop_AudioRedirectionMode = GlobalStaticConfiguration.RemoteDesktop_AudioRedirectionMode;
    2014 2074   public AudioRedirectionMode RemoteDesktop_AudioRedirectionMode
    2015 2075   {
    skipped 39 lines
    2055 2115   }
    2056 2116   }
    2057 2117   
    2058  - private bool _remoteDesktop_RedirectClipboard = true;
     2118 + private bool _remoteDesktop_RedirectClipboard = GlobalStaticConfiguration.RemoteDesktop_RedirectClipboard;
    2059 2119   public bool RemoteDesktop_RedirectClipboard
    2060 2120   {
    2061 2121   get => _remoteDesktop_RedirectClipboard;
    skipped 218 lines
    2280 2340   }
    2281 2341   }
    2282 2342   
    2283  - private bool _remoteDesktop_ExpandProfileView = true;
     2343 + private bool _remoteDesktop_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    2284 2344   public bool RemoteDesktop_ExpandProfileView
    2285 2345   {
    2286 2346   get => _remoteDesktop_ExpandProfileView;
    skipped 14 lines
    2301 2361   get => _remoteDesktop_ProfileWidth;
    2302 2362   set
    2303 2363   {
    2304  - if (Math.Abs(value - _remoteDesktop_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     2364 + if (Math.Abs(value - _remoteDesktop_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    2305 2365   return;
    2306 2366   
    2307 2367   _remoteDesktop_ProfileWidth = value;
    skipped 79 lines
    2387 2447   }
    2388 2448   }
    2389 2449   
    2390  - private bool _powerShell_ExpandProfileView = true;
     2450 + private bool _powerShell_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    2391 2451   public bool PowerShell_ExpandProfileView
    2392 2452   {
    2393 2453   get => _powerShell_ExpandProfileView;
    skipped 14 lines
    2408 2468   get => _powerShell_ProfileWidth;
    2409 2469   set
    2410 2470   {
    2411  - if (Math.Abs(value - _powerShell_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     2471 + if (Math.Abs(value - _powerShell_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    2412 2472   return;
    2413 2473   
    2414 2474   _powerShell_ProfileWidth = value;
    skipped 244 lines
    2659 2719   }
    2660 2720   }
    2661 2721   
    2662  - private bool _puTTY_ExpandProfileView = true;
     2722 + private bool _puTTY_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    2663 2723   public bool PuTTY_ExpandProfileView
    2664 2724   {
    2665 2725   get => _puTTY_ExpandProfileView;
    skipped 14 lines
    2680 2740   get => _puTTY_ProfileWidth;
    2681 2741   set
    2682 2742   {
    2683  - if (Math.Abs(value - _puTTY_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     2743 + if (Math.Abs(value - _puTTY_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    2684 2744   return;
    2685 2745   
    2686 2746   _puTTY_ProfileWidth = value;
    skipped 244 lines
    2931 2991   }
    2932 2992   }
    2933 2993   
    2934  - private bool _awsSessionManager_ExpandProfileView = true;
     2994 + private bool _awsSessionManager_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    2935 2995   public bool AWSSessionManager_ExpandProfileView
    2936 2996   {
    2937 2997   get => _awsSessionManager_ExpandProfileView;
    skipped 14 lines
    2952 3012   get => _awsSessionManager_ProfileWidth;
    2953 3013   set
    2954 3014   {
    2955  - if (Math.Abs(value - _awsSessionManager_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     3015 + if (Math.Abs(value - _awsSessionManager_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    2956 3016   return;
    2957 3017   
    2958 3018   _awsSessionManager_ProfileWidth = value;
    skipped 34 lines
    2993 3053   }
    2994 3054   }
    2995 3055   
    2996  - private bool _tigerVNC_ExpandProfileView = true;
     3056 + private bool _tigerVNC_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    2997 3057   public bool TigerVNC_ExpandProfileView
    2998 3058   {
    2999 3059   get => _tigerVNC_ExpandProfileView;
    skipped 14 lines
    3014 3074   get => _tigerVNC_ProfileWidth;
    3015 3075   set
    3016 3076   {
    3017  - if (Math.Abs(value - _tigerVNC_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     3077 + if (Math.Abs(value - _tigerVNC_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    3018 3078   return;
    3019 3079   
    3020 3080   _tigerVNC_ProfileWidth = value;
    skipped 49 lines
    3070 3130   }
    3071 3131   }
    3072 3132   
    3073  - private bool _webConsole_ExpandProfileView = true;
     3133 + private bool _webConsole_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    3074 3134   public bool WebConsole_ExpandProfileView
    3075 3135   {
    3076 3136   get => _webConsole_ExpandProfileView;
    skipped 14 lines
    3091 3151   get => _webConsole_ProfileWidth;
    3092 3152   set
    3093 3153   {
    3094  - if (Math.Abs(value - _webConsole_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     3154 + if (Math.Abs(value - _webConsole_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    3095 3155   return;
    3096 3156   
    3097 3157   _webConsole_ProfileWidth = value;
    skipped 371 lines
    3469 3529   }
    3470 3530   }
    3471 3531   
    3472  - private bool _wakeOnLAN_ExpandProfileView = true;
     3532 + private bool _wakeOnLAN_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    3473 3533   public bool WakeOnLAN_ExpandProfileView
    3474 3534   {
    3475 3535   get => _wakeOnLAN_ExpandProfileView;
    skipped 14 lines
    3490 3550   get => _wakeOnLAN_ProfileWidth;
    3491 3551   set
    3492 3552   {
    3493  - if (Math.Abs(value - _wakeOnLAN_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     3553 + if (Math.Abs(value - _wakeOnLAN_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    3494 3554   return;
    3495 3555   
    3496 3556   _wakeOnLAN_ProfileWidth = value;
    skipped 274 lines
    3771 3831   }
    3772 3832   }
    3773 3833   
    3774  - private bool _whois_ExpandProfileView = true;
     3834 + private bool _whois_ExpandProfileView = GlobalStaticConfiguration.Profile_ExpandProfileView;
    3775 3835   public bool Whois_ExpandProfileView
    3776 3836   {
    3777 3837   get => _whois_ExpandProfileView;
    skipped 14 lines
    3792 3852   get => _whois_ProfileWidth;
    3793 3853   set
    3794 3854   {
    3795  - if (Math.Abs(value - _whois_ProfileWidth) < GlobalStaticConfiguration.FloatPointFix)
     3855 + if (Math.Abs(value - _whois_ProfileWidth) < GlobalStaticConfiguration.Profile_FloatPointFix)
    3796 3856   return;
    3797 3857   
    3798 3858   _whois_ProfileWidth = value;
    skipped 313 lines
  • ■ ■ ■ ■ ■ ■
    Source/NETworkManager.Validators/EmptyOrWindowsDomainValidator.cs
     1 +using NETworkManager.Localization.Resources;
     2 +using NETworkManager.Utilities;
     3 +using System.Globalization;
     4 +using System.Text.RegularExpressions;
     5 +using System.Windows.Controls;
     6 + 
     7 +namespace NETworkManager.Validators;
     8 + 
     9 +public class EmptyOrWindowsDomainValidator : ValidationRule
     10 +{
     11 + public override ValidationResult Validate(object value, CultureInfo cultureInfo)
     12 + {
     13 + if (string.IsNullOrEmpty(value as string))
     14 + return ValidationResult.ValidResult;
     15 + 
     16 + return Regex.IsMatch((string)value, RegexHelper.HostnameRegex) ? ValidationResult.ValidResult : new ValidationResult(false, Strings.EnterValidDomain);
     17 + }
     18 +}
     19 + 
  • ■ ■ ■ ■ ■ ■
    docs/Changelog/next-release.md
    skipped 15 lines
    16 16  - [.NET Desktop Runtime 6.x (LTS)](https://dotnet.microsoft.com/download/dotnet/6.0){:target="\_blank"}
    17 17   
    18 18  ## What's new?
     19 +- Remote Desktop
     20 + - Support for Remote Desktop Gateway server added [#2108](https://github.com/BornToBeRoot/NETworkManager/pull/2108){:target="\_blank"}
    19 21   
    20 22  ## Improvements
    21 23   
    skipped 17 lines
Please wait...
Page is in error, reload to recover