Renames tile control classes
Adds conditional logging for memory debugging Hides CrredentialTile3 implementation
This commit is contained in:
@@ -0,0 +1,479 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Lithnet.CredentialProvider.Interop;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Lithnet.CredentialProvider
|
||||
{
|
||||
public partial class CredentialTile : ICredentialProviderCredential
|
||||
{
|
||||
int ICredentialProviderCredential.Advise(ICredentialProviderCredentialEvents pcpce)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace("Advise");
|
||||
|
||||
if (pcpce != null)
|
||||
{
|
||||
this.Controls.AssignEvents(pcpce);
|
||||
this.events = pcpce;
|
||||
this.events2 = pcpce as ICredentialProviderCredentialEvents2;
|
||||
|
||||
var intPtr = Marshal.GetIUnknownForObject(pcpce);
|
||||
Marshal.AddRef(intPtr);
|
||||
}
|
||||
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "Advise failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.UnAdvise()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace("Unadvise");
|
||||
|
||||
if (this.events != null)
|
||||
{
|
||||
this.Controls.UnassignEvents();
|
||||
var intPtr = Marshal.GetIUnknownForObject(this.events);
|
||||
Marshal.Release(intPtr);
|
||||
this.events = null;
|
||||
}
|
||||
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "UnAdvise failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.SetSelected(out int pbAutoLogon)
|
||||
{
|
||||
pbAutoLogon = 0;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace("SetSelected");
|
||||
this.IsSelected = true;
|
||||
pbAutoLogon = this.IsAutoLogon ? 1 : 0;
|
||||
this.OnSelected();
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "SetSelected failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.SetDeselected()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace("SetDeselected");
|
||||
this.IsSelected = false;
|
||||
this.OnDeselected();
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "SetDeselected failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.GetFieldState(uint dwFieldID, out FieldState pcpfs, out FieldInteractiveState pcpfis)
|
||||
{
|
||||
pcpfis = FieldInteractiveState.None;
|
||||
pcpfs = FieldState.Hidden;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"GetFieldState: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl(dwFieldID, out var instance))
|
||||
{
|
||||
pcpfs = instance.State;
|
||||
pcpfis = instance.InteractiveState;
|
||||
|
||||
this.logger.LogTrace($"GetFieldState on [{instance}] returning state {instance.State} and interactive state {instance.InteractiveState}");
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"GetFieldState failed to find a field match for {dwFieldID}");
|
||||
|
||||
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "GetFieldState failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.GetStringValue(uint dwFieldID, out IntPtr ppsz)
|
||||
{
|
||||
ppsz = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"GetStringValue: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl(dwFieldID, out var instance))
|
||||
{
|
||||
if (instance is TextboxControl t)
|
||||
{
|
||||
ppsz = Marshal.StringToCoTaskMemUni(t.Text);
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
if (instance is SecurePasswordTextboxControl p)
|
||||
{
|
||||
if (p.Password == null || p.Password.Length == 0)
|
||||
{
|
||||
ppsz = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppsz = Marshal.SecureStringToCoTaskMemUnicode(p.Password);
|
||||
this.logger.LogWarningDebug($"0x{ppsz.ToString("X16")} - Put password for outbound GetStringValue");
|
||||
}
|
||||
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
if (instance is InsecurePasswordTextboxControl i)
|
||||
{
|
||||
if (i.Password == null || i.Password.Length == 0)
|
||||
{
|
||||
ppsz = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppsz = Marshal.StringToCoTaskMemUni(i.Password);
|
||||
this.logger.LogWarningDebug($"0x{ppsz.ToString("X16")} - Put password for outbound GetStringValue");
|
||||
}
|
||||
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
ppsz = Marshal.StringToCoTaskMemUni(instance.Label);
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"GetStringValue failed to find a field match for {dwFieldID}");
|
||||
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "GetStringValue failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.GetBitmapValue(uint dwFieldID, out IntPtr phbmp)
|
||||
{
|
||||
phbmp = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"GetBitmapValue: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl<BitmapControl>(dwFieldID, FieldType.TileImage, out var instance))
|
||||
{
|
||||
phbmp = instance.GetHBitmap();
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"GetBitmapValue was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "GetBitmapValue failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.GetCheckboxValue(uint dwFieldID, out int pbChecked, out string ppszLabel)
|
||||
{
|
||||
pbChecked = 0;
|
||||
ppszLabel = null;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"GetCheckboxValue: field {dwFieldID}");
|
||||
|
||||
|
||||
if (this.Controls.TryGetControl<CheckboxControl>(dwFieldID, FieldType.CheckBox, out var instance))
|
||||
{
|
||||
ppszLabel = instance.Label;
|
||||
pbChecked = instance.IsChecked ? 1 : 0;
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"GetCheckboxValue was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "GetCheckboxValue failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.GetSubmitButtonValue(uint dwFieldID, out uint pdwAdjacentTo)
|
||||
{
|
||||
pdwAdjacentTo = 0;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"GetSubmitButtonValue: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl<SubmitButtonControl>(dwFieldID, FieldType.Submit, out var instance))
|
||||
{
|
||||
pdwAdjacentTo = instance.AdjacentToId;
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"GetSubmitButtonValue was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "GetSubmitButtonValue failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.GetComboBoxValueCount(uint dwFieldID, out uint pcItems, out uint pdwSelectedItem)
|
||||
{
|
||||
pcItems = 0;
|
||||
pdwSelectedItem = 0;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"GetComboBoxValueCount: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl<ComboboxControl>(dwFieldID, FieldType.ComboBox, out var instance))
|
||||
{
|
||||
pcItems = (uint)instance.ComboBoxItems.Count;
|
||||
pdwSelectedItem = (uint)instance.SelectedItemIndex;
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"GetComboBoxValueCount was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "GetComboBoxValueCount failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.GetComboBoxValueAt(uint dwFieldID, uint dwItem, out string ppszItem)
|
||||
{
|
||||
ppszItem = null;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"GetComboBoxValueAt: field {dwFieldID}");
|
||||
if (this.Controls.TryGetControl<ComboboxControl>(dwFieldID, FieldType.ComboBox, out var instance))
|
||||
{
|
||||
if (dwItem < instance.ComboBoxItems.Count)
|
||||
{
|
||||
ppszItem = instance.ComboBoxItems[(int)dwItem];
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.LogError($"GetComboBoxValueAt was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "GetComboBoxValueAt failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.SetStringValue(uint dwFieldID, IntPtr psz)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.logger.LogWarningDebug($"0x{psz.ToString("X16")} - Incoming SetStringValue: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl(dwFieldID, out var instance))
|
||||
{
|
||||
if (instance.Type == FieldType.EditText && instance is TextboxControl b)
|
||||
{
|
||||
b.SetTextInternal(Marshal.PtrToStringUni(psz));
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
if (instance.Type == FieldType.PasswordText && instance is SecurePasswordTextboxControl p)
|
||||
{
|
||||
this.logger.LogWarningDebug($"0x{psz.ToString("X16")} - Incoming password in SetStringValue");
|
||||
p.SetPasswordInternal(psz.IntPtrToSecureString());
|
||||
PInvoke.SecureZeroMemory(psz, (uint)(psz.Wcslen() * 2));
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
if (instance.Type == FieldType.PasswordText && instance is InsecurePasswordTextboxControl i)
|
||||
{
|
||||
this.logger.LogWarningDebug($"0x{psz.ToString("X16")} - Incoming password in SetStringValue");
|
||||
i.SetPasswordInternal(Marshal.PtrToStringUni(psz));
|
||||
PInvoke.SecureZeroMemory(psz, (uint)(psz.Wcslen() * 2));
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.LogError($"SetStringValue was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "SetStringValue failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.SetCheckboxValue(uint dwFieldID, int bChecked)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"SetCheckboxValue: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl<CheckboxControl>(dwFieldID, FieldType.CheckBox, out var instance))
|
||||
{
|
||||
instance.SetIsCheckedInternal(bChecked != 0);
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"SetCheckboxValue was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "SetCheckboxValue failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.SetComboBoxSelectedValue(uint dwFieldID, uint dwSelectedItem)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"SetComboBoxSelectedValue: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl<ComboboxControl>(dwFieldID, FieldType.ComboBox, out var instance))
|
||||
{
|
||||
instance.SetComboboxSelectedItemIndexInternal((unchecked((int)dwSelectedItem)));
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"SetComboBoxSelectedValue was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "SetComboBoxSelectedValue failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.CommandLinkClicked(uint dwFieldID)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"CommandLinkClicked: field {dwFieldID}");
|
||||
|
||||
if (this.Controls.TryGetControl<CommandLinkControl>(dwFieldID, FieldType.CommandLink, out var instance))
|
||||
{
|
||||
instance.OnClick?.Invoke();
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
|
||||
this.logger.LogError($"CommandLinkClicked was incorrectly called on field {instance}");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "CommandLinkClicked failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.GetSerialization(out SerializationResponse pcpgsr, out CredentialSerialization pcpcs, out string ppszOptionalStatusText, out StatusIcon pcpsiOptionalStatusIcon)
|
||||
{
|
||||
pcpgsr = SerializationResponse.NoCredentialNotFinished;
|
||||
pcpcs = default;
|
||||
ppszOptionalStatusText = null;
|
||||
pcpsiOptionalStatusIcon = StatusIcon.None;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"GetSerialization called");
|
||||
NativeSerializationResponse response = this.OnGetSerialization();
|
||||
|
||||
pcpgsr = response.SerializationResponse;
|
||||
pcpcs = response.SerializedCredentials;
|
||||
ppszOptionalStatusText = response.OptionalStatusText;
|
||||
pcpsiOptionalStatusIcon = response.OptionalStatusIcon;
|
||||
|
||||
|
||||
this.logger.LogTrace($"GetSerialization is returning {pcpgsr}, with auth provider {pcpcs.AuthenticationPackage}, status {pcpsiOptionalStatusIcon}: {ppszOptionalStatusText}");
|
||||
|
||||
return response.HResult;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ppszOptionalStatusText = "Unexpected error";
|
||||
pcpsiOptionalStatusIcon = StatusIcon.Error;
|
||||
this.logger.LogError(ex, "GetSerialization failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
int ICredentialProviderCredential.ReportResult(int ntsStatus, int ntsSubstatus, out string ppszOptionalStatusText, out StatusIcon pcpsiOptionalStatusIcon)
|
||||
{
|
||||
ppszOptionalStatusText = null;
|
||||
pcpsiOptionalStatusIcon = StatusIcon.None;
|
||||
|
||||
try
|
||||
{
|
||||
this.logger.LogTrace($"ReportResult");
|
||||
|
||||
this.OnLogonStatusReported(ntsStatus, ntsSubstatus, out ppszOptionalStatusText, out pcpsiOptionalStatusIcon);
|
||||
|
||||
if (ppszOptionalStatusText == null && pcpsiOptionalStatusIcon == StatusIcon.None)
|
||||
{
|
||||
pcpsiOptionalStatusIcon = 0;
|
||||
return HRESULT.E_NOTIMPL;
|
||||
}
|
||||
|
||||
return HRESULT.S_OK;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.LogError(ex, "ReportResult failed");
|
||||
return HRESULT.E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user