diff --git a/README.md b/README.md index d9e9a13..683a176 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ public override CredentialTile2 CreateUserTile(CredentialProviderUser user) } ``` -* Create your tile class. Inherit from `CredentialTile2` if you want to create personalized tiles supported by Windows 8 and later, or `CredentialTile1` if you only want to implement a generic tile. Grab the instances of your controls in the `Initialize` method, so you can attach to their properties to read and respond to value changes. Finally, override the `GetCredentials` method, which is called when the user clicks the submit button. +* Create your tile class. Inherit from `CredentialTile2` if you want to create personalized tiles supported by Windows 8 and later, or `CredentialTile` if you only want to implement a generic tile. Use `CredentialTile3` when an image must preserve transparency. Grab the instances of your controls in the `Initialize` method, so you can attach to their properties to read and respond to value changes. Finally, override the `GetCredentials` method, which is called when the user clicks the submit button. ```cs public class MyTile : CredentialTile2 @@ -188,10 +188,44 @@ public class MyTile : CredentialTile2 }; } } +``` * Build your project and you have a functional credential provider! +## Bitmap transparency + +`CredentialProviderLogoControl` and `UserTileControl` both accept a `Bitmap`. The tile base class controls how Windows receives images that contain transparent or partially transparent pixels. + +| Tile base class | Image behaviour | +|-----------------|-----------------| +| `CredentialTile` | Renders transparency against the control's `BackgroundColor`. | +| `CredentialTile2` | Renders transparency against the control's `BackgroundColor`. | +| `CredentialTile3` | Preserves the image's alpha channel and ignores `BackgroundColor`. | + +Existing providers that inherit from `CredentialTile` or `CredentialTile2` keep their current behaviour. The default `BackgroundColor` is `#464646`. + +To preserve transparency, inherit your tile class from `CredentialTile3` and provide a `Bitmap` with an alpha channel. The library selects the image representation required by Windows, so your provider does not need to handle that conversion. + +```cs +public class MyTile : CredentialTile3 +{ + public MyTile(CredentialProviderBase credentialProvider) : base(credentialProvider) + { + } + + public MyTile(CredentialProviderBase credentialProvider, CredentialProviderUser user) : base(credentialProvider, user) + { + } +} + +public override IEnumerable GetControls(UsageScenario cpus) +{ + Bitmap image = LoadTransparentBitmap(); + yield return new UserTileControl("UserTile", "User tile image", image); + yield return new CredentialProviderLogoControl("ProviderLogo", "Credential provider logo", image); +} ``` + ## Installing the credential provider You can use the traditional methods of registering a credential provider (regasm, regsvr32, create registry keys etc), but we've provided a PowerShell module to automatically register your credential provider with a single command. diff --git a/src/Lithnet.CredentialProvider/ChangePasswordResponse.cs b/src/Lithnet.CredentialProvider/ChangePasswordResponse.cs index 13a9d70..a928226 100644 --- a/src/Lithnet.CredentialProvider/ChangePasswordResponse.cs +++ b/src/Lithnet.CredentialProvider/ChangePasswordResponse.cs @@ -1,7 +1,7 @@ namespace Lithnet.CredentialProvider { /// - /// The object is used to communicate the results of a password change operation to LogonUI + /// The object communicates the result of a password change operation to LogonUI. /// public class ChangePasswordResponse { diff --git a/src/Lithnet.CredentialProvider/ConsentUI/ConsentUIData.cs b/src/Lithnet.CredentialProvider/ConsentUI/ConsentUIData.cs index 34fe588..bb8d978 100644 --- a/src/Lithnet.CredentialProvider/ConsentUI/ConsentUIData.cs +++ b/src/Lithnet.CredentialProvider/ConsentUI/ConsentUIData.cs @@ -17,7 +17,7 @@ namespace Lithnet.CredentialProvider /// ConsentUIData is an abstract base class that represents all the different types of data structures that can be passed to the ConsentUI process for a UAC elevation prompt. /// The static members of the class can be used to retrieve the data structure passed to the ConsentUI process, or to determine if the current process is the ConsentUI process. /// The caller will be provided with one of the concrete implementations of this class, depending on the type of data structure that was passed to the ConsentUI process. - /// Use the property to determine the type of data structure and cast it to one of the concrete implementations. + /// Use the property to determine the type of data structure and cast it to one of the concrete implementations. /// public abstract class ConsentUIData { @@ -55,7 +55,7 @@ namespace Lithnet.CredentialProvider /// /// A series of flags that AppInfo passes to ConsentUI to signify actions that need to /// take place on the UI side. - /// This includes specifics around the UI that should be presented & signature verification settings. + /// This includes details about the UI that should be presented and the signature verification settings. /// public ConsentUIFlags Flags => this.header.Flags; @@ -356,4 +356,4 @@ namespace Lithnet.CredentialProvider return duplicatedToken; } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/BitmapControl.cs b/src/Lithnet.CredentialProvider/Controls/BitmapControl.cs index 35c71b5..b74a97a 100644 --- a/src/Lithnet.CredentialProvider/Controls/BitmapControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/BitmapControl.cs @@ -8,13 +8,20 @@ using Lithnet.CredentialProvider.Interop; namespace Lithnet.CredentialProvider { /// - /// The base class of image-based controls + /// Provides common image behaviour for credential provider logo and user tile controls. /// public abstract class BitmapControl : ControlBase { private Bitmap bitmap; private Color backgroundColor; + /// + /// Initializes an image control. + /// + /// The unique key for the control. + /// The label associated with the control. + /// to identify the image as the credential provider logo; otherwise, . + /// The initial image displayed by the control. protected BitmapControl(string key, string label, bool isProviderLogo, Bitmap bitmap) : base(key, label, FieldType.TileImage, isProviderLogo ? Guid.Parse(CredProviderConstants.CPFG_CREDENTIAL_PROVIDER_LOGO) : Guid.Empty) { @@ -22,6 +29,10 @@ namespace Lithnet.CredentialProvider this.backgroundColor = Color.FromArgb(70, 70, 70); } + /// + /// Initializes an image control by copying an existing image control. + /// + /// The image control to copy. protected BitmapControl(BitmapControl source) : base(source) { this.bitmap = source.bitmap; @@ -29,9 +40,9 @@ namespace Lithnet.CredentialProvider } /// - /// Specifies the background color used to replace transparent pixels for and . This defaults to #707070. + /// Gets or sets the background color used when an image that contains transparency is displayed by a or . /// - /// This property does not apply to . + /// The default color is #464646. A preserves the image's alpha channel and does not use this property. public Color BackgroundColor { get { return this.backgroundColor; } @@ -46,7 +57,7 @@ namespace Lithnet.CredentialProvider } /// - /// The image to be displayed + /// Gets or sets the image displayed by the control. /// public Bitmap Bitmap { diff --git a/src/Lithnet.CredentialProvider/Controls/CheckboxControl.cs b/src/Lithnet.CredentialProvider/Controls/CheckboxControl.cs index 6128dfa..33b80ef 100644 --- a/src/Lithnet.CredentialProvider/Controls/CheckboxControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/CheckboxControl.cs @@ -10,13 +10,13 @@ namespace Lithnet.CredentialProvider private bool isChecked; /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control public CheckboxControl(string key) : this(key, null) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -54,4 +54,4 @@ namespace Lithnet.CredentialProvider return clone; } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/ComboboxControl.cs b/src/Lithnet.CredentialProvider/Controls/ComboboxControl.cs index a8c8ef4..0598d2a 100644 --- a/src/Lithnet.CredentialProvider/Controls/ComboboxControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/ComboboxControl.cs @@ -10,13 +10,13 @@ namespace Lithnet.CredentialProvider private int selectedItemIndex; /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control public ComboboxControl(string key) : this(key, null) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -107,4 +107,4 @@ namespace Lithnet.CredentialProvider return clone; } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/CommandLinkControl.cs b/src/Lithnet.CredentialProvider/Controls/CommandLinkControl.cs index a077f28..1e90090 100644 --- a/src/Lithnet.CredentialProvider/Controls/CommandLinkControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/CommandLinkControl.cs @@ -9,13 +9,13 @@ namespace Lithnet.CredentialProvider public class CommandLinkControl : ControlBase { /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control public CommandLinkControl(string key) : this(key, null) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -35,4 +35,4 @@ namespace Lithnet.CredentialProvider return clone; } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/ControlBase.cs b/src/Lithnet.CredentialProvider/Controls/ControlBase.cs index d53d417..833e6f5 100644 --- a/src/Lithnet.CredentialProvider/Controls/ControlBase.cs +++ b/src/Lithnet.CredentialProvider/Controls/ControlBase.cs @@ -18,6 +18,10 @@ namespace Lithnet.CredentialProvider private string label; private FieldOptions options; private protected ICredentialProviderLogger logger; + + /// + /// Occurs when the value of a public property changes. + /// public event PropertyChangedEventHandler PropertyChanged; private protected ControlBase(ControlBase source) @@ -200,4 +204,4 @@ namespace Lithnet.CredentialProvider internal abstract ControlBase Clone(); } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/CredentialProviderLabelControl.cs b/src/Lithnet.CredentialProvider/Controls/CredentialProviderLabelControl.cs index 5d1805e..cb8c36b 100644 --- a/src/Lithnet.CredentialProvider/Controls/CredentialProviderLabelControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/CredentialProviderLabelControl.cs @@ -1,22 +1,21 @@ namespace Lithnet.CredentialProvider { /// - /// Represents a control that provides the credential UI with the name of this credential provider + /// Represents a control that provides the credential UI with the name of this credential provider. /// public class CredentialProviderLabelControl : SmallLabelControl { /// - /// Creates a new control + /// Creates a new control. /// - /// The unique key for this control - /// The label associated with the control + /// The unique key for this control. public CredentialProviderLabelControl(string key) : this(key, null) { } /// - /// Creates a new control + /// Creates a new control. /// - /// The unique key for this control - /// The label associated with the control + /// The unique key for this control. + /// The label associated with the control. public CredentialProviderLabelControl(string key, string label) : base(key, label, true) { this.State = FieldState.DisplayInDeselectedTile; @@ -29,4 +28,4 @@ return new CredentialProviderLabelControl(this); } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/CredentialProviderLogoControl.cs b/src/Lithnet.CredentialProvider/Controls/CredentialProviderLogoControl.cs index f8b11b2..cf22376 100644 --- a/src/Lithnet.CredentialProvider/Controls/CredentialProviderLogoControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/CredentialProviderLogoControl.cs @@ -3,29 +3,30 @@ namespace Lithnet.CredentialProvider { /// - /// Represents a control that provides the credential UI with the logo of this credential provider + /// Represents a control that provides the credential UI with the logo of this credential provider. /// + /// See for the image transparency behaviour of each credential tile version. public class CredentialProviderLogoControl : BitmapControl { /// - /// Creates a new control + /// Creates a new control. /// - /// The unique key for this control + /// The unique key for this control. public CredentialProviderLogoControl(string key) : this(key, null, null) { } /// - /// Creates a new control + /// Creates a new control. /// - /// The unique key for this control - /// The label associated with the control. This value is not displayed to the user + /// The unique key for this control. + /// The label associated with the control. This value is not displayed to the user. public CredentialProviderLogoControl(string key, string label) : this(key, label, null) { } /// - /// Creates a new control + /// Creates a new control. /// - /// The unique key for this control - /// The label associated with the control - /// The bitmap to use as the logo + /// The unique key for this control. + /// The label associated with the control. + /// The bitmap to use as the logo. public CredentialProviderLogoControl(string key, string label, Bitmap bitmap) : base(key, label, true, bitmap) { this.State = FieldState.DisplayInDeselectedTile; @@ -38,4 +39,4 @@ namespace Lithnet.CredentialProvider return new CredentialProviderLogoControl(this); } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/InsecurePasswordTextboxControl.cs b/src/Lithnet.CredentialProvider/Controls/InsecurePasswordTextboxControl.cs index 0d59df5..6d7a906 100644 --- a/src/Lithnet.CredentialProvider/Controls/InsecurePasswordTextboxControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/InsecurePasswordTextboxControl.cs @@ -12,13 +12,13 @@ namespace Lithnet.CredentialProvider private string password; /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control public InsecurePasswordTextboxControl(string key) : this(key, null) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -66,4 +66,4 @@ namespace Lithnet.CredentialProvider return clone; } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/LargeLabelControl.cs b/src/Lithnet.CredentialProvider/Controls/LargeLabelControl.cs index 5a9c294..d43fc24 100644 --- a/src/Lithnet.CredentialProvider/Controls/LargeLabelControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/LargeLabelControl.cs @@ -8,13 +8,13 @@ namespace Lithnet.CredentialProvider public class LargeLabelControl : ControlBase { /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control public LargeLabelControl(string key) : this(key, null) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -27,4 +27,4 @@ namespace Lithnet.CredentialProvider return new LargeLabelControl(this); } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/SecurePasswordTextboxControl.cs b/src/Lithnet.CredentialProvider/Controls/SecurePasswordTextboxControl.cs index 78efab8..d760277 100644 --- a/src/Lithnet.CredentialProvider/Controls/SecurePasswordTextboxControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/SecurePasswordTextboxControl.cs @@ -13,13 +13,13 @@ namespace Lithnet.CredentialProvider private SecureString password; /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control public SecurePasswordTextboxControl(string key) : this(key, null) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -67,4 +67,4 @@ namespace Lithnet.CredentialProvider return clone; } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/SimpleList.cs b/src/Lithnet.CredentialProvider/Controls/SimpleList.cs index b019ef9..3b0f41b 100644 --- a/src/Lithnet.CredentialProvider/Controls/SimpleList.cs +++ b/src/Lithnet.CredentialProvider/Controls/SimpleList.cs @@ -11,7 +11,14 @@ namespace Lithnet.CredentialProvider { private readonly List backingList = new List(); + /// + /// Occurs after an item is added to the list. + /// public event EventHandler ItemAdded; + + /// + /// Occurs after an item is removed from the list. The event value is the former zero-based index of the item. + /// public event EventHandler ItemRemoved; /// @@ -80,4 +87,4 @@ namespace Lithnet.CredentialProvider } } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/SmallLabelControl.cs b/src/Lithnet.CredentialProvider/Controls/SmallLabelControl.cs index 5be1e7a..d264c0c 100644 --- a/src/Lithnet.CredentialProvider/Controls/SmallLabelControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/SmallLabelControl.cs @@ -9,13 +9,13 @@ namespace Lithnet.CredentialProvider public class SmallLabelControl : ControlBase { /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control public SmallLabelControl(string key) : this(key, null, false) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -37,4 +37,4 @@ namespace Lithnet.CredentialProvider return new SmallLabelControl(this); } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/SubmitButtonControl.cs b/src/Lithnet.CredentialProvider/Controls/SubmitButtonControl.cs index 8aa30c5..9351842 100644 --- a/src/Lithnet.CredentialProvider/Controls/SubmitButtonControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/SubmitButtonControl.cs @@ -10,14 +10,14 @@ namespace Lithnet.CredentialProvider private ControlBase adjacentToControl; /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The control that the submit button should appear adjacent to public SubmitButtonControl(string key, ControlBase adjacentToControl) : this(key, null, adjacentToControl) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -62,4 +62,4 @@ namespace Lithnet.CredentialProvider return clone; } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/TextboxControl.cs b/src/Lithnet.CredentialProvider/Controls/TextboxControl.cs index 046f6a5..e780148 100644 --- a/src/Lithnet.CredentialProvider/Controls/TextboxControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/TextboxControl.cs @@ -13,13 +13,13 @@ namespace Lithnet.CredentialProvider private TextboxControl(TextboxControl source) : base(source) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control public TextboxControl(string key) : this(key, null) { } /// - /// Creates a new control + /// Creates a new control. /// /// The unique key for this control /// The label associated with the control @@ -58,4 +58,4 @@ namespace Lithnet.CredentialProvider return clone; } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Controls/UserTileControl.cs b/src/Lithnet.CredentialProvider/Controls/UserTileControl.cs index f37deb3..d37ab75 100644 --- a/src/Lithnet.CredentialProvider/Controls/UserTileControl.cs +++ b/src/Lithnet.CredentialProvider/Controls/UserTileControl.cs @@ -3,29 +3,30 @@ namespace Lithnet.CredentialProvider { /// - /// A control that displays the user's tile image + /// Represents a control that displays the user's tile image. /// + /// See for the image transparency behaviour of each credential tile version. public class UserTileControl : BitmapControl { /// - /// Creates a new control + /// Creates a new control. /// - /// The unique key for this control + /// The unique key for this control. public UserTileControl(string key) : this(key, null, null) { } /// - /// Creates a new control + /// Creates a new control. /// - /// The unique key for this control - /// The label associated with the control + /// The unique key for this control. + /// The label associated with the control. public UserTileControl(string key, string label) : this(key, label, null) { } /// - /// Creates a new control + /// Creates a new control. /// - /// The unique key for this control - /// The label associated with the control - /// The bitmap to use as the user's tile image + /// The unique key for this control. + /// The label associated with the control. + /// The bitmap to use as the user's tile image. public UserTileControl(string key, string label, Bitmap bitmap) : base(key, label, false, bitmap) { } private UserTileControl(UserTileControl source) : base(source) { } @@ -35,4 +36,4 @@ namespace Lithnet.CredentialProvider return new UserTileControl(this); } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/CredentialProviderBase.cs b/src/Lithnet.CredentialProvider/CredentialProviderBase.cs index b1fb490..7290b2a 100644 --- a/src/Lithnet.CredentialProvider/CredentialProviderBase.cs +++ b/src/Lithnet.CredentialProvider/CredentialProviderBase.cs @@ -67,6 +67,10 @@ namespace Lithnet.CredentialProvider /// public CredentialSerialization InboundSerialization { get; private set; } + /// + /// Initializes a credential provider and obtains its identifier from the on the derived class. + /// + /// The derived credential provider class does not have a . protected CredentialProviderBase() { this.LoggerFactory = this.GetLoggerFactory(); @@ -84,13 +88,13 @@ namespace Lithnet.CredentialProvider } /// - /// Gets a logger factory. Override this method and provide an implementation of to enable credential provider logging + /// Gets a logger factory. Override this method and provide an implementation of to enable credential provider logging. /// - /// An ILoggerFactory instance + /// An instance. protected virtual ICredentialProviderLoggerFactory GetLoggerFactory() { return TraceLoggerFactory.Instance; } /// - /// Gets a value indicating if the credential provider supports the provided by LogonUI or CredUI + /// Gets a value indicating whether the credential provider supports the provided by LogonUI or CredUI. /// /// The usage scenario /// Additional flags provided by CredUI @@ -116,10 +120,22 @@ namespace Lithnet.CredentialProvider /// public abstract bool ShouldIncludeGenericTile(); + /// + /// Gets or sets the tile that the credential provider reports as the default credential. + /// protected internal CredentialTile DefaultTile { get; set; } + /// + /// Gets or sets a value that indicates whether Logon UI or Credential UI should immediately request serialization from the default tile. + /// protected internal bool DefaultTileAutoLogon { get; set; } + /// + /// Sets the default tile, configures its automatic logon request, and notifies the credential UI to enumerate the tiles again. + /// + /// A tile in the current collection. + /// to make Logon UI or Credential UI immediately request serialization from the default tile; otherwise, . + /// is not in the current collection. public void SetDefaultTile(CredentialTile tile, bool autoLogon) { if (this.DefaultTile == tile && this.DefaultTileAutoLogon == autoLogon) @@ -188,7 +204,7 @@ namespace Lithnet.CredentialProvider } /// - /// This method is used to generate the generic tile for this credential provider. This is called when return true + /// Creates the generic tile for this credential provider. This method is called when returns . /// public abstract CredentialTile CreateGenericTile(); @@ -308,4 +324,4 @@ namespace Lithnet.CredentialProvider } } } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/CredentialTile.cs b/src/Lithnet.CredentialProvider/CredentialTile.cs index 2252f47..82862c2 100644 --- a/src/Lithnet.CredentialProvider/CredentialTile.cs +++ b/src/Lithnet.CredentialProvider/CredentialTile.cs @@ -15,6 +15,10 @@ namespace Lithnet.CredentialProvider private protected ICredentialProviderCredentialEvents2 events2; private protected ControlCollection controls; + /// + /// Initializes a version 1 credential tile. + /// + /// The credential provider that owns this tile. protected CredentialTile(CredentialProviderBase credentialProvider) { this.CredentialProvider = credentialProvider; @@ -34,7 +38,7 @@ namespace Lithnet.CredentialProvider public bool IsSelected { get; private set; } /// - /// 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. + /// Gets a value that indicates whether Logon UI or Credential UI should immediately request serialization from this tile. The tile must also be the default tile. /// public bool IsDefaultTileAutoLogon { @@ -111,7 +115,7 @@ namespace Lithnet.CredentialProvider } /// - /// Indicates to the host that multiple updates need to be made to the fields, and that it should delay updating the UI until + /// Indicates to the host that multiple fields will be updated and that it should delay updating the UI until is called. /// /// public void BeginBulkFieldUpdate() @@ -176,7 +180,7 @@ namespace Lithnet.CredentialProvider protected virtual void OnDeselected() { } /// - /// Called just before credentials are serialized and returned to the host + /// Called immediately before credentials are serialized and returned to the host /// protected virtual void OnBeforeSerialize() { } diff --git a/src/Lithnet.CredentialProvider/CredentialTile2.cs b/src/Lithnet.CredentialProvider/CredentialTile2.cs index e0a266d..bde3e4c 100644 --- a/src/Lithnet.CredentialProvider/CredentialTile2.cs +++ b/src/Lithnet.CredentialProvider/CredentialTile2.cs @@ -23,8 +23,17 @@ /// This does not apply in scenarios where a personalized tile is provided public GenericTileDisplayMode GenericTileDisplayMode { get; set; } + /// + /// Initializes a generic version 2 credential tile. + /// + /// The credential provider that owns this tile. protected CredentialTile2(CredentialProviderBase credentialProvider) : this(credentialProvider, null) { } + /// + /// Initializes a version 2 credential tile for a user. + /// + /// The credential provider that owns this tile. + /// The user represented by this tile, or for a generic tile. protected CredentialTile2(CredentialProviderBase credentialProvider, CredentialProviderUser user) : base(credentialProvider) { this.User = user; diff --git a/src/Lithnet.CredentialProvider/CredentialTile3.cs b/src/Lithnet.CredentialProvider/CredentialTile3.cs index fa0f365..1807e5d 100644 --- a/src/Lithnet.CredentialProvider/CredentialTile3.cs +++ b/src/Lithnet.CredentialProvider/CredentialTile3.cs @@ -4,13 +4,22 @@ using Lithnet.CredentialProvider.Interop; namespace Lithnet.CredentialProvider { /// - /// Represents a user credential tile that implements the functionality of and , but includes support for dynamically updating bitmap images. + /// Represents a version 3 credential tile that preserves transparency in bitmap controls. /// - /// This interface is public, but undocumented by Microsoft. It is recommended to use tiles unless this specific functionality is needed + /// Inherit from this class when a or must preserve the image's alpha channel. The property does not apply to this tile type. Microsoft does not publish documentation for the underlying version 3 credential interfaces, so use unless you need image transparency. public abstract partial class CredentialTile3 : CredentialTile2 { + /// + /// Initializes a generic version 3 credential tile. + /// + /// The credential provider that owns this tile. protected CredentialTile3(CredentialProviderBase credentialProvider) : this(credentialProvider, null) { } + /// + /// Initializes a version 3 credential tile for a user. + /// + /// The credential provider that owns this tile. + /// The user represented by this tile, or for a generic tile. protected CredentialTile3(CredentialProviderBase credentialProvider, CredentialProviderUser user) : base(credentialProvider, user) { } } } diff --git a/src/Lithnet.CredentialProvider/Enums/ConsentUIElevationReason.cs b/src/Lithnet.CredentialProvider/Enums/ConsentUIElevationReason.cs index 9c07c1e..c72d217 100644 --- a/src/Lithnet.CredentialProvider/Enums/ConsentUIElevationReason.cs +++ b/src/Lithnet.CredentialProvider/Enums/ConsentUIElevationReason.cs @@ -1,5 +1,8 @@ namespace Lithnet.CredentialProvider { + /// + /// Specifies the reason that Consent UI received an elevation request. + /// public enum ConsentUIElevationReason { /// @@ -86,4 +89,4 @@ /// NumReasons = 9, } -} \ No newline at end of file +} diff --git a/src/Lithnet.CredentialProvider/Enums/ConsentUIFlags.cs b/src/Lithnet.CredentialProvider/Enums/ConsentUIFlags.cs index 04a82bf..4d80e7f 100644 --- a/src/Lithnet.CredentialProvider/Enums/ConsentUIFlags.cs +++ b/src/Lithnet.CredentialProvider/Enums/ConsentUIFlags.cs @@ -2,9 +2,15 @@ namespace Lithnet.CredentialProvider { + /// + /// Specifies how Consent UI should display and verify an elevation request. + /// [Flags] public enum ConsentUIFlags { + /// + /// The purpose of the 0x01 flag is not documented. + /// SkipSignatureVerification = 0x01, /// @@ -12,8 +18,19 @@ namespace Lithnet.CredentialProvider /// SecureDesktop = 0x02, + /// + /// The purpose of the 0x04 flag is not documented. + /// Unknown1 = 0x04, + + /// + /// The purpose of the 0x08 flag is not documented. + /// Unknown2 = 0x08, + + /// + /// The purpose of the 0x10 flag is not documented. + /// Unknown3 = 0x10, /// @@ -42,6 +59,9 @@ namespace Lithnet.CredentialProvider /// AutoElevationOther = 0x100, + /// + /// The purpose of the 0x200 flag is not documented. + /// Unknown4 = 0x200, /// diff --git a/src/Lithnet.CredentialProvider/Enums/ConsentUIMsiAction.cs b/src/Lithnet.CredentialProvider/Enums/ConsentUIMsiAction.cs index 24e7ad1..d4aba4c 100644 --- a/src/Lithnet.CredentialProvider/Enums/ConsentUIMsiAction.cs +++ b/src/Lithnet.CredentialProvider/Enums/ConsentUIMsiAction.cs @@ -2,10 +2,24 @@ namespace Lithnet.CredentialProvider { + /// + /// Specifies the Windows Installer action described by Consent UI data. + /// public enum ConsentUIMsiAction : uint { + /// + /// Installs a Windows Installer package. + /// Install = 0, + + /// + /// Uninstalls a Windows Installer package. + /// Uninstall = 1, + + /// + /// Updates or repairs an installed Windows Installer package. + /// Update = 2 } } diff --git a/src/Lithnet.CredentialProvider/Enums/ConsentUIPromptType.cs b/src/Lithnet.CredentialProvider/Enums/ConsentUIPromptType.cs index eee927a..0a5920f 100644 --- a/src/Lithnet.CredentialProvider/Enums/ConsentUIPromptType.cs +++ b/src/Lithnet.CredentialProvider/Enums/ConsentUIPromptType.cs @@ -1,10 +1,28 @@ namespace Lithnet.CredentialProvider { + /// + /// Specifies how Consent UI obtains approval for an elevation request. + /// public enum ConsentUIPromptType { + /// + /// The prompt type is not known. + /// Unknown = 0, + + /// + /// Uses the Consent UI automatic administrator mode. + /// AutomaticAdmin = 1, + + /// + /// Requests consent from an administrator. + /// Consent = 2, + + /// + /// Requests administrator credentials. + /// Credentials = 3 } } diff --git a/src/Lithnet.CredentialProvider/Enums/ConsentUIType.cs b/src/Lithnet.CredentialProvider/Enums/ConsentUIType.cs index 91446e7..24ac003 100644 --- a/src/Lithnet.CredentialProvider/Enums/ConsentUIType.cs +++ b/src/Lithnet.CredentialProvider/Enums/ConsentUIType.cs @@ -1,12 +1,38 @@ namespace Lithnet.CredentialProvider { + /// + /// Identifies the type of data supplied to Consent UI for an elevation request. + /// public enum ConsentUIType { + /// + /// The data describes an executable file. + /// Exe = 0, + + /// + /// The data describes an elevated COM object. + /// Com = 1, + + /// + /// The data describes a Windows Installer package. + /// Msi = 2, + + /// + /// The data describes an ActiveX installation. + /// ActiveX = 3, + + /// + /// The data uses the CredCollect structure. The purpose of this structure is not documented. + /// CredCollect = 4, + + /// + /// The data describes a packaged application. + /// Msix = 5 } } diff --git a/src/Lithnet.CredentialProvider/Enums/CredUIWinFlags.cs b/src/Lithnet.CredentialProvider/Enums/CredUIWinFlags.cs index 182f8ad..948f68c 100644 --- a/src/Lithnet.CredentialProvider/Enums/CredUIWinFlags.cs +++ b/src/Lithnet.CredentialProvider/Enums/CredUIWinFlags.cs @@ -6,6 +6,9 @@ using System.Threading.Tasks; namespace Lithnet.CredentialProvider { + /// + /// Specifies options that control the Windows credential user interface. + /// [Flags] public enum CredUIWinFlags { diff --git a/src/Lithnet.CredentialProvider/Enums/SerializationResponse.cs b/src/Lithnet.CredentialProvider/Enums/SerializationResponse.cs index d6a6927..4593df5 100644 --- a/src/Lithnet.CredentialProvider/Enums/SerializationResponse.cs +++ b/src/Lithnet.CredentialProvider/Enums/SerializationResponse.cs @@ -1,5 +1,8 @@ namespace Lithnet.CredentialProvider { + /// + /// Specifies how the credential UI should continue after a credential provider handles a serialization request. + /// public enum SerializationResponse { /// diff --git a/src/Lithnet.CredentialProvider/Enums/UsageScenario.cs b/src/Lithnet.CredentialProvider/Enums/UsageScenario.cs index 9f43157..1bdbf06 100644 --- a/src/Lithnet.CredentialProvider/Enums/UsageScenario.cs +++ b/src/Lithnet.CredentialProvider/Enums/UsageScenario.cs @@ -18,7 +18,7 @@ /// /// Workstation unlock. Credential providers that implement this scenario should be prepared to serialize credentials to the local authority for authentication. These credential providers also need to enumerate the currently logged-in user as the default tile. /// - /// Starting in Windows 10, the CPUS_LOGON and CPUS_UNLOCK_WORKSTATION user scenarios have been combined. This enables the system to support multiple users logging into a machine without creating and switching sessions unnecessarily. Any user on the machine can log into it once it has been locked without needing to back out of a current session and create a new one. Because of this, CPUS_LOGON can be used both for logging onto a system or when a workstation is unlocked. However, CPUS_LOGON cannot be used in all cases. Because of policy restrictions imposed by various systems, sometimes it is necessary for the user scenario to be CPUS_UNLOCK_WORKSTATION. Your credential provider should be robust enough to create the appropriate credential structure based on the scenario given to it. Windows will request the appropriate user scenario based on the situation. Some of the factors that impact whether or not a CPUS_UNLOCK_WORKSTATION scenario must be used include the following. Note that this is just a subset of possibilities. + /// Starting in Windows 10, the CPUS_LOGON and CPUS_UNLOCK_WORKSTATION user scenarios have been combined. This enables the system to support multiple users logging into a machine without creating and switching sessions unnecessarily. Any user on the machine can log into it once it has been locked without needing to back out of a current session and create a new one. Because of this, CPUS_LOGON can be used both for logging onto a system or when a workstation is unlocked. However, CPUS_LOGON cannot be used in all cases. Because of policy restrictions imposed by various systems, sometimes it is necessary for the user scenario to be CPUS_UNLOCK_WORKSTATION. Your credential provider should be robust enough to create the appropriate credential structure based on the scenario given to it. Windows will request the appropriate user scenario based on the situation. Some of the factors that impact whether or not a CPUS_UNLOCK_WORKSTATION scenario must be used include the following. This is a subset of the possible factors. /// - The operating system of the device. /// - Whether this is a console or remote session. /// - Group policies such as hiding entry points for fast user switching, or interactive logon that does not display the user's last name. @@ -31,7 +31,7 @@ ChangePassword, /// - /// Credential UI. This scenario enables you to use credentials serialized by the credential provider to be used as authentication on remote machines. This is also the scenario used for over-the-shoulder prompting in User Access Control. This scenario uses a different instance of the credential provider than the one used for , , and , so the state of the credential provider cannot be maintained across the different scenarios. + /// Credential UI. This scenario enables you to use credentials serialized by the credential provider as authentication on remote machines. This is also the scenario used for over-the-shoulder prompting in User Access Control. This scenario uses a different instance of the credential provider than the one used for , , and , so the state of the credential provider cannot be maintained across the different scenarios. /// CredUI, diff --git a/src/Lithnet.CredentialProvider/Lithnet.CredentialProvider.csproj b/src/Lithnet.CredentialProvider/Lithnet.CredentialProvider.csproj index a3a8312..672f392 100644 --- a/src/Lithnet.CredentialProvider/Lithnet.CredentialProvider.csproj +++ b/src/Lithnet.CredentialProvider/Lithnet.CredentialProvider.csproj @@ -10,6 +10,7 @@ true 9 true + true @@ -25,6 +26,7 @@ true Lithnet.CredentialProvider MIT + README.md https://github.com/lithnet/windows-credential-provider https://github.com/lithnet/windows-credential-provider D:\dev\nuget\packages @@ -50,6 +52,10 @@ + + + + all diff --git a/src/Lithnet.CredentialProvider/Logging/ICredentialProviderLogger.cs b/src/Lithnet.CredentialProvider/Logging/ICredentialProviderLogger.cs index 874a906..75d9cde 100644 --- a/src/Lithnet.CredentialProvider/Logging/ICredentialProviderLogger.cs +++ b/src/Lithnet.CredentialProvider/Logging/ICredentialProviderLogger.cs @@ -2,16 +2,40 @@ namespace Lithnet.CredentialProvider { + /// + /// Receives log messages from a credential provider and its credential tiles. + /// public interface ICredentialProviderLogger { + /// + /// Logs an error message and its associated exception. + /// + /// The exception associated with the error. + /// The error message. void LogError(Exception ex, string message); + /// + /// Logs an error message. + /// + /// The error message. void LogError(string message); + /// + /// Logs a trace message. + /// + /// The trace message. void LogTrace(string message); + /// + /// Logs an informational message. + /// + /// The informational message. void LogInformation(string message); + /// + /// Logs a warning message. + /// + /// The warning message. void LogWarning(string message); } } diff --git a/src/Lithnet.CredentialProvider/Logging/ICredentialProviderLoggerFactory.cs b/src/Lithnet.CredentialProvider/Logging/ICredentialProviderLoggerFactory.cs index 4f03efe..cda6b61 100644 --- a/src/Lithnet.CredentialProvider/Logging/ICredentialProviderLoggerFactory.cs +++ b/src/Lithnet.CredentialProvider/Logging/ICredentialProviderLoggerFactory.cs @@ -2,10 +2,23 @@ namespace Lithnet.CredentialProvider { + /// + /// Creates loggers for credential provider components. + /// public interface ICredentialProviderLoggerFactory { + /// + /// Creates a logger for the specified component type. + /// + /// The type that will write log messages. + /// A logger for the specified type. ICredentialProviderLogger CreateLogger(Type type); + /// + /// Creates a logger for the specified component type. + /// + /// The type that will write log messages. + /// A logger for the specified type. ICredentialProviderLogger CreateLogger(); } } diff --git a/src/Lithnet.CredentialProvider/Logging/TraceLogger.cs b/src/Lithnet.CredentialProvider/Logging/TraceLogger.cs index cbbbc06..d8249f2 100644 --- a/src/Lithnet.CredentialProvider/Logging/TraceLogger.cs +++ b/src/Lithnet.CredentialProvider/Logging/TraceLogger.cs @@ -3,28 +3,52 @@ using System.Diagnostics; namespace Lithnet.CredentialProvider { + /// + /// Writes credential provider log messages to . + /// public class TraceLogger : ICredentialProviderLogger { + /// + /// Writes an error message and its associated exception to . + /// + /// The exception associated with the error. + /// The error message. public void LogError(Exception ex, string v) { Trace.WriteLine($"{v}\r\n\r\n{ex?.ToString()}"); } + /// + /// Writes an error message to . + /// + /// The error message. public void LogError(string v) { Trace.WriteLine(v); } + /// + /// Writes an informational message to . + /// + /// The informational message. public void LogInformation(string message) { Trace.WriteLine(message); } + /// + /// Writes a trace message to . + /// + /// The trace message. public void LogTrace(string v) { Trace.WriteLine(v); } + /// + /// Writes a warning message to . + /// + /// The warning message. public void LogWarning(string message) { Trace.WriteLine(message); diff --git a/src/Lithnet.CredentialProvider/Logging/TraceLoggerFactory.cs b/src/Lithnet.CredentialProvider/Logging/TraceLoggerFactory.cs index 6b46753..38bf084 100644 --- a/src/Lithnet.CredentialProvider/Logging/TraceLoggerFactory.cs +++ b/src/Lithnet.CredentialProvider/Logging/TraceLoggerFactory.cs @@ -2,13 +2,26 @@ namespace Lithnet.CredentialProvider { + /// + /// Creates instances. + /// public class TraceLoggerFactory : ICredentialProviderLoggerFactory { + /// + /// Creates a trace logger for the specified component type. + /// + /// The type that will write log messages. + /// A trace logger for the specified type. public ICredentialProviderLogger CreateLogger(Type type) { return new TraceLogger(); } + /// + /// Creates a trace logger for the specified component type. + /// + /// The type that will write log messages. + /// A trace logger for the specified type. public ICredentialProviderLogger CreateLogger() { return new TraceLogger(); @@ -16,6 +29,9 @@ namespace Lithnet.CredentialProvider private static readonly TraceLoggerFactory loggerFactory = new TraceLoggerFactory(); + /// + /// Gets the shared trace logger factory. + /// public static ICredentialProviderLoggerFactory Instance => loggerFactory; } } diff --git a/src/samples/Lithnet.CredentialProvider.Sample.Core.x64/TestCredentialProviderCoreX64.cs b/src/samples/Lithnet.CredentialProvider.Sample.Core.x64/TestCredentialProviderCoreX64.cs index cd155ec..4eacd22 100644 --- a/src/samples/Lithnet.CredentialProvider.Sample.Core.x64/TestCredentialProviderCoreX64.cs +++ b/src/samples/Lithnet.CredentialProvider.Sample.Core.x64/TestCredentialProviderCoreX64.cs @@ -101,6 +101,7 @@ namespace Lithnet.CredentialProvider.Samples private static Bitmap CreateTransparentUserTile() { + // CredentialTile3 preserves the alpha channel in this image. CredentialTile and CredentialTile2 render it against the control's BackgroundColor. Bitmap image = new Bitmap(128, 128, PixelFormat.Format32bppArgb); using (Graphics graphics = Graphics.FromImage(image)) diff --git a/src/samples/Lithnet.CredentialProvider.Sample.Framework.x64/TestCredentialProviderTile.cs b/src/samples/Lithnet.CredentialProvider.Sample.Framework.x64/TestCredentialProviderTile.cs index 204d0c1..20cd9ea 100644 --- a/src/samples/Lithnet.CredentialProvider.Sample.Framework.x64/TestCredentialProviderTile.cs +++ b/src/samples/Lithnet.CredentialProvider.Sample.Framework.x64/TestCredentialProviderTile.cs @@ -5,6 +5,9 @@ using Microsoft.Extensions.Logging; namespace Lithnet.CredentialProvider.Samples { + /// + /// Demonstrates a version 3 credential tile that preserves image transparency. + /// public class TestCredentialProviderTile : CredentialTile3 { private TextboxControl UsernameControl;