diff --git a/src/Lithnet.CredentialProvider/CredentialProviderBase.ICredentialProvider.cs b/src/Lithnet.CredentialProvider/CredentialProviderBase.ICredentialProvider.cs index a52a5e7..9d0cd1f 100644 --- a/src/Lithnet.CredentialProvider/CredentialProviderBase.ICredentialProvider.cs +++ b/src/Lithnet.CredentialProvider/CredentialProviderBase.ICredentialProvider.cs @@ -169,23 +169,20 @@ namespace Lithnet.CredentialProvider this.notifyOnTileCollectionChange = true; - var autoLogonTile = this.Tiles.FirstOrDefault(t => t.IsAutoLogon); - var defaultTile = this.Tiles.FirstOrDefault(t => t.IsDefault); + var defaultTile = this.DefaultTile; - uint defaultIndex = CREDENTIAL_PROVIDER_NO_DEFAULT; - if (autoLogonTile != null) + if (defaultTile != null) { - defaultIndex = (uint)this.tiles.IndexOf(autoLogonTile); - } - else if (defaultTile != null) - { - defaultIndex = (uint)this.tiles.IndexOf(defaultTile); + var index = this.tiles.IndexOf(defaultTile); + + if (index >= 0) + { + pdwDefault = (uint)index; + pbAutoLogonWithDefault = this.DefaultTileAutoLogon ? 1 : 0; + } } pdwCount = (uint)this.Tiles.Count; - pdwDefault = defaultIndex; - pbAutoLogonWithDefault = autoLogonTile == null ? 0 : 1; - this.logger.LogTrace($"GetCredentialCount returning pdwCount: {pdwCount}, pdwDefault: {pdwDefault}, pbAutoLogonWithDefault: {pbAutoLogonWithDefault}"); return HRESULT.S_OK; diff --git a/src/Lithnet.CredentialProvider/CredentialProviderBase.cs b/src/Lithnet.CredentialProvider/CredentialProviderBase.cs index 3568fb1..b1fb490 100644 --- a/src/Lithnet.CredentialProvider/CredentialProviderBase.cs +++ b/src/Lithnet.CredentialProvider/CredentialProviderBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using Lithnet.CredentialProvider.Interop; @@ -115,6 +116,35 @@ namespace Lithnet.CredentialProvider /// public abstract bool ShouldIncludeGenericTile(); + protected internal CredentialTile DefaultTile { get; set; } + + protected internal bool DefaultTileAutoLogon { get; set; } + + public void SetDefaultTile(CredentialTile tile, bool autoLogon) + { + if (this.DefaultTile == tile && this.DefaultTileAutoLogon == autoLogon) + { + return; + } + + if (!this.Tiles.Contains(tile)) + { + throw new InvalidOperationException("The default tile must be one of the tiles provided by the credential provider"); + } + + this.DefaultTile = tile; + this.DefaultTileAutoLogon = autoLogon; + this.ReloadUserTiles(); + } + + /// + /// Notifies LogonUI that one of more of the tile items has been modified, and should be reloaded + /// + public void ReloadUserTiles() + { + this.NotifyHostOfTileCollectionChange(); + } + /// /// Adds additional user tiles to the collection, and notifies LogonUI that new tiles are available /// diff --git a/src/Lithnet.CredentialProvider/CredentialTile.ICredentialProviderCredential.cs b/src/Lithnet.CredentialProvider/CredentialTile.ICredentialProviderCredential.cs index 81b0362..247a9f6 100644 --- a/src/Lithnet.CredentialProvider/CredentialTile.ICredentialProviderCredential.cs +++ b/src/Lithnet.CredentialProvider/CredentialTile.ICredentialProviderCredential.cs @@ -66,8 +66,8 @@ namespace Lithnet.CredentialProvider { this.logger.LogTrace("SetSelected"); this.IsSelected = true; - pbAutoLogon = this.IsAutoLogon ? 1 : 0; this.OnSelected(); + pbAutoLogon = this.OnSelectedShouldAutoLogon() ? 1 : 0; return HRESULT.S_OK; } catch (Exception ex) diff --git a/src/Lithnet.CredentialProvider/CredentialTile.cs b/src/Lithnet.CredentialProvider/CredentialTile.cs index 9afcac7..2252f47 100644 --- a/src/Lithnet.CredentialProvider/CredentialTile.cs +++ b/src/Lithnet.CredentialProvider/CredentialTile.cs @@ -13,7 +13,6 @@ namespace Lithnet.CredentialProvider private protected readonly ICredentialProviderLogger logger; private protected ICredentialProviderCredentialEvents events; private protected ICredentialProviderCredentialEvents2 events2; - private protected ControlCollection controls; protected CredentialTile(CredentialProviderBase credentialProvider) @@ -37,12 +36,18 @@ namespace Lithnet.CredentialProvider /// /// Gets a value that indicates if the user should be automatically logged on when the tile is selected. The tile must also have IsDefault set to true. /// - public bool IsAutoLogon { get; set; } + public bool IsDefaultTileAutoLogon + { + get => this.CredentialProvider.DefaultTile == this && this.CredentialProvider.DefaultTileAutoLogon; + } /// - /// Gets a value indicating if this should be the default time + /// Gets a value indicating if this should be the default tile /// - public bool IsDefault { get; set; } + public bool IsDefaultTile + { + get => this.CredentialProvider.DefaultTile == this; + } /// /// Gets the current usage scenario @@ -87,7 +92,7 @@ namespace Lithnet.CredentialProvider /// Gets the HWND of the parent of the credential provider, and notifies LogonUI or CredUI that we need to create a Window /// /// A HWND to the parentobject - /// The method was called before the host has advised that is ready to rpovide events + /// The method was called before the host has advised that is ready to provide events /// The request to obtain the parent window HWND failed public IntPtr CreateParentWindowHwnd() { @@ -156,6 +161,15 @@ namespace Lithnet.CredentialProvider /// protected virtual void OnSelected() { } + /// + /// Called after a tiles is selected to determine if the user should be automatically logged on + /// + /// True, if a logon should be immediately attempted + /// + /// In Windows 10, if a credential provider wants to automatically log the user on in a situation Windows does not think is appropriate, the system will display a sign in button as a speed bump. One example of this is when a user with an empty password locks the computer or signs out. In that scenario, Windows does not directly log the user back in. + /// + protected virtual bool OnSelectedShouldAutoLogon() => false; + /// /// Called when a user deselects this tile ///