Expand framework support and COM ABI coverage
Target .NET 8, 9, 10, Framework 4.7.2, and Framework 4.8. Rename samples to stable Core and Framework names. Add raw-vtable COM tests for x64, x86, and ARM64, and require the Azure architecture matrix before packaging.
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0-windows;net9.0-windows;net10.0-windows;net472;net48</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<DefineConstants>$(DefineConstants);TEST_ARM64</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lithnet.CredentialProvider\Lithnet.CredentialProvider.csproj" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.UnitTests.x64\BitmapControlTests.cs" Link="BitmapControlTests.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.UnitTests.x64\ComInterop\**\*.cs" Link="ComInterop\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[Guid("2A83F3F8-A46C-4104-8FFB-BD9979279450")]
|
||||
internal sealed class AbiTestCredentialProvider : CredentialProviderBase
|
||||
{
|
||||
public AbiTestCredentialProvider()
|
||||
{
|
||||
this.Field = new SmallLabelControl("message", "COM ABI test");
|
||||
}
|
||||
|
||||
public SmallLabelControl Field { get; }
|
||||
|
||||
public AbiTestCredentialTile2 Tile { get; private set; }
|
||||
|
||||
public override bool IsUsageScenarioSupported(UsageScenario cpus, CredUIWinFlags dwFlags)
|
||||
{
|
||||
return cpus == UsageScenario.CredUI;
|
||||
}
|
||||
|
||||
public override IEnumerable<ControlBase> GetControls(UsageScenario cpus)
|
||||
{
|
||||
return new ControlBase[] { this.Field };
|
||||
}
|
||||
|
||||
public override bool ShouldIncludeUserTile(CredentialProviderUser user)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool ShouldIncludeGenericTile()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override CredentialTile CreateGenericTile()
|
||||
{
|
||||
this.Tile = new AbiTestCredentialTile2(this);
|
||||
return this.Tile;
|
||||
}
|
||||
|
||||
public override CredentialTile2 CreateUserTile(CredentialProviderUser user)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
internal sealed class AbiTestCredentialTile2 : CredentialTile2
|
||||
{
|
||||
public AbiTestCredentialTile2(CredentialProviderBase credentialProvider) : base(credentialProvider)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CredentialResponseBase GetCredentials()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
internal sealed class ComInterfacePointer : IDisposable
|
||||
{
|
||||
private IntPtr value;
|
||||
|
||||
private ComInterfacePointer(IntPtr value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public IntPtr Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.value == IntPtr.Zero)
|
||||
{
|
||||
throw new ObjectDisposedException(nameof(ComInterfacePointer));
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
public static ComInterfacePointer Create(object instance, Guid interfaceId)
|
||||
{
|
||||
IntPtr unknown = Marshal.GetIUnknownForObject(instance);
|
||||
|
||||
try
|
||||
{
|
||||
int hresult = ComMarshal.QueryInterface(unknown, interfaceId, out IntPtr interfacePointer);
|
||||
if (hresult != CredentialProviderAbi.S_OK)
|
||||
{
|
||||
if (interfacePointer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.Release(interfacePointer);
|
||||
}
|
||||
|
||||
throw new COMException("The COM interface was not available", hresult);
|
||||
}
|
||||
|
||||
return new ComInterfacePointer(interfacePointer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.Release(unknown);
|
||||
}
|
||||
}
|
||||
|
||||
public static ComInterfacePointer TakeOwnership(IntPtr value)
|
||||
{
|
||||
if (value == IntPtr.Zero)
|
||||
{
|
||||
throw new ArgumentException("The COM interface pointer cannot be zero", nameof(value));
|
||||
}
|
||||
|
||||
return new ComInterfacePointer(value);
|
||||
}
|
||||
|
||||
public TDelegate GetMethod<TDelegate>(int slot) where TDelegate : class
|
||||
{
|
||||
IntPtr vtable = Marshal.ReadIntPtr(this.Value);
|
||||
IntPtr method = Marshal.ReadIntPtr(vtable, checked(slot * IntPtr.Size));
|
||||
return (TDelegate)(object)Marshal.GetDelegateForFunctionPointer(method, typeof(TDelegate));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.value != IntPtr.Zero)
|
||||
{
|
||||
Marshal.Release(this.value);
|
||||
this.value = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
internal static class ComMarshal
|
||||
{
|
||||
public static int QueryInterface(IntPtr unknown, Guid interfaceId, out IntPtr interfacePointer)
|
||||
{
|
||||
#if NET9_0_OR_GREATER
|
||||
return Marshal.QueryInterface(unknown, in interfaceId, out interfacePointer);
|
||||
#else
|
||||
return Marshal.QueryInterface(unknown, ref interfaceId, out interfacePointer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
internal static class CredentialProviderAbi
|
||||
{
|
||||
public static readonly Guid ICredentialProvider = new Guid("D27C3481-5A1C-45B2-8AAA-C20EBBE8229E");
|
||||
|
||||
public static readonly Guid ICredentialProviderCredential = new Guid("63913A93-40C1-481A-818D-4072FF8C70CC");
|
||||
|
||||
public static readonly Guid ICredentialProviderCredential2 = new Guid("FD672C54-40EA-4D6E-9B49-CFB1A7507BD7");
|
||||
|
||||
public static readonly Guid ICredentialProviderSetUserArray = new Guid("095C1484-1C0C-4388-9C6D-500E61BF84BD");
|
||||
|
||||
public static readonly Guid ICredentialProviderUserArray = new Guid("90C119AE-0F18-4520-A1F1-114366A40FE8");
|
||||
|
||||
public const int SetUsageScenarioSlot = 3;
|
||||
|
||||
public const int GetFieldDescriptorCountSlot = 7;
|
||||
|
||||
public const int GetFieldDescriptorAtSlot = 8;
|
||||
|
||||
public const int GetCredentialCountSlot = 9;
|
||||
|
||||
public const int GetCredentialAtSlot = 10;
|
||||
|
||||
public const int SetUserArraySlot = 3;
|
||||
|
||||
public const int UserArrayGetCountSlot = 5;
|
||||
|
||||
public const int SetSelectedSlot = 5;
|
||||
|
||||
public const int SetDeselectedSlot = 6;
|
||||
|
||||
public const int GetFieldStateSlot = 7;
|
||||
|
||||
public const int GetStringValueSlot = 8;
|
||||
|
||||
public const int GetUserSidSlot = 20;
|
||||
|
||||
public const int SmallTextFieldType = 2;
|
||||
|
||||
public const int DisplayInSelectedTileFieldState = 1;
|
||||
|
||||
public const int NoInteractiveFieldState = 0;
|
||||
|
||||
public const uint NoDefaultCredential = 0xFFFFFFFF;
|
||||
|
||||
public const int S_OK = 0;
|
||||
|
||||
public const int S_FALSE = 1;
|
||||
|
||||
public const int E_FAIL = unchecked((int)0x80004005);
|
||||
|
||||
public const int E_INVALIDARG = unchecked((int)0x80070057);
|
||||
|
||||
public const int E_NOTIMPL = unchecked((int)0x80004001);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,450 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[TestFixture]
|
||||
[NonParallelizable]
|
||||
[Apartment(ApartmentState.STA)]
|
||||
public class CredentialProviderAbiTests
|
||||
{
|
||||
[Test]
|
||||
public void CredentialProviderInterfaceCanBeQueried()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
IntPtr unknown = Marshal.GetIUnknownForObject(provider);
|
||||
IntPtr providerInterface = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
int hresult = ComMarshal.QueryInterface(unknown, CredentialProviderAbi.ICredentialProvider, out providerInterface);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(providerInterface, Is.Not.EqualTo(IntPtr.Zero));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (providerInterface != IntPtr.Zero)
|
||||
{
|
||||
Marshal.Release(providerInterface);
|
||||
}
|
||||
|
||||
Marshal.Release(unknown);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetUsageScenarioPreservesHResultAndArguments()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
|
||||
using (ComInterfacePointer providerInterface = ComInterfacePointer.Create(provider, CredentialProviderAbi.ICredentialProvider))
|
||||
{
|
||||
SetUsageScenarioDelegate setUsageScenario = providerInterface.GetMethod<SetUsageScenarioDelegate>(CredentialProviderAbi.SetUsageScenarioSlot);
|
||||
|
||||
int hresult = setUsageScenario(providerInterface.Value, (int)UsageScenario.CredUI, (uint)CredUIWinFlags.CREDUIWIN_SECURE_PROMPT);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(provider.UsageScenario, Is.EqualTo(UsageScenario.CredUI));
|
||||
Assert.That(provider.CredUIFlags, Is.EqualTo(CredUIWinFlags.CREDUIWIN_SECURE_PROMPT));
|
||||
|
||||
hresult = setUsageScenario(providerInterface.Value, (int)UsageScenario.Logon, 0);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.E_NOTIMPL));
|
||||
Assert.That(provider.UsageScenario, Is.EqualTo(UsageScenario.Logon));
|
||||
Assert.That(provider.CredUIFlags, Is.EqualTo((CredUIWinFlags)0));
|
||||
}
|
||||
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetFieldDescriptorCountReturnsProviderControlCount()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
|
||||
using (ComInterfacePointer providerInterface = ComInterfacePointer.Create(provider, CredentialProviderAbi.ICredentialProvider))
|
||||
{
|
||||
GetFieldDescriptorCountDelegate getFieldDescriptorCount = providerInterface.GetMethod<GetFieldDescriptorCountDelegate>(CredentialProviderAbi.GetFieldDescriptorCountSlot);
|
||||
|
||||
int hresult = getFieldDescriptorCount(providerInterface.Value, out uint count);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetFieldDescriptorAtReturnsWindowsSdkLayout()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
|
||||
using (ComInterfacePointer providerInterface = ComInterfacePointer.Create(provider, CredentialProviderAbi.ICredentialProvider))
|
||||
{
|
||||
GetFieldDescriptorCountDelegate getFieldDescriptorCount = providerInterface.GetMethod<GetFieldDescriptorCountDelegate>(CredentialProviderAbi.GetFieldDescriptorCountSlot);
|
||||
GetFieldDescriptorAtDelegate getFieldDescriptorAt = providerInterface.GetMethod<GetFieldDescriptorAtDelegate>(CredentialProviderAbi.GetFieldDescriptorAtSlot);
|
||||
|
||||
Assert.That(getFieldDescriptorCount(providerInterface.Value, out uint count), Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
|
||||
IntPtr descriptorPointer = IntPtr.Zero;
|
||||
IntPtr labelPointer = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
int hresult = getFieldDescriptorAt(providerInterface.Value, 0, out descriptorPointer);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(descriptorPointer, Is.Not.EqualTo(IntPtr.Zero));
|
||||
|
||||
NativeCredentialProviderFieldDescriptor descriptor = Marshal.PtrToStructure<NativeCredentialProviderFieldDescriptor>(descriptorPointer);
|
||||
labelPointer = descriptor.Label;
|
||||
|
||||
Assert.That(descriptor.FieldId, Is.EqualTo(provider.Field.Id));
|
||||
Assert.That(descriptor.FieldType, Is.EqualTo(CredentialProviderAbi.SmallTextFieldType));
|
||||
Assert.That(Marshal.PtrToStringUni(labelPointer), Is.EqualTo("COM ABI test"));
|
||||
Assert.That(descriptor.FieldTypeGuid, Is.EqualTo(Guid.Empty));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (labelPointer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(labelPointer);
|
||||
}
|
||||
|
||||
if (descriptorPointer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(descriptorPointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetFieldDescriptorAtRejectsInvalidIndex()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
|
||||
using (ComInterfacePointer providerInterface = ComInterfacePointer.Create(provider, CredentialProviderAbi.ICredentialProvider))
|
||||
{
|
||||
GetFieldDescriptorCountDelegate getFieldDescriptorCount = providerInterface.GetMethod<GetFieldDescriptorCountDelegate>(CredentialProviderAbi.GetFieldDescriptorCountSlot);
|
||||
GetFieldDescriptorAtDelegate getFieldDescriptorAt = providerInterface.GetMethod<GetFieldDescriptorAtDelegate>(CredentialProviderAbi.GetFieldDescriptorAtSlot);
|
||||
|
||||
Assert.That(getFieldDescriptorCount(providerInterface.Value, out uint count), Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
|
||||
int hresult = getFieldDescriptorAt(providerInterface.Value, count, out IntPtr descriptorPointer);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.E_INVALIDARG));
|
||||
Assert.That(descriptorPointer, Is.EqualTo(IntPtr.Zero));
|
||||
}
|
||||
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CredentialProviderSetUserArrayInterfaceCanBeQueried()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
IntPtr unknown = Marshal.GetIUnknownForObject(provider);
|
||||
IntPtr setUserArrayInterface = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
int hresult = ComMarshal.QueryInterface(unknown, CredentialProviderAbi.ICredentialProviderSetUserArray, out setUserArrayInterface);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(setUserArrayInterface, Is.Not.EqualTo(IntPtr.Zero));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (setUserArrayInterface != IntPtr.Zero)
|
||||
{
|
||||
Marshal.Release(setUserArrayInterface);
|
||||
}
|
||||
|
||||
Marshal.Release(unknown);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUserArrayUsesWindowsSdkGetCountSlot()
|
||||
{
|
||||
var users = new TestCredentialProviderUserArray();
|
||||
|
||||
using (ComInterfacePointer userArrayInterface = ComInterfacePointer.Create(users, CredentialProviderAbi.ICredentialProviderUserArray))
|
||||
{
|
||||
GetUserCountDelegate getCount = userArrayInterface.GetMethod<GetUserCountDelegate>(CredentialProviderAbi.UserArrayGetCountSlot);
|
||||
|
||||
int hresult = getCount(userArrayInterface.Value, out uint count);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(count, Is.EqualTo(0));
|
||||
Assert.That(users.GetCountCallCount, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
GC.KeepAlive(users);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetUserArrayInvokesWindowsSdkUserArrayGetCount()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
var users = new TestCredentialProviderUserArray();
|
||||
|
||||
SetEmptyUserArray(provider, users);
|
||||
|
||||
Assert.That(users.GetCountCallCount, Is.EqualTo(1));
|
||||
|
||||
GC.KeepAlive(users);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCredentialCountReturnsGenericTileWithoutDefault()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
var users = new TestCredentialProviderUserArray();
|
||||
|
||||
SetEmptyUserArray(provider, users);
|
||||
|
||||
using (ComInterfacePointer providerInterface = ComInterfacePointer.Create(provider, CredentialProviderAbi.ICredentialProvider))
|
||||
{
|
||||
GetCredentialCountDelegate getCredentialCount = providerInterface.GetMethod<GetCredentialCountDelegate>(CredentialProviderAbi.GetCredentialCountSlot);
|
||||
|
||||
int hresult = getCredentialCount(providerInterface.Value, out uint count, out uint defaultCredential, out int autoLogonWithDefault);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
Assert.That(defaultCredential, Is.EqualTo(CredentialProviderAbi.NoDefaultCredential));
|
||||
Assert.That(autoLogonWithDefault, Is.EqualTo(0));
|
||||
Assert.That(users.GetCountCallCount, Is.EqualTo(2));
|
||||
Assert.That(provider.Tile, Is.Not.Null);
|
||||
}
|
||||
|
||||
GC.KeepAlive(users);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCredentialAtRejectsInvalidIndex()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
var users = new TestCredentialProviderUserArray();
|
||||
|
||||
SetEmptyUserArray(provider, users);
|
||||
|
||||
using (ComInterfacePointer providerInterface = ComInterfacePointer.Create(provider, CredentialProviderAbi.ICredentialProvider))
|
||||
{
|
||||
GetCredentialCountDelegate getCredentialCount = providerInterface.GetMethod<GetCredentialCountDelegate>(CredentialProviderAbi.GetCredentialCountSlot);
|
||||
GetCredentialAtDelegate getCredentialAt = providerInterface.GetMethod<GetCredentialAtDelegate>(CredentialProviderAbi.GetCredentialAtSlot);
|
||||
|
||||
Assert.That(getCredentialCount(providerInterface.Value, out uint count, out uint defaultCredential, out int autoLogonWithDefault), Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
|
||||
int hresult = getCredentialAt(providerInterface.Value, count, out IntPtr credential);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.E_FAIL));
|
||||
Assert.That(credential, Is.EqualTo(IntPtr.Zero));
|
||||
}
|
||||
|
||||
GC.KeepAlive(users);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CredentialV1SelectionMethodsPreserveStateAndHResults()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
var users = new TestCredentialProviderUserArray();
|
||||
|
||||
using (ComInterfacePointer credential = CreateCredentialInterface(provider, users))
|
||||
{
|
||||
SetSelectedDelegate setSelected = credential.GetMethod<SetSelectedDelegate>(CredentialProviderAbi.SetSelectedSlot);
|
||||
SetDeselectedDelegate setDeselected = credential.GetMethod<SetDeselectedDelegate>(CredentialProviderAbi.SetDeselectedSlot);
|
||||
|
||||
int hresult = setSelected(credential.Value, out int autoLogon);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(autoLogon, Is.EqualTo(0));
|
||||
Assert.That(provider.Tile.IsSelected, Is.True);
|
||||
|
||||
hresult = setDeselected(credential.Value);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(provider.Tile.IsSelected, Is.False);
|
||||
}
|
||||
|
||||
GC.KeepAlive(users);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CredentialV1GetFieldStateUsesWindowsSdkEnumValues()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
var users = new TestCredentialProviderUserArray();
|
||||
|
||||
using (ComInterfacePointer credential = CreateCredentialInterface(provider, users))
|
||||
{
|
||||
GetFieldStateDelegate getFieldState = credential.GetMethod<GetFieldStateDelegate>(CredentialProviderAbi.GetFieldStateSlot);
|
||||
|
||||
int hresult = getFieldState(credential.Value, provider.Field.Id, out int fieldState, out int interactiveState);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(fieldState, Is.EqualTo(CredentialProviderAbi.DisplayInSelectedTileFieldState));
|
||||
Assert.That(interactiveState, Is.EqualTo(CredentialProviderAbi.NoInteractiveFieldState));
|
||||
}
|
||||
|
||||
GC.KeepAlive(users);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CredentialV1GetStringValueReturnsComTaskMemory()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
var users = new TestCredentialProviderUserArray();
|
||||
|
||||
using (ComInterfacePointer credential = CreateCredentialInterface(provider, users))
|
||||
{
|
||||
GetStringValueDelegate getStringValue = credential.GetMethod<GetStringValueDelegate>(CredentialProviderAbi.GetStringValueSlot);
|
||||
IntPtr value = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
int hresult = getStringValue(credential.Value, provider.Field.Id, out value);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(value, Is.Not.EqualTo(IntPtr.Zero));
|
||||
Assert.That(Marshal.PtrToStringUni(value), Is.EqualTo("COM ABI test"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (value != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GC.KeepAlive(users);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CredentialV2GetUserSidUsesInheritedVtableOrder()
|
||||
{
|
||||
var provider = new AbiTestCredentialProvider();
|
||||
var users = new TestCredentialProviderUserArray();
|
||||
|
||||
using (ComInterfacePointer credential = CreateCredentialInterface(provider, users))
|
||||
{
|
||||
IntPtr credential2Pointer = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
int hresult = ComMarshal.QueryInterface(credential.Value, CredentialProviderAbi.ICredentialProviderCredential2, out credential2Pointer);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(credential2Pointer, Is.Not.EqualTo(IntPtr.Zero));
|
||||
|
||||
using (ComInterfacePointer credential2 = ComInterfacePointer.TakeOwnership(credential2Pointer))
|
||||
{
|
||||
credential2Pointer = IntPtr.Zero;
|
||||
GetUserSidDelegate getUserSid = credential2.GetMethod<GetUserSidDelegate>(CredentialProviderAbi.GetUserSidSlot);
|
||||
IntPtr sid = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
hresult = getUserSid(credential2.Value, out sid);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_FALSE));
|
||||
Assert.That(sid, Is.EqualTo(IntPtr.Zero));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (sid != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(sid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (credential2Pointer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.Release(credential2Pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GC.KeepAlive(users);
|
||||
GC.KeepAlive(provider);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FieldDescriptorDeclarationMatchesWindowsSdkSize()
|
||||
{
|
||||
int expectedSize = IntPtr.Size == 4 ? 28 : 32;
|
||||
|
||||
Assert.That(Marshal.SizeOf<NativeCredentialProviderFieldDescriptor>(), Is.EqualTo(expectedSize));
|
||||
}
|
||||
|
||||
private static void SetEmptyUserArray(AbiTestCredentialProvider provider, TestCredentialProviderUserArray users)
|
||||
{
|
||||
using (ComInterfacePointer setUserArrayInterface = ComInterfacePointer.Create(provider, CredentialProviderAbi.ICredentialProviderSetUserArray))
|
||||
using (ComInterfacePointer userArrayInterface = ComInterfacePointer.Create(users, CredentialProviderAbi.ICredentialProviderUserArray))
|
||||
{
|
||||
SetUserArrayDelegate setUserArray = setUserArrayInterface.GetMethod<SetUserArrayDelegate>(CredentialProviderAbi.SetUserArraySlot);
|
||||
|
||||
int hresult = setUserArray(setUserArrayInterface.Value, userArrayInterface.Value);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
}
|
||||
}
|
||||
|
||||
private static ComInterfacePointer CreateCredentialInterface(AbiTestCredentialProvider provider, TestCredentialProviderUserArray users)
|
||||
{
|
||||
SetEmptyUserArray(provider, users);
|
||||
|
||||
using (ComInterfacePointer providerInterface = ComInterfacePointer.Create(provider, CredentialProviderAbi.ICredentialProvider))
|
||||
{
|
||||
GetCredentialCountDelegate getCredentialCount = providerInterface.GetMethod<GetCredentialCountDelegate>(CredentialProviderAbi.GetCredentialCountSlot);
|
||||
GetCredentialAtDelegate getCredentialAt = providerInterface.GetMethod<GetCredentialAtDelegate>(CredentialProviderAbi.GetCredentialAtSlot);
|
||||
|
||||
Assert.That(getCredentialCount(providerInterface.Value, out uint count, out uint defaultCredential, out int autoLogonWithDefault), Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(count, Is.EqualTo(1));
|
||||
|
||||
IntPtr credential = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
int hresult = getCredentialAt(providerInterface.Value, 0, out credential);
|
||||
|
||||
Assert.That(hresult, Is.EqualTo(CredentialProviderAbi.S_OK));
|
||||
Assert.That(credential, Is.Not.EqualTo(IntPtr.Zero));
|
||||
|
||||
ComInterfacePointer result = ComInterfacePointer.TakeOwnership(credential);
|
||||
credential = IntPtr.Zero;
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (credential != IntPtr.Zero)
|
||||
{
|
||||
Marshal.Release(credential);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int GetCredentialAtDelegate(IntPtr instance, uint index, out IntPtr credential);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int GetCredentialCountDelegate(IntPtr instance, out uint count, out uint defaultCredential, out int autoLogonWithDefault);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int GetFieldDescriptorAtDelegate(IntPtr instance, uint index, out IntPtr descriptor);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int GetFieldDescriptorCountDelegate(IntPtr instance, out uint count);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int GetFieldStateDelegate(IntPtr instance, uint fieldId, out int fieldState, out int interactiveState);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int GetStringValueDelegate(IntPtr instance, uint fieldId, out IntPtr value);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int GetUserCountDelegate(IntPtr instance, out uint count);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int GetUserSidDelegate(IntPtr instance, out IntPtr sid);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[Guid("90C119AE-0F18-4520-A1F1-114366A40FE8")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ITestCredentialProviderUserArray
|
||||
{
|
||||
[PreserveSig]
|
||||
[return: MarshalAs(UnmanagedType.Error)]
|
||||
int SetProviderFilter(ref Guid providerToFilterTo);
|
||||
|
||||
[PreserveSig]
|
||||
[return: MarshalAs(UnmanagedType.Error)]
|
||||
int GetAccountOptions(out int accountOptions);
|
||||
|
||||
[PreserveSig]
|
||||
[return: MarshalAs(UnmanagedType.Error)]
|
||||
int GetCount(out uint userCount);
|
||||
|
||||
[PreserveSig]
|
||||
[return: MarshalAs(UnmanagedType.Error)]
|
||||
int GetAt(uint userIndex, out IntPtr user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NativeCredentialProviderFieldDescriptor
|
||||
{
|
||||
public uint FieldId;
|
||||
|
||||
public int FieldType;
|
||||
|
||||
public IntPtr Label;
|
||||
|
||||
public Guid FieldTypeGuid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[TestFixture]
|
||||
public class ProcessArchitectureTests
|
||||
{
|
||||
[Test]
|
||||
public void TestHostUsesRequestedArchitecture()
|
||||
{
|
||||
#if TEST_X86
|
||||
const string expectedArchitecture = "x86";
|
||||
#elif TEST_X64
|
||||
const string expectedArchitecture = "AMD64";
|
||||
#elif TEST_ARM64
|
||||
const string expectedArchitecture = "ARM64";
|
||||
#else
|
||||
#error A test process architecture must be defined by the project.
|
||||
#endif
|
||||
|
||||
string actualArchitecture = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
|
||||
|
||||
Assert.That(actualArchitecture, Is.EqualTo(expectedArchitecture).IgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int SetDeselectedDelegate(IntPtr instance);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int SetSelectedDelegate(IntPtr instance, out int autoLogon);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int SetUsageScenarioDelegate(IntPtr instance, int usageScenario, uint flags);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||
internal delegate int SetUserArrayDelegate(IntPtr instance, IntPtr users);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Lithnet.CredentialProvider.Interop;
|
||||
|
||||
namespace Lithnet.CredentialProvider.UnitTests.ComInterop
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
// The in-process call also requires the callback to implement the parameter's managed interface type.
|
||||
// ITestCredentialProviderUserArray keeps the COM contract under test independent of that adapter.
|
||||
internal sealed class TestCredentialProviderUserArray : ITestCredentialProviderUserArray, ICredentialProviderUserArray
|
||||
{
|
||||
public int GetCountCallCount { get; private set; }
|
||||
|
||||
public int SetProviderFilter(ref Guid providerToFilterTo)
|
||||
{
|
||||
return CredentialProviderAbi.E_NOTIMPL;
|
||||
}
|
||||
|
||||
public int GetAccountOptions(out int accountOptions)
|
||||
{
|
||||
accountOptions = 0;
|
||||
return CredentialProviderAbi.S_OK;
|
||||
}
|
||||
|
||||
public int GetCount(out uint userCount)
|
||||
{
|
||||
this.GetCountCallCount++;
|
||||
userCount = 0;
|
||||
return CredentialProviderAbi.S_OK;
|
||||
}
|
||||
|
||||
public int GetAt(uint userIndex, out IntPtr user)
|
||||
{
|
||||
user = IntPtr.Zero;
|
||||
return CredentialProviderAbi.E_INVALIDARG;
|
||||
}
|
||||
|
||||
int ICredentialProviderUserArray.GetAccountOptions(out AccountOptions accountOptions)
|
||||
{
|
||||
accountOptions = AccountOptions.None;
|
||||
return CredentialProviderAbi.S_OK;
|
||||
}
|
||||
|
||||
int ICredentialProviderUserArray.GetAt(uint userIndex, out ICredentialProviderUser user)
|
||||
{
|
||||
user = null;
|
||||
return CredentialProviderAbi.E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0-windows;net7.0-windows;net8.0-windows;net461;net48</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0-windows;net9.0-windows;net10.0-windows;net472;net48</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<PlatformTargets>x64</PlatformTargets>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DefineConstants>$(DefineConstants);TEST_X64</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0-windows;net7.0-windows;net8.0-windows;net461;net48</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0-windows;net9.0-windows;net10.0-windows;net472;net48</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DefineConstants>$(DefineConstants);TEST_X86</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lithnet.CredentialProvider\Lithnet.CredentialProvider.csproj" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.UnitTests.x64\BitmapControlTests.cs" Link="BitmapControlTests.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.UnitTests.x64\ComInterop\**\*.cs" Link="ComInterop\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -11,13 +11,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
..\azure-pipelines.yml = ..\azure-pipelines.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.net6.0.x64", "samples\Lithnet.CredentialProvider.Sample.net6.0.x64\Lithnet.CredentialProvider.Sample.net6.0.x64.csproj", "{163E16D0-9FF3-40D3-AE96-3F221C922AA3}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.Core.x64", "samples\Lithnet.CredentialProvider.Sample.Core.x64\Lithnet.CredentialProvider.Sample.Core.x64.csproj", "{163E16D0-9FF3-40D3-AE96-3F221C922AA3}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.net6.0.x86", "samples\Lithnet.CredentialProvider.Sample.net6.0.x86\Lithnet.CredentialProvider.Sample.net6.0.x86.csproj", "{7A8A10F9-7D79-4755-BBDD-77C80FDC58ED}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.Core.x86", "samples\Lithnet.CredentialProvider.Sample.Core.x86\Lithnet.CredentialProvider.Sample.Core.x86.csproj", "{7A8A10F9-7D79-4755-BBDD-77C80FDC58ED}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.net472.x64", "samples\Lithnet.CredentialProvider.Sample.net472.x64\Lithnet.CredentialProvider.Sample.net472.x64.csproj", "{F60AC10A-337C-46D9-A2DE-1ED48B4AB301}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.Framework.x64", "samples\Lithnet.CredentialProvider.Sample.Framework.x64\Lithnet.CredentialProvider.Sample.Framework.x64.csproj", "{F60AC10A-337C-46D9-A2DE-1ED48B4AB301}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.net472.x86", "samples\Lithnet.CredentialProvider.Sample.net472.x86\Lithnet.CredentialProvider.Sample.net472.x86.csproj", "{57F2780E-58F1-4A7B-BCB4-A218733273EA}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.Sample.Framework.x86", "samples\Lithnet.CredentialProvider.Sample.Framework.x86\Lithnet.CredentialProvider.Sample.Framework.x86.csproj", "{57F2780E-58F1-4A7B-BCB4-A218733273EA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lithnet.CredentialProvider.TestApp.x64", "samples\Lithnet.CredentialProvider.TestApp.x64\Lithnet.CredentialProvider.TestApp.x64.csproj", "{5019CCEB-AD78-4688-8C11-89A85C4289CD}"
|
||||
EndProject
|
||||
@@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lithnet.CredentialProvider.
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lithnet.CredentialProvider.UnitTests.x86", "Lithnet.CredentialProvider.UnitTests.x86\Lithnet.CredentialProvider.UnitTests.x86.csproj", "{DA23151B-B7B6-4942-B7A4-48E1918EF145}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lithnet.CredentialProvider.UnitTests.arm64", "Lithnet.CredentialProvider.UnitTests.arm64\Lithnet.CredentialProvider.UnitTests.arm64.csproj", "{07D19CE5-8419-4E06-B39D-CC90EAA3FF9A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -69,6 +71,10 @@ Global
|
||||
{DA23151B-B7B6-4942-B7A4-48E1918EF145}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DA23151B-B7B6-4942-B7A4-48E1918EF145}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DA23151B-B7B6-4942-B7A4-48E1918EF145}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{07D19CE5-8419-4E06-B39D-CC90EAA3FF9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{07D19CE5-8419-4E06-B39D-CC90EAA3FF9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{07D19CE5-8419-4E06-B39D-CC90EAA3FF9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07D19CE5-8419-4E06-B39D-CC90EAA3FF9A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0-windows;net7.0-windows;net8.0-windows;net461</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0-windows;net9.0-windows;net10.0-windows;net472;net48</TargetFrameworks>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<OutputType>Library</OutputType>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
@@ -45,6 +45,9 @@
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>Lithnet.CredentialProvider.UnitTests.x86</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>Lithnet.CredentialProvider.UnitTests.arm64</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -7,10 +7,10 @@ In order to install and run the sample app, you have to register the COM compone
|
||||
Build the EXE, and from an elevated command prompt, change to the bin folder, and run the following commands
|
||||
|
||||
```
|
||||
regsvr32 "Lithnet.CredentialProvider.Sample.net6.0.x64.comhost.dll"
|
||||
regsvr32 "Lithnet.CredentialProvider.Sample.Core.x64.comhost.dll"
|
||||
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /f
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.net6.0.x64"
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.Core.x64"
|
||||
```
|
||||
|
||||
## Disable the sample
|
||||
@@ -31,6 +31,6 @@ REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credentia
|
||||
To remove the credential provider, run the following command.
|
||||
|
||||
```
|
||||
regsvr32 /u "Lithnet.CredentialProvider.Sample.net6.0.x64.comhost.dll"
|
||||
regsvr32 /u "Lithnet.CredentialProvider.Sample.Core.x64.comhost.dll"
|
||||
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /f
|
||||
```
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<Platform>x64</Platform>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\TileIcon.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\InternalLogger.cs" Link="InternalLogger.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\ControlKeys.cs" Link="ControlKeys.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\TileIcon.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Lithnet.CredentialProvider\Lithnet.CredentialProvider.csproj" />
|
||||
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -9,11 +11,11 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ProgId("Lithnet.CredentialProvider.Sample.net6.0.x64")]
|
||||
[ProgId("Lithnet.CredentialProvider.Sample.Core.x64")]
|
||||
[Guid("4cd12d80-9259-4f38-94dc-1828080ad9ff")]
|
||||
public class TestCredentialProviderNet60x64 : CredentialProviderBase
|
||||
public class TestCredentialProviderCoreX64 : CredentialProviderBase
|
||||
{
|
||||
private static readonly ICredentialProviderLogger logger = InternalLoggerFactory.Instance.CreateLogger<TestCredentialProviderNet60x64>();
|
||||
private static readonly ICredentialProviderLogger logger = InternalLoggerFactory.Instance.CreateLogger<TestCredentialProviderCoreX64>();
|
||||
|
||||
protected override ICredentialProviderLoggerFactory GetLoggerFactory()
|
||||
{
|
||||
@@ -36,10 +38,11 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
{
|
||||
yield return new CredentialProviderLabelControl(ControlKeys.LabelCredentialProvider, "Login with showcase credential provider");
|
||||
|
||||
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.net6.0.x64.Resources.TileIcon.png"));
|
||||
var providerLogo = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.Core.x64.Resources.TileIcon.png"));
|
||||
var transparentUserTile = CreateTransparentUserTile();
|
||||
|
||||
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", image);
|
||||
yield return new CredentialProviderLogoControl(ControlKeys.ImageUserTile, "User tile image", image);
|
||||
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", providerLogo);
|
||||
yield return new UserTileControl(ControlKeys.ImageUserTile, "Transparent user tile image", transparentUserTile);
|
||||
|
||||
yield return new LargeLabelControl(ControlKeys.LabelLargeHeading, "The is our showcase credential provider");
|
||||
yield return new SmallLabelControl(ControlKeys.LabelSmallHeading, "Let's see what we can do");
|
||||
@@ -95,5 +98,24 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
{
|
||||
return new TestCredentialProviderTile(this, user);
|
||||
}
|
||||
|
||||
private static Bitmap CreateTransparentUserTile()
|
||||
{
|
||||
Bitmap image = new Bitmap(128, 128, PixelFormat.Format32bppArgb);
|
||||
|
||||
using (Graphics graphics = Graphics.FromImage(image))
|
||||
using (SolidBrush shadow = new SolidBrush(Color.FromArgb(96, 0, 0, 0)))
|
||||
using (SolidBrush foreground = new SolidBrush(Color.FromArgb(255, 38, 132, 255)))
|
||||
using (Pen outline = new Pen(Color.White, 5))
|
||||
{
|
||||
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
graphics.Clear(Color.Transparent);
|
||||
graphics.FillEllipse(shadow, 28, 30, 88, 88);
|
||||
graphics.FillEllipse(foreground, 12, 12, 88, 88);
|
||||
graphics.DrawEllipse(outline, 12, 12, 88, 88);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,10 @@ In order to install and run the sample app, you have to register the COM compone
|
||||
Build the EXE, and from an elevated command prompt, change to the bin folder, and run the following commands
|
||||
|
||||
```
|
||||
regsvr32 "Lithnet.CredentialProvider.Sample.net6.0.x86.comhost.dll"
|
||||
regsvr32 "Lithnet.CredentialProvider.Sample.Core.x86.comhost.dll"
|
||||
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /f
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.net6.0.x86"
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.Core.x86"
|
||||
```
|
||||
|
||||
## Disable the sample
|
||||
@@ -31,6 +31,6 @@ REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credentia
|
||||
To remove the credential provider, run the following command.
|
||||
|
||||
```
|
||||
regsvr32 /u "Lithnet.CredentialProvider.Sample.net6.0.x86.comhost.dll"
|
||||
regsvr32 /u "Lithnet.CredentialProvider.Sample.Core.x86.comhost.dll"
|
||||
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /f
|
||||
```
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<Platform>x86</Platform>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\TileIcon.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\InternalLogger.cs" Link="InternalLogger.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\ControlKeys.cs" Link="ControlKeys.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\TileIcon.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Lithnet.CredentialProvider\Lithnet.CredentialProvider.csproj" />
|
||||
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -9,11 +9,11 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ProgId("Lithnet.CredentialProvider.Sample.net6.0.x86")]
|
||||
[ProgId("Lithnet.CredentialProvider.Sample.Core.x86")]
|
||||
[Guid("90592593-f4d3-4f62-aa83-9cf1f7b590e0")]
|
||||
public class TestCredentialProviderNet60x86 : CredentialProviderBase
|
||||
public class TestCredentialProviderCoreX86 : CredentialProviderBase
|
||||
{
|
||||
private static readonly ICredentialProviderLogger logger = InternalLoggerFactory.Instance.CreateLogger<TestCredentialProviderNet60x86>();
|
||||
private static readonly ICredentialProviderLogger logger = InternalLoggerFactory.Instance.CreateLogger<TestCredentialProviderCoreX86>();
|
||||
|
||||
protected override ICredentialProviderLoggerFactory GetLoggerFactory()
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
}
|
||||
else
|
||||
{
|
||||
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.net6.0.x86.Resources.TileIcon.png"));
|
||||
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.Core.x86.Resources.TileIcon.png"));
|
||||
|
||||
yield return new CredentialProviderLabelControl(ControlKeys.LabelCredentialProvider, "Login with showcase credential provider");
|
||||
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", image);
|
||||
@@ -9,8 +9,8 @@ Build the EXE, and from an elevated command prompt, change to the bin folder, an
|
||||
```
|
||||
SETLOCAL
|
||||
SET CLSID={4EB911FA-CA18-40EA-86DF-19AFF5D1DA58}
|
||||
SET BinaryPath=D:\dev\git\lithnet\windows-credential-provider\src\samples\Lithnet.CredentialProvider.Sample.net472.x64\bin\Debug\net472\Lithnet.CredentialProvider.Sample.net472.x64.dll
|
||||
REM %windir%\Microsoft.NET\Framework64\v4.0.30319\regasm /codebase "Lithnet.CredentialProvider.Sample.net472.x64.dll"
|
||||
SET BinaryPath=D:\dev\git\lithnet\windows-credential-provider\src\samples\Lithnet.CredentialProvider.Sample.Framework.x64\bin\Debug\net472\Lithnet.CredentialProvider.Sample.Framework.x64.dll
|
||||
REM %windir%\Microsoft.NET\Framework64\v4.0.30319\regasm /codebase "Lithnet.CredentialProvider.Sample.Framework.x64.dll"
|
||||
|
||||
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Samples.TestCredentialProvider"
|
||||
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}"
|
||||
@@ -20,11 +20,11 @@ REM REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\InprocServer32" /v "Class" /t R
|
||||
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\InprocServer32" /v "RuntimeVersion" /t REG_SZ /f /d "v4.0.30319"
|
||||
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\InprocServer32" /v "CodeBase" /t REG_SZ /f /d "%BinaryPath%"
|
||||
|
||||
REG ADD "HKLM\SOFTWARE\Classes\Lithnet.CredentialProvider.Sample.net472.x64" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Samples.TestCredentialProvider"
|
||||
REG ADD "HKLM\SOFTWARE\Classes\Lithnet.CredentialProvider.Sample.net472.x64\CLSID" /ve /t REG_SZ /f /d "%CLSID%"
|
||||
REG ADD "HKLM\SOFTWARE\Classes\Lithnet.CredentialProvider.Sample.Framework.x64" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Samples.TestCredentialProvider"
|
||||
REG ADD "HKLM\SOFTWARE\Classes\Lithnet.CredentialProvider.Sample.Framework.x64\CLSID" /ve /t REG_SZ /f /d "%CLSID%"
|
||||
|
||||
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\%CLSID%" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.net472.x64"
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\%CLSID%" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.Framework.x64"
|
||||
```
|
||||
|
||||
## Disable the sample
|
||||
@@ -45,6 +45,6 @@ REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credentia
|
||||
To remove the credential provider, run the following command.
|
||||
|
||||
```
|
||||
%windir%\Microsoft.NET\Framework64\v4.0.30319\regasm /u "Lithnet.CredentialProvider.Sample.net472.x64.dll"
|
||||
%windir%\Microsoft.NET\Framework64\v4.0.30319\regasm /u "Lithnet.CredentialProvider.Sample.Framework.x64.dll"
|
||||
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4eb911fa-ca18-40ea-86df-19aff5d1da58"}" /f
|
||||
```
|
||||
```
|
||||
@@ -15,7 +15,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Lithnet.CredentialProvider" Version="1.0.*-beta1*" />
|
||||
<ProjectReference Include="..\..\Lithnet.CredentialProvider\Lithnet.CredentialProvider.csproj" />
|
||||
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||
</ItemGroup>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -10,9 +10,9 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ProgId("Lithnet.CredentialProvider.Sample.net472.x64")]
|
||||
[ProgId("Lithnet.CredentialProvider.Sample.Framework.x64")]
|
||||
[Guid("4eb911fa-ca18-40ea-86df-19aff5d1da58")]
|
||||
public class TestCredentialProviderNet472x64 : CredentialProviderBase
|
||||
public class TestCredentialProviderFrameworkX64 : CredentialProviderBase
|
||||
{
|
||||
protected override ICredentialProviderLoggerFactory GetLoggerFactory()
|
||||
{
|
||||
@@ -33,7 +33,7 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
}
|
||||
else
|
||||
{
|
||||
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.net472.x64.Resources.TileIcon.png"));
|
||||
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.Framework.x64.Resources.TileIcon.png"));
|
||||
|
||||
yield return new CredentialProviderLabelControl(ControlKeys.LabelCredentialProvider, "Login with showcase credential provider");
|
||||
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", image);
|
||||
@@ -5,7 +5,7 @@ using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Lithnet.CredentialProvider.Samples
|
||||
{
|
||||
public class TestCredentialProviderTile : CredentialTile2
|
||||
public class TestCredentialProviderTile : CredentialTile3
|
||||
{
|
||||
private TextboxControl UsernameControl;
|
||||
private SecurePasswordTextboxControl PasswordControl;
|
||||
@@ -189,4 +189,4 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
return plainTextPassword;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,10 @@ In order to install and run the sample app, you have to register the COM compone
|
||||
Build the EXE, and from an elevated command prompt, change to the bin folder, and run the following commands
|
||||
|
||||
```
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\regasm /codebase "Lithnet.CredentialProvider.Sample.net472.x86.dll"
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\regasm /codebase "Lithnet.CredentialProvider.Sample.Framework.x86.dll"
|
||||
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /f
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.net472.x86"
|
||||
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.Framework.x86"
|
||||
```
|
||||
|
||||
## Disable the sample
|
||||
@@ -31,6 +31,6 @@ REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credentia
|
||||
To remove the credential provider, run the following command.
|
||||
|
||||
```
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\regasm /u "Lithnet.CredentialProvider.Sample.net472.x86.dll"
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\regasm /u "Lithnet.CredentialProvider.Sample.Framework.x86.dll"
|
||||
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /f
|
||||
```
|
||||
```
|
||||
@@ -11,9 +11,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\InternalLogger.cs" Link="InternalLogger.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\ControlKeys.cs" Link="ControlKeys.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\InternalLogger.cs" Link="InternalLogger.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\ControlKeys.cs" Link="ControlKeys.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.Framework.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -21,7 +21,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Lithnet.CredentialProvider" Version="1.0.*-beta1*" />
|
||||
<ProjectReference Include="..\..\Lithnet.CredentialProvider\Lithnet.CredentialProvider.csproj" />
|
||||
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -9,11 +9,11 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ProgId("Lithnet.CredentialProvider.Sample.net472.x86")]
|
||||
[ProgId("Lithnet.CredentialProvider.Sample.Framework.x86")]
|
||||
[Guid("c9055c88-03f9-4a12-8e33-1ee75826a4a6")]
|
||||
public class TestCredentialProviderNet472x86 : CredentialProviderBase
|
||||
public class TestCredentialProviderFrameworkX86 : CredentialProviderBase
|
||||
{
|
||||
private static readonly ICredentialProviderLogger logger = InternalLoggerFactory.Instance.CreateLogger<TestCredentialProviderNet472x86>();
|
||||
private static readonly ICredentialProviderLogger logger = InternalLoggerFactory.Instance.CreateLogger<TestCredentialProviderFrameworkX86>();
|
||||
|
||||
protected override ICredentialProviderLoggerFactory GetLoggerFactory()
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace Lithnet.CredentialProvider.Samples
|
||||
}
|
||||
else
|
||||
{
|
||||
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.net472.x86.Resources.TileIcon.png"));
|
||||
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.Framework.x86.Resources.TileIcon.png"));
|
||||
|
||||
yield return new CredentialProviderLabelControl(ControlKeys.LabelCredentialProvider, "Login with showcase credential provider");
|
||||
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", image);
|
||||
@@ -1,32 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<Platform>x64</Platform>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\TileIcon.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\InternalLogger.cs" Link="InternalLogger.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\ControlKeys.cs" Link="ControlKeys.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\TileIcon.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Lithnet.CredentialProvider" Version="1.0.*-beta1*" />
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,32 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<Platform>x86</Platform>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\TileIcon.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\InternalLogger.cs" Link="InternalLogger.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\ControlKeys.cs" Link="ControlKeys.cs" />
|
||||
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\TileIcon.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Lithnet.CredentialProvider" Version="1.0.*-beta1*" />
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -8,8 +8,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<Platform>x86</Platform>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||