Vanara/PInvoke/WinSCard/WinSCard.cs

4551 lines
236 KiB
C#
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#nullable enable
global using System;
global using System.Runtime.InteropServices;
global using Vanara.InteropServices;
global using SCARDCONTEXT = System.UIntPtr;
using System.Linq;
using System.Text;
using Vanara.Extensions;
namespace Vanara.PInvoke;
/// <summary>
/// Provides the definitions and symbols necessary for an Application or Smart Card Service Provider to access the Smartcard Subsystem from WinSCard.dll.
/// </summary>
public static partial class WinSCard
{
/// <summary>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </summary>
public const string SCARD_ALL_READERS = "SCard$AllReaders\000";
/// <summary>Value used to indicate that memory for a return value should be allocated by the function and freed using <see cref="SCardFreeMemory"/>.</summary>
public const uint SCARD_AUTOALLOCATE = unchecked((uint)-1);
/// <summary>Default group to which all readers are added when introduced into the system.</summary>
public const string SCARD_DEFAULT_READERS = "SCard$DefaultReaders\000";
/// <summary>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </summary>
public const string SCARD_LOCAL_READERS = "SCard$LocalReaders\000";
/// <summary>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </summary>
public const string SCARD_SYSTEM_READERS = "SCard$SystemReaders\000";
private const string Lib_Scarddlg = "scarddlg.dll";
private const string Lib_Winscard = "winscard.dll";
/// <summary>A card verify routine delegate.</summary>
/// <param name="hSCardContext">The card context passed in the parameter block.</param>
/// <param name="hcard">The card handle.</param>
/// <param name="pvUserData">Pointer to user data passed in the parameter block.</param>
/// <returns>
/// If the card is rejected by the verify routine, <see langword="false"/> is returned, and the card will be disconnected. If the card is
/// accepted by the verify routine, <see langword="true"/> is returned.
/// </returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Auto)]
public delegate bool LPOCNCHKPROC([In] SCARDCONTEXT hSCardContext, [In] SCARDHANDLE hcard, [In] IntPtr pvUserData);
/// <summary>A card connect routine delegate.</summary>
/// <param name="hSCardContext">The card context passed in the parameter block.</param>
/// <param name="szReader">The name of the reader.</param>
/// <param name="mszCards">The possible card names in the reader.</param>
/// <param name="pvUserData">Pointer to user data passed in the parameter block.</param>
/// <returns>If the connect function is successful, the card is left connected and initialized, and the card handle is returned.</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Auto)]
public delegate SCARDHANDLE LPOCNCONNPROC([In] SCARDCONTEXT hSCardContext, [In] string szReader, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[] mszCards, [In] IntPtr pvUserData);
/// <summary>A card disconnect routine delegate.</summary>
/// <param name="hSCardContext">The card context passed in the parameter block.</param>
/// <param name="hcard">The card handle.</param>
/// <param name="pvUserData">Pointer to user data passed in the parameter block.</param>
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Auto)]
public delegate void LPOCNDSCPROC([In] SCARDCONTEXT hSCardContext, [In] SCARDHANDLE hcard, [In] IntPtr pvUserData);
private delegate SCARD_RET SCardListCardsDelegate(IntPtr mszOut, ref uint pcch);
/// <summary></summary>
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.__unnamed_struct_4")]
[Flags]
public enum SC_DLG : uint
{
/// <summary>
/// Display the dialog box only if the card being searched for by the calling application is not located and available for use in a
/// reader. This allows the card to be found, connected (either through the internal dialog box mechanism or the user callback
/// functions), and returned to the calling application.
/// </summary>
SC_DLG_MINIMAL_UI = 0x01,
/// <summary>Force no display of the <c>Select Card</c> user interface (UI), regardless of search outcome.</summary>
SC_DLG_NO_UI = 0x02,
/// <summary>Force display of the <c>Select Card</c> UI, regardless of the search outcome.</summary>
SC_DLG_FORCE_UI = 0x04,
}
/// <summary>Action to take on the card in the connected reader.</summary>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardDisconnect")]
public enum SCARD_ACTION
{
/// <summary>Do not do anything special.</summary>
SCARD_LEAVE_CARD = 0,
/// <summary>Reset the card.</summary>
SCARD_RESET_CARD = 1,
/// <summary>Power down the card.</summary>
SCARD_UNPOWER_CARD = 2,
/// <summary>Eject the card.</summary>
SCARD_EJECT_CARD = 3,
}
/// <summary>The event to log.</summary>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardAudit")]
[Flags]
public enum SCARD_AUDIT_CHV : uint
{
/// <summary>A smart card holder verification (CHV) attempt failed.</summary>
SCARD_AUDIT_CHV_FAILURE = 0x0,
/// <summary>A smart card holder verification (CHV) attempt succeeded.</summary>
SCARD_AUDIT_CHV_SUCCESS = 0x1,
}
/// <summary></summary>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetCardTypeProviderNameA")]
public enum SCARD_PROVIDER
{
/// <summary>The function retrieves the name of the smart card's primary service provider as a GUID string.</summary>
SCARD_PROVIDER_PRIMARY = 1,
/// <summary>The function retrieves the name of the cryptographic service provider.</summary>
SCARD_PROVIDER_CSP = 2,
/// <summary>The function retrieves the name of the smart card key storage provider (KSP).</summary>
SCARD_PROVIDER_KSP = 3,
}
/// <summary>Scope of the resource manager context.</summary>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardEstablishContext")]
public enum SCARD_SCOPE
{
/// <summary>Database operations are performed within the domain of the user.</summary>
SCARD_SCOPE_USER = 0,
/// <summary>Database operations are performed within the terminal session context.</summary>
SCARD_SCOPE_TERMINAL = 1,
/// <summary>
/// Database operations are performed within the domain of the system. The calling application must have appropriate access
/// permissions for any database actions.
/// </summary>
SCARD_SCOPE_SYSTEM = 2,
}
/// <summary>A flag that indicates whether other applications may form connections to the card.</summary>
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.nf-winscard-scardconnecta")]
public enum SCARD_SHARE : uint
{
/// <summary>This application is not willing to share the card with other applications.</summary>
SCARD_SHARE_EXCLUSIVE = 1,
/// <summary>This application is willing to share the card with other applications.</summary>
SCARD_SHARE_SHARED = 2,
/// <summary>
/// This application is allocating the reader for its private use, and will be controlling it directly. No other applications are
/// allowed access to it.
/// </summary>
SCARD_SHARE_DIRECT = 3,
}
/// <summary>State of the reader, as seen by the application.</summary>
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.__unnamed_struct_0")]
[Flags]
public enum SCARD_STATE : uint
{
/// <summary>
/// The application is unaware of the current state, and would like to know. The use of this value results in an immediate return
/// from state transition monitoring services. This is represented by all bits set to zero.
/// </summary>
SCARD_STATE_UNAWARE = 0x00000000,
/// <summary>
/// The application is not interested in this reader, and it should not be considered during monitoring operations. If this bit value
/// is set, all other bits are ignored.
/// </summary>
SCARD_STATE_IGNORE = 0x00000001,
/// <summary>
/// There is a difference between the state believed by the application, and the state known by the resource manager. When this bit
/// is set, the application may assume a significant state change has occurred on this reader.
/// </summary>
SCARD_STATE_CHANGED = 0x00000002,
/// <summary>
/// The given reader name is not recognized by the resource manager. If this bit is set, then SCARD_STATE_CHANGED and
/// SCARD_STATE_IGNORE will also be set.
/// </summary>
SCARD_STATE_UNKNOWN = 0x00000004,
/// <summary>
/// The application expects that this reader is not available for use. If this bit is set, then all the following bits are ignored.
/// </summary>
SCARD_STATE_UNAVAILABLE = 0x00000008,
/// <summary>The application expects that there is no card in the reader. If this bit is set, all the following bits are ignored.</summary>
SCARD_STATE_EMPTY = 0x00000010,
/// <summary>The application expects that there is a card in the reader.</summary>
SCARD_STATE_PRESENT = 0x00000020,
/// <summary>
/// The application expects that there is a card in the reader with an ATR that matches one of the target cards. If this bit is set,
/// SCARD_STATE_PRESENT is assumed. This bit has no meaning to SCardGetStatusChange beyond SCARD_STATE_PRESENT.
/// </summary>
SCARD_STATE_ATRMATCH = 0x00000040,
/// <summary>
/// The application expects that the card in the reader is allocated for exclusive use by another application. If this bit is set,
/// SCARD_STATE_PRESENT is assumed.
/// </summary>
SCARD_STATE_EXCLUSIVE = 0x00000080,
/// <summary>
/// The application expects that the card in the reader is in use by one or more other applications, but may be connected to in
/// shared mode. If this bit is set, SCARD_STATE_PRESENT is assumed.
/// </summary>
SCARD_STATE_INUSE = 0x00000100,
/// <summary>The application expects that there is an unresponsive card in the reader.</summary>
SCARD_STATE_MUTE = 0x00000200,
/// <summary>This implies that the card in the reader has not been powered up.</summary>
SCARD_STATE_UNPOWERED = 0x00000400,
}
/// <summary>
/// The <c>GetOpenCardName</c> function displays the smart card "select card" dialog box. Call the function SCardUIDlgSelectCard instead
/// of <c>GetOpenCardName</c>. The <c>GetOpenCardName</c> function is maintained for backward compatibility with version 1.0 of the
/// Microsoft Smart Card Base Components, but calls to <c>GetOpenCardName</c> are mapped to <c>SCardUIDlgSelectCard</c>.
/// </summary>
/// <param name="unnamedParam1">A pointer to the OPENCARDNAME structure for the "select card" dialog box.</param>
/// <returns>
/// <para>The function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines GetOpenCardName as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-getopencardnamea LONG GetOpenCardNameA( [in] LPOPENCARDNAMEA
// unnamedParam1 );
[DllImport(Lib_Scarddlg, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.GetOpenCardNameA")]
public static extern SCARD_RET GetOpenCardName(in OPENCARDNAME unnamedParam1);
/// <summary>
/// The <c>SCardAccessStartedEvent</c> function returns an event handle when an event signals that the smart card resource manager is
/// started. The event-object handle can be specified in a call to one of the wait functions.
/// </summary>
/// <returns>
/// <para>The function returns an event HANDLE if it succeeds or <c>NULL</c> if it fails.</para>
/// <para>If the function fails, the GetLastError function provides information on the cause of the failure.</para>
/// </returns>
/// <remarks>
/// <para>The event-object handle returned can be specified in a call to one of the wait functions.</para>
/// <para>
/// Do not close the handle returned by this function. When you have finished using the handle, decrement the reference count by calling
/// the SCardReleaseStartedEvent function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardaccessstartedevent HANDLE SCardAccessStartedEvent();
[DllImport(Lib_Winscard, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardAccessStartedEvent")]
public static extern HEVENT SCardAccessStartedEvent();
/// <summary>The <c>SCardAddReaderToGroup</c> function adds a reader to a reader group.</summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szReaderName">Display name of the reader that you are adding.</param>
/// <param name="szGroupName">
/// <para>Display name of the group to which you are adding the reader.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ALL_READERS</c> TEXT("SCard$AllReaders\000")</term>
/// <term>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_DEFAULT_READERS</c> TEXT("SCard$DefaultReaders\000")</term>
/// <term>Default group to which all readers are added when introduced into the system.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LOCAL_READERS</c> TEXT("SCard$LocalReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_SYSTEM_READERS</c> TEXT("SCard$SystemReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>SCardAddReaderToGroup</c> automatically creates the reader group specified if it does not already exist.</para>
/// <para>
/// The <c>SCardAddReaderToGroup</c> function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example demonstrates how to add a smart card reader to a group. The example assumes that lReturn is an existing
/// variable of type <c>LONG</c>, that <c>hContext</c> is a valid handle received from a previous call to the SCardEstablishContext
/// function, and that "MyReader" and "MyReaderGroup" are known by the system through previous calls to the SCardIntroduceReader and
/// SCardIntroduceReaderGroup functions, respectively.
/// </para>
/// <para>
/// <code> lReturn = SCardAddReaderToGroup( hContext, L"MyReader", L"MyReaderGroup"); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardAddReaderToGroup\n");</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardAddReaderToGroup as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardaddreadertogroupa LONG SCardAddReaderToGroupA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szReaderName, [in] LPCSTR szGroupName );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardAddReaderToGroupA")]
public static extern SCARD_RET SCardAddReaderToGroup([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szReaderName, [MarshalAs(UnmanagedType.LPTStr)] string szGroupName);
/// <summary>The <c>SCardAudit</c> function writes event messages to the Windows application log Microsoft-Windows-SmartCard-Audit/Authentication.</summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context can be set by a previous call to the
/// SCardEstablishContext function. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="dwEvent">
/// <para>The event to log.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_AUDIT_CHV_FAILURE</c> 0x0</term>
/// <term>A smart card holder verification (CHV) attempt failed.</term>
/// </item>
/// <item>
/// <term><c>SCARD_AUDIT_CHV_SUCCESS</c> 0x1</term>
/// <term>A smart card holder verification (CHV) attempt succeeded.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected. An application calling the <c>SCardAudit</c> function from within a Remote Desktop session will log
/// the event on the remote system.
/// </para>
/// <para>Examples</para>
/// <para>
/// <code>// hContext was set by a previous call to SCardEstablishContext. lReturn = SCardAudit (hContext, SCARD_AUDIT_CHV_SUCCESS); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardAudit - %x\n", lReturn); // Take appropriate action }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardaudit LONG SCardAudit( [in] SCARDCONTEXT hContext, [in]
// DWORD dwEvent );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardAudit")]
public static extern SCARD_RET SCardAudit([In] SCARDCONTEXT hContext, [In] SCARD_AUDIT_CHV dwEvent);
/// <summary>
/// <para>The <c>SCardBeginTransaction</c> function starts a transaction.</para>
/// <para>
/// The function waits for the completion of all other transactions before it begins. After the transaction starts, all other
/// applications are blocked from accessing the smart card while the transaction is in progress.
/// </para>
/// </summary>
/// <param name="hCard">A reference value obtained from a previous call to SCardConnect.</param>
/// <returns>
/// <para>If the function succeeds, it returns <c>SCARD_S_SUCCESS</c>.</para>
/// <para>If the function fails, it returns an error code. For more information, see Smart Card Return Values.</para>
/// <para>If another process or thread has reset the card, SCARD_W_RESET_CARD is returned as expected.</para>
/// <para>
/// <c>Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> This function
/// returns <c>SCARD_S_SUCCESS</c> even if another process or thread has reset the card. To determine whether the card has been reset,
/// call the SCardStatus function immediately after calling this function.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// If a transaction is held on the card for more than five seconds with no operations happening on that card, then the card is reset.
/// Calling any of the Smart Card and Reader Access Functions or Direct Card Access Functions on the card that is transacted results in
/// the timer being reset to continue allowing the transaction to be used.
/// </para>
/// <para>
/// The <c>SCardBeginTransaction</c> function is a smart card and reader access function. For more information about other access
/// functions, see Smart Card and Reader Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>The following example demonstrates how to begin a smart card transaction. The example assumes that
/// <code>lReturn</code>
/// is an existing variable of type <c>LONG</c> and that
/// <code>hCard</code>
/// is a valid handle received from a previous call to SCardConnect.
/// </para>
/// <para>
/// <code> lReturn = SCardBeginTransaction( hCard ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardBeginTransaction\n");</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardbegintransaction LONG SCardBeginTransaction( [in]
// SCARDHANDLE hCard );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardBeginTransaction")]
public static extern SCARD_RET SCardBeginTransaction([In] SCARDHANDLE hCard);
/// <summary>
/// <para>The <c>SCardCancel</c> function terminates all outstanding actions within a specific resource manager context.</para>
/// <para>
/// The only requests that you can cancel are those that require waiting for external action by the smart card or user. Any such
/// outstanding action requests will terminate with a status indication that the action was canceled. This is especially useful to force
/// outstanding SCardGetStatusChange calls to terminate.
/// </para>
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardCancel</c> function is a smart card tracking function. For a description of other tracking functions, see Smart Card
/// Tracking Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example cancels all outstanding actions in the specified context. The example assumes that lReturn is an existing
/// variable of type <c>LONG</c> and that hContext is a valid handle received from a previous call to SCardEstablishContext.
/// </para>
/// <para>
/// <code> lReturn = SCardCancel( hContext ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardCancel\n");</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardcancel LONG SCardCancel( [in] SCARDCONTEXT hContext );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardCancel")]
public static extern SCARD_RET SCardCancel([In] SCARDCONTEXT hContext);
/// <summary>
/// The <c>SCardConnect</c> function establishes a connection (using a specific resource manager context) between the calling application
/// and a smart card contained by a specific reader. If no card exists in the specified reader, an error is returned.
/// </summary>
/// <param name="hContext">
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// </param>
/// <param name="szReader">The name of the reader that contains the target card.</param>
/// <param name="dwShareMode">
/// <para>A flag that indicates whether other applications may form connections to the card.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_SHARE_SHARED</c></term>
/// <term>This application is willing to share the card with other applications.</term>
/// </item>
/// <item>
/// <term><c>SCARD_SHARE_EXCLUSIVE</c></term>
/// <term>This application is not willing to share the card with other applications.</term>
/// </item>
/// <item>
/// <term><c>SCARD_SHARE_DIRECT</c></term>
/// <term>
/// This application is allocating the reader for its private use, and will be controlling it directly. No other applications are allowed
/// access to it.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="dwPreferredProtocols">
/// <para>A bitmask of acceptable protocols for the connection. Possible values may be combined with the <c>OR</c> operation.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_PROTOCOL_T0</c></term>
/// <term>T=0 is an acceptable protocol.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROTOCOL_T1</c></term>
/// <term>T=1 is an acceptable protocol.</term>
/// </item>
/// <item>
/// <term><c>0</c></term>
/// <term>
/// This parameter may be zero only if <c>dwShareMode</c> is set to SCARD_SHARE_DIRECT. In this case, no protocol negotiation will be
/// performed by the drivers until an IOCTL_SMARTCARD_SET_PROTOCOL control directive is sent with SCardControl.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="phCard">A handle that identifies the connection to the smart card in the designated reader.</param>
/// <param name="pdwActiveProtocol">
/// <para>A flag that indicates the established active protocol.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_PROTOCOL_T0</c></term>
/// <term>T=0 is the active protocol.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROTOCOL_T1</c></term>
/// <term>T=1 is the active protocol.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROTOCOL_UNDEFINED</c></term>
/// <term>
/// SCARD_SHARE_DIRECT has been specified, so that no protocol negotiation has occurred. It is possible that there is no card in the reader.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// <item>
/// <term><c>SCARD_E_NOT_READY</c></term>
/// <term>The reader was unable to connect to the card.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardConnect</c> function is a smart card and reader access function. For more information about other access functions, see
/// Smart Card and Reader Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example creates a connection to a reader. The example assumes that <c>hContext</c> is a valid handle of type
/// <c>SCARDCONTEXT</c> received from a previous call to SCardEstablishContext.
/// </para>
/// <para>
/// <code>SCARDHANDLE hCardHandle; LONG lReturn; DWORD dwAP; lReturn = SCardConnect( hContext, (LPCTSTR)"Rainbow Technologies SCR3531 0", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &amp;hCardHandle, &amp;dwAP ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardConnect\n"); exit(1); // Or other appropriate action. } // Use the connection. // Display the active protocol. switch ( dwAP ) { case SCARD_PROTOCOL_T0: printf("Active protocol T0\n"); break; case SCARD_PROTOCOL_T1: printf("Active protocol T1\n"); break; case SCARD_PROTOCOL_UNDEFINED: default: printf("Active protocol unnegotiated or unknown\n"); break; } // Remember to disconnect (by calling SCardDisconnect). // ...</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardConnect as an alias which automatically selects the ANSI or Unicode version of this function based
/// on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardconnecta LONG SCardConnectA( [in] SCARDCONTEXT hContext,
// [in] LPCSTR szReader, [in] DWORD dwShareMode, [in] DWORD dwPreferredProtocols, [out] LPSCARDHANDLE phCard, [out] LPDWORD
// pdwActiveProtocol );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardConnectA")]
public static extern SCARD_RET SCardConnect([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szReader,
[In] SCARD_SHARE dwShareMode, [In] SCARD_PROTOCOL dwPreferredProtocols, [Out] out SafeSCARDHANDLE phCard, out SCARD_PROTOCOL pdwActiveProtocol);
/// <summary>
/// The <c>SCardControl</c> function gives you direct control of the reader. You can call it any time after a successful call to
/// SCardConnect and before a successful call to SCardDisconnect. The effect on the state of the reader depends on the control code.
/// </summary>
/// <param name="hCard">Reference value returned from SCardConnect.</param>
/// <param name="dwControlCode">Control code for the operation. This value identifies the specific operation to be performed.</param>
/// <param name="lpInBuffer">
/// Pointer to a buffer that contains the data required to perform the operation. This parameter can be <c>NULL</c> if the
/// <c>dwControlCode</c> parameter specifies an operation that does not require input data.
/// </param>
/// <param name="cbInBufferSize">Size, in bytes, of the buffer pointed to by <c>lpInBuffer</c>.</param>
/// <param name="lpOutBuffer">
/// Pointer to a buffer that receives the operation's output data. This parameter can be <c>NULL</c> if the <c>dwControlCode</c>
/// parameter specifies an operation that does not produce output data.
/// </param>
/// <param name="cbOutBufferSize">Size, in bytes, of the buffer pointed to by <c>lpOutBuffer</c>.</param>
/// <param name="lpBytesReturned">
/// Pointer to a <c>DWORD</c> that receives the size, in bytes, of the data stored into the buffer pointed to by <c>lpOutBuffer</c>.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardControl</c> function is a direct card access function. For more information on other direct access functions, see Direct
/// Card Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example issues a control code. The example assumes that hCardHandle is a valid handle received from a previous call to
/// SCardConnect and that dwControlCode is a variable of type <c>DWORD</c> previously initialized to a valid control code. This
/// particular control code requires no input data and expects no output data.
/// </para>
/// <para>
/// <code> lReturn = SCardControl( hCardHandle, dwControlCode, NULL, 0, NULL, 0, 0 ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardControl\n");</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardcontrol LONG SCardControl( [in] SCARDHANDLE hCard, [in]
// DWORD dwControlCode, [in] LPCVOID lpInBuffer, [in] DWORD cbInBufferSize, [out] LPVOID lpOutBuffer, [in] DWORD cbOutBufferSize, [out]
// LPDWORD lpBytesReturned );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardControl")]
public static extern SCARD_RET SCardControl([In] SCARDHANDLE hCard, [In] uint dwControlCode, [In, Optional] IntPtr lpInBuffer, [In] uint cbInBufferSize,
[Out, Optional] IntPtr lpOutBuffer, [In] uint cbOutBufferSize, out uint lpBytesReturned);
/// <summary>
/// The <c>SCardDisconnect</c> function terminates a connection previously opened between the calling application and a smart card in the
/// target reader.
/// </summary>
/// <param name="hCard">Reference value obtained from a previous call to SCardConnect.</param>
/// <param name="dwDisposition">
/// <para>Action to take on the card in the connected reader on close.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_LEAVE_CARD</c></term>
/// <term>Do not do anything special.</term>
/// </item>
/// <item>
/// <term><c>SCARD_RESET_CARD</c></term>
/// <term>Reset the card.</term>
/// </item>
/// <item>
/// <term><c>SCARD_UNPOWER_CARD</c></term>
/// <term>Power down the card.</term>
/// </item>
/// <item>
/// <term><c>SCARD_EJECT_CARD</c></term>
/// <term>Eject the card.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If an application (which previously called SCardConnect) exits without calling <c>SCardDisconnect</c>, the card is automatically reset.
/// </para>
/// <para>
/// The <c>SCardDisconnect</c> function is a smart card and reader access function. For more information on other access functions, see
/// Smart Card and Reader Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example terminates the specified smart card connection. The example assumes that lReturn is a variable of type
/// <c>LONG</c>, and that hCardHandle is a valid handle received from a previous call to SCardConnect.
/// </para>
/// <para>
/// <code> lReturn = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardDisconnect\n"); exit(1); // Or other appropriate action. }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scarddisconnect LONG SCardDisconnect( [in] SCARDHANDLE hCard,
// [in] DWORD dwDisposition );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardDisconnect")]
public static extern SCARD_RET SCardDisconnect([In] SCARDHANDLE hCard, [In] SCARD_ACTION dwDisposition);
/// <summary>
/// The <c>SCardEndTransaction</c> function completes a previously declared transaction, allowing other applications to resume
/// interactions with the card.
/// </summary>
/// <param name="hCard">
/// Reference value obtained from a previous call to SCardConnect. This value would also have been used in an earlier call to SCardBeginTransaction.
/// </param>
/// <param name="dwDisposition">
/// <para>Action to take on the card in the connected reader on close.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_EJECT_CARD</c></term>
/// <term>Eject the card.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LEAVE_CARD</c></term>
/// <term>Do not do anything special.</term>
/// </item>
/// <item>
/// <term><c>SCARD_RESET_CARD</c></term>
/// <term>Reset the card.</term>
/// </item>
/// <item>
/// <term><c>SCARD_UNPOWER_CARD</c></term>
/// <term>Power down the card.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>SCARD_S_SUCCESS</c>.</para>
/// <para>If the function fails, it returns an error code. For more information, see Smart Card Return Values. Possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code/value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_W_RESET_CARD</c> 0x80100068L</term>
/// <term>
/// The transaction was released. Any future communication with the card requires a call to the SCardReconnect function. <c>Windows
/// Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> The transaction was not released. The application must
/// immediately call the SCardDisconnect, SCardReconnect, or SCardReleaseContext function to avoid an existing transaction blocking other
/// threads and processes from communicating with the smart card.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardEndTransaction</c> function is a smart card and reader access function. For more information on other access functions,
/// see Smart Card and Reader Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example ends a smart card transaction. The example assumes that lReturn is a valid variable of type <c>LONG</c>, that
/// hCard is a valid handle received from a previous call to the SCardConnect function, and that hCard was passed to a previous call to
/// the SCardBeginTransaction function.
/// </para>
/// <para>
/// <code> lReturn = SCardEndTransaction(hCard, SCARD_LEAVE_CARD); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardEndTransaction\n");</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardendtransaction LONG SCardEndTransaction( [in] SCARDHANDLE
// hCard, [in] DWORD dwDisposition );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardEndTransaction")]
public static extern SCARD_RET SCardEndTransaction([In] SCARDHANDLE hCard, [In] SCARD_ACTION dwDisposition);
/// <summary>
/// The <c>SCardEstablishContext</c> function establishes the resource manager context (the scope) within which database operations are performed.
/// </summary>
/// <param name="dwScope">
/// <para>Scope of the resource manager context. This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_SCOPE_USER</c></term>
/// <term>Database operations are performed within the domain of the user.</term>
/// </item>
/// <item>
/// <term><c>SCARD_SCOPE_SYSTEM</c></term>
/// <term>
/// Database operations are performed within the domain of the system. The calling application must have appropriate access permissions
/// for any database actions.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pvReserved1">
/// Reserved for future use and must be <c>NULL</c>. This parameter will allow a suitably privileged management application to act on
/// behalf of another user.
/// </param>
/// <param name="pvReserved2">Reserved for future use and must be <c>NULL</c>.</param>
/// <param name="phContext">
/// A handle to the established resource manager context. This handle can now be supplied to other functions attempting to do work within
/// this context.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns SCARD_S_SUCCESS.</para>
/// <para>If the function fails, it returns an error code. For more information, see Smart Card Return Values.</para>
/// </returns>
/// <remarks>
/// <para>
/// The context handle returned by <c>SCardEstablishContext</c> can be used by database query and management functions. For more
/// information, see Smart Card Database Query Functions and Smart Card Database Management Functions.
/// </para>
/// <para>To release an established resource manager context, use SCardReleaseContext.</para>
/// <para>
/// If the client attempts a smart card operation in a remote session, such as a client session running on a terminal server, and the
/// operating system in use does not support smart card redirection, this function returns ERROR_BROKEN_PIPE.
/// </para>
/// <para>Examples</para>
/// <para>The following example establishes a resource manager context.</para>
/// <para>
/// <code>SCARDCONTEXT hSC; LONG lReturn; // Establish the context. lReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &amp;hSC); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardEstablishContext\n"); else { // Use the context as needed. When done, // free the context by calling SCardReleaseContext. // ... }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardestablishcontext LONG SCardEstablishContext( [in] DWORD
// dwScope, [in] LPCVOID pvReserved1, [in] LPCVOID pvReserved2, [out] LPSCARDCONTEXT phContext );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardEstablishContext")]
public static extern SCARD_RET SCardEstablishContext([In] SCARD_SCOPE dwScope, [In, Optional] IntPtr pvReserved1, [In, Optional] IntPtr pvReserved2, out SCARDCONTEXT phContext);
/// <summary>The <c>SCardForgetCardType</c> function removes an introduced smart card from the smart card subsystem.</summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szCardName">Display name of the card to be removed from the smart card database.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function <c>SCardForgetCardType</c> when inside a Remote Desktop session will not
/// result in an error. It only means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>
/// The <c>SCardForgetCardType</c> function is a database management function. For more information about other database management
/// functions, see Smart Card Database Management Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example removes the specified card type from the system. The example assumes that lReturn is a valid variable of type
/// <c>LONG</c>, that <c>hContext</c> is a valid handle received from a previous call to the SCardEstablishContext function, and that
/// "MyCardName" was previously introduced by a call to the SCardIntroduceCardType function.
/// </para>
/// <para>
/// <code> lReturn = SCardForgetCardType(hContext, L"MyCardName"); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardForgetCardType\n");</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardForgetCardType as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardforgetcardtypea LONG SCardForgetCardTypeA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szCardName );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardForgetCardTypeA")]
public static extern SCARD_RET SCardForgetCardType([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCardName);
/// <summary>
/// The <c>SCardForgetReader</c> function removes a previously introduced reader from control by the smart card subsystem. It is removed
/// from the smart card database, including from any reader group that it may have been added to.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szReaderName">Display name of the reader to be removed from the smart card database.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>If the specified reader is the last member of a reader group, the reader group is automatically removed as well.</para>
/// <para>
/// The <c>SCardForgetReader</c> function is a database management function. For more information on other database management functions,
/// see Smart Card Database Management Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example removes the display name of the specified card reader from the system. The example assumes that lReturn is a
/// valid variable of type <c>LONG</c> and that hContext is a valid handle received from a previous call to the SCardEstablishContext function.
/// </para>
/// <para>
/// <code> lReturn = SCardForgetReader(hContext, TEXT("MyReader")); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardForgetReader\n");</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardForgetReader as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardforgetreadera LONG SCardForgetReaderA( [in] SCARDCONTEXT
// hContext, [in] LPCSTR szReaderName );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardForgetReaderA")]
public static extern SCARD_RET SCardForgetReader([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szReaderName);
/// <summary>
/// The <c>SCardForgetReaderGroup</c> function removes a previously introduced smart card reader group from the smart card subsystem.
/// Although this function automatically clears all readers from the group, it does not affect the existence of the individual readers in
/// the database.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szGroupName">
/// <para>Display name of the reader group to be removed. System-defined reader groups cannot be removed from the database.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ALL_READERS</c> TEXT("SCard$AllReaders\000")</term>
/// <term>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_DEFAULT_READERS</c> TEXT("SCard$DefaultReaders\000")</term>
/// <term>Default group to which all readers are added when introduced into the system.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LOCAL_READERS</c> TEXT("SCard$LocalReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_SYSTEM_READERS</c> TEXT("SCard$SystemReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardForgetReaderGroup</c> function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows how to remove a reader group from the system. The example assumes that lReturn is an existing variable of
/// type <c>LONG</c>, and that hContext is a valid handle to a resource manager context previously obtained from a call to the
/// SCardEstablishContext function.
/// </para>
/// <para>
/// <code> lReturn = SCardForgetReaderGroup(hContext, L"MyReaderGroup"); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardForgetReaderGroup\n");</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardForgetReaderGroup as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardforgetreadergroupa LONG SCardForgetReaderGroupA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szGroupName );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardForgetReaderGroupA")]
public static extern SCARD_RET SCardForgetReaderGroup([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szGroupName);
/// <summary>
/// The <c>SCardFreeMemory</c> function releases memory that has been returned from the resource manager using the SCARD_AUTOALLOCATE
/// length designator.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context returned from SCardEstablishContext, or <c>NULL</c> if the creating function also
/// specified <c>NULL</c> for its <c>hContext</c> parameter. For more information, see Smart Card Database Query Functions.
/// </param>
/// <param name="pvMem">Memory block to be released.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardfreememory LONG SCardFreeMemory( [in] SCARDCONTEXT
// hContext, [in] LPCVOID pvMem );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardFreeMemory")]
public static extern SCARD_RET SCardFreeMemory([In] SCARDCONTEXT hContext, [In] IntPtr pvMem);
/// <summary>
/// The <c>SCardGetAttrib</c> function retrieves the current reader attributes for the given handle. It does not affect the state of the
/// reader, driver, or card.
/// </summary>
/// <param name="hCard">Reference value returned from SCardConnect.</param>
/// <param name="dwAttrId">
/// <para>
/// Identifier for the attribute to get. The following table lists possible values for <c>dwAttrId</c>. These values are read-only. Note
/// that vendors may not support all attributes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ATTR_ATR_STRING</c></term>
/// <term>Answer to reset (ATR) string.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CHANNEL_ID</c></term>
/// <term><c>DWORD</c> encoded as 0x <c>DDDDCCCC</c>, where <c>DDDD</c> = data channel type and <c>CCCC</c> = channel number:</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CHARACTERISTICS</c></term>
/// <term>
/// <c>DWORD</c> indicating which mechanical characteristics are supported. If zero, no special characteristics are supported. Note that
/// multiple bits can be set: All other values are reserved for future use (RFU).
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_BWT</c></term>
/// <term>Current block waiting time.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_CLK</c></term>
/// <term>Current clock rate, in kHz.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_CWT</c></term>
/// <term>Current character waiting time.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_D</c></term>
/// <term>Bit rate conversion factor.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_EBC_ENCODING</c></term>
/// <term>Current error block control encoding. 0 = longitudinal redundancy check (LRC) 1 = cyclical redundancy check (CRC)</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_F</c></term>
/// <term>Clock conversion factor.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_IFSC</c></term>
/// <term>Current byte size for information field size card.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_IFSD</c></term>
/// <term>Current byte size for information field size device.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_N</c></term>
/// <term>Current guard time.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_PROTOCOL_TYPE</c></term>
/// <term>
/// <c>DWORD</c> encoded as 0x0 <c>rrrpppp</c> where <c>rrr</c> is RFU and should be 0x000. <c>pppp</c> encodes the current protocol
/// type. Whichever bit has been set indicates which ISO protocol is currently in use. (For example, if bit zero is set, T=0 protocol is
/// in effect.)
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_CURRENT_W</c></term>
/// <term>Current work waiting time.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_DEFAULT_CLK</c></term>
/// <term>Default clock rate, in kHz.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_DEFAULT_DATA_RATE</c></term>
/// <term>Default data rate, in bps.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_DEVICE_FRIENDLY_NAME</c></term>
/// <term>Reader's display name.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_DEVICE_IN_USE</c></term>
/// <term>Reserved for future use.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_DEVICE_SYSTEM_NAME</c></term>
/// <term>Reader's system name.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_DEVICE_UNIT</c></term>
/// <term>
/// Instance of this vendor's reader attached to the computer. The first instance will be device unit 0, the next will be unit 1 (if it
/// is the same brand of reader) and so on. Two different brands of readers will both have zero for this value.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_ICC_INTERFACE_STATUS</c></term>
/// <term>Single byte. Zero if smart card electrical contact is not active; nonzero if contact is active.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_ICC_PRESENCE</c></term>
/// <term>
/// Single byte indicating smart card presence: 0 = not present 1 = card present but not swallowed (applies only if reader supports smart
/// card swallowing) 2 = card present (and swallowed if reader supports smart card swallowing) 4 = card confiscated.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_ICC_TYPE_PER_ATR</c></term>
/// <term>Single byte indicating smart card type: 0 = unknown type 1 = 7816 Asynchronous 2 = 7816 Synchronous Other values RFU.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_MAX_CLK</c></term>
/// <term>Maximum clock rate, in kHz.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_MAX_DATA_RATE</c></term>
/// <term>Maximum data rate, in bps.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_MAX_IFSD</c></term>
/// <term>Maximum bytes for information file size device.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_POWER_MGMT_SUPPORT</c></term>
/// <term>Zero if device does not support power down while smart card is inserted. Nonzero otherwise.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_PROTOCOL_TYPES</c></term>
/// <term>
/// <c>DWORD</c> encoded as 0x0 <c>rrrpppp</c> where <c>rrr</c> is RFU and should be 0x000. <c>pppp</c> encodes the supported protocol
/// types. A '1' in a given bit position indicates support for the associated ISO protocol, so if bits zero and one are set, both T=0 and
/// T=1 protocols are supported.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_VENDOR_IFD_SERIAL_NO</c></term>
/// <term>Vendor-supplied interface device serial number.</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_VENDOR_IFD_TYPE</c></term>
/// <term>Vendor-supplied interface device type (model designation of reader).</term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_VENDOR_IFD_VERSION</c></term>
/// <term>
/// Vendor-supplied interface device version ( <c>DWORD</c> in the form 0x <c>MMmmbbbb</c> where <c>MM</c> = major version, <c>mm</c> =
/// minor version, and <c>bbbb</c> = build number).
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_ATTR_VENDOR_NAME</c></term>
/// <term>Vendor name.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbAttr">
/// Pointer to a buffer that receives the attribute whose ID is supplied in <c>dwAttrId</c>. If this value is <c>NULL</c>,
/// <c>SCardGetAttrib</c> ignores the buffer length supplied in <c>pcbAttrLen</c>, writes the length of the buffer that would have been
/// returned if this parameter had not been <c>NULL</c> to <c>pcbAttrLen</c>, and returns a success code.
/// </param>
/// <param name="pcbAttrLen">
/// Length of the <c>pbAttr</c> buffer in bytes, and receives the actual length of the received attribute If the buffer length is
/// specified as SCARD_AUTOALLOCATE, then <c>pbAttr</c> is converted to a pointer to a byte pointer, and receives the address of a block
/// of memory containing the attribute. This block of memory must be deallocated with SCardFreeMemory.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Attribute value not supported.</c></term>
/// <term>ERROR_NOT_SUPPORTED.</term>
/// </item>
/// <item>
/// <term><c>Other Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardGetAttrib</c> function is a direct card access function. For more information on other direct access functions, see
/// Direct Card Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows how to retrieve an attribute for a card reader. The example assumes that hCardHandle is a valid handle
/// obtained from a previous call to the SCardConnect function.
/// </para>
/// <para>
/// <code>LPBYTE pbAttr = NULL; DWORD cByte = SCARD_AUTOALLOCATE; DWORD i; LONG lReturn; lReturn = SCardGetAttrib(hCardHandle, SCARD_ATTR_VENDOR_NAME, (LPBYTE)&amp;pbAttr, &amp;cByte); if ( SCARD_S_SUCCESS != lReturn ) { if ( ERROR_NOT_SUPPORTED == lReturn ) printf("Value not supported\n"); else { // Some other error occurred. printf("Failed SCardGetAttrib - %x\n", lReturn); exit(1); // Or other appropriate action } } else { // Output the bytes. for (i = 0; i &lt; cByte; i++) printf("%c", *(pbAttr+i)); printf("\n"); // Free the memory when done. // hContext was set earlier by SCardEstablishContext lReturn = SCardFreeMemory( hContext, pbAttr ); }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgetattrib LONG SCardGetAttrib( [in] SCARDHANDLE hCard,
// [in] DWORD dwAttrId, [out] LPBYTE pbAttr, [in, out] LPDWORD pcbAttrLen );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetAttrib")]
public static extern SCARD_RET SCardGetAttrib([In] SCARDHANDLE hCard, [In] uint dwAttrId, [Out] IntPtr pbAttr, ref uint pcbAttrLen);
/// <summary>
/// The <c>SCardGetCardTypeProviderName</c> function returns the name of the module (dynamic link library) that contains the provider for
/// a given card name and provider type.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context can be set by a previous call to
/// SCardEstablishContext. This value can be <c>NULL</c> if the call to <c>SCardGetCardTypeProviderName</c> is not directed to a specific context.
/// </param>
/// <param name="szCardName">Name of the card type with which this provider name is associated.</param>
/// <param name="dwProviderId">
/// <para>Identifier for the provider associated with this card type.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_PROVIDER_PRIMARY</c> 1</term>
/// <term>The function retrieves the name of the smart card's primary service provider as a GUID string.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROVIDER_CSP</c> 2</term>
/// <term>The function retrieves the name of the cryptographic service provider.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROVIDER_KSP</c> 3</term>
/// <term>The function retrieves the name of the smart card key storage provider (KSP).</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROVIDER_CARD_MODULE</c> 0x80000001</term>
/// <term>The function retrieves the name of the card module.</term>
/// </item>
/// </list>
/// </param>
/// <param name="szProvider">String variable to receive the provider name upon successful completion of this function.</param>
/// <param name="pcchProvider">
/// <para>
/// Pointer to <c>DWORD</c> value. On input, <c>pcchProvider</c> supplies the length of the <c>szProvider</c> buffer in characters. If
/// this value is SCARD_AUTOALLOCATE, then <c>szProvider</c> is converted to a pointer to a byte pointer and receives the address of a
/// block of memory containing the string. This block of memory must be deallocated by calling SCardFreeMemory.
/// </para>
/// <para>
/// On output, this value represents the actual number of characters, including the <c>null</c> terminator, in the <c>szProvider</c> variable.
/// </para>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when inside a Remote Desktop session will not result in an error. It only
/// means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>
/// Upon successful completion of this function, the value in <c>szProvider</c> can be used as the third parameter in a call to CryptAcquireContext.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows how to retrieve the provider name for the specified reader context. The example assumes that hContext is
/// a valid handle obtained from a previous call to the SCardEstablishContext function.
/// </para>
/// <para>
/// <code>LPTSTR szProvider = NULL; LPTSTR szCardName = _T("WindowsCard"); DWORD chProvider = SCARD_AUTOALLOCATE; LONG lReturn = SCARD_S_SUCCESS; // Retrieve the provider name. // hContext was set by SCardEstablishContext. lReturn = SCardGetCardTypeProviderName(hContext, szCardName, SCARD_PROVIDER_CSP, (LPTSTR)&amp;szProvider, &amp;chProvider); if (SCARD_S_SUCCESS == lReturn) { BOOL fSts = TRUE; HCRYPTPROV hProv = NULL; // Acquire a Cryptographic operation context. fSts = CryptAcquireContext(&amp;hProv, NULL, szProvider, PROV_RSA_FULL, 0); // Perform Cryptographic operations with smart card // ... // Free memory allocated by SCardGetCardTypeProviderName. lReturn = SCardFreeMemory(hContext, szProvider); }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardGetCardTypeProviderName as an alias which automatically selects the ANSI or Unicode version of
/// this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that
/// not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgetcardtypeprovidernamea LONG
// SCardGetCardTypeProviderNameA( [in] SCARDCONTEXT hContext, [in] LPCSTR szCardName, [in] DWORD dwProviderId, [out] CHAR *szProvider,
// [in, out] LPDWORD pcchProvider );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetCardTypeProviderNameA")]
public static extern SCARD_RET SCardGetCardTypeProviderName([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCardName, [In] SCARD_PROVIDER dwProviderId,
[Out] StringBuilder szProvider, ref uint pcchProvider);
/// <summary>
/// The <c>SCardGetDeviceTypeId</c> function gets the device type identifier of the card reader for the given reader name. This function
/// does not affect the state of the reader.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. You can set the resource manager context by calling the
/// SCardEstablishContext function. This parameter cannot be NULL.
/// </param>
/// <param name="szReaderName">Reader name. You can get this value by calling the SCardListReaders function.</param>
/// <param name="pdwDeviceTypeId">
/// The actual device type identifier. The list of reader types returned by this function are listed under <c>ReaderType</c> member in
/// the SCARD_READER_CAPABILITIES structure.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardGetDeviceTypeId as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgetdevicetypeida LONG SCardGetDeviceTypeIdA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szReaderName, [in, out] LPDWORD pdwDeviceTypeId );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetDeviceTypeIdA")]
public static extern SCARD_RET SCardGetDeviceTypeId([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szReaderName, out SCARD_READER_TYPE pdwDeviceTypeId);
/// <summary>
/// <para>The <c>SCardGetProviderId</c> function returns the identifier (GUID) of the primary service provider for a given card.</para>
/// <para>
/// The caller supplies the name of a smart card (previously introduced to the system) and receives the registered identifier of the
/// primary service provider GUID, if one exists.
/// </para>
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to
/// SCardEstablishContext. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szCard">Name of the card defined to the system.</param>
/// <param name="pguidProviderId">
/// Identifier (GUID) of the primary service provider. This provider may be activated using COM, and will supply access to other services
/// in the card.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when inside a Remote Desktop session will not result in an error. It only
/// means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>
/// The <c>SCardGetProviderId</c> function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows how to get the provider ID for the specified card. The example assumes that hContext is a valid handle
/// obtained from a previous call to the SCardEstablishContext function and that "MyCardName" was introduced by a previous call to the
/// SCardIntroduceCardType function.
/// </para>
/// <para>
/// <code>GUID guidProv; LONG lReturn; lReturn = SCardGetProviderId(hContext, L"MyCardName", &amp;guidProv); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardGetProviderId - %x\n", lReturn); else { // Use the provider GUID as needed. // ... }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardGetProviderId as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgetproviderida LONG SCardGetProviderIdA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szCard, [out] LPGUID pguidProviderId );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetProviderIdA")]
public static extern SCARD_RET SCardGetProviderId([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCard, out Guid pguidProviderId);
/// <summary>
/// The <c>SCardGetReaderDeviceInstanceId</c> function gets the device instance identifier of the card reader for the given reader name.
/// This function does not affect the state of the reader.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. You can set the resource manager context by a previous call to the
/// SCardEstablishContext function. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szReaderName">Reader name. You can get this value by calling the SCardListReaders function.</param>
/// <param name="szDeviceInstanceId">
/// Buffer that receives the device instance ID of the reader. If this value is <c>NULL</c>, the function ignores the buffer length
/// supplied in <c>cchDeviceInstanceId</c> parameter, writes the length of the buffer that would have been returned if this parameter had
/// not been <c>NULL</c> to <c>cchDeviceInstanceId</c>, and returns a success code.
/// </param>
/// <param name="pcchDeviceInstanceId">
/// Length, in characters, of the <c>szDeviceInstanceId</c> buffer, including the <c>NULL</c> terminator. If the buffer length is
/// specified as SCARD_AUTOALLOCATE, then the <c>szDeviceInstanceId</c> parameter is converted to a pointer to a byte pointer, and
/// receives the address of a block of memory containing the instance id. This block of memory must be deallocated with the
/// SCardFreeMemory function.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected. Calling the <c>SCardGetReaderDeviceInstanceId</c> function when inside a Remote Desktop session
/// fails with the SCARD_E_READER_UNAVAILABLE error code.
/// </para>
/// <para>Examples</para>
/// <para>
/// <code> LONG lReturn; LPTSTR szReaderName = "USB Smart Card Reader 0"; WCHAR szDeviceInstanceId[256]; DWORD cchDeviceInstanceId = 256; // Retrieve the reader's device instance ID. // hContext was set by a previous call to SCardEstablishContext. lReturn = SCardGetReaderDeviceInstanceId (hContext, szReaderName, szDeviceInstanceId, &amp;cchDeviceInstanceId); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardGetReaderDeviceInstanceId - %x\n", lReturn); // Take appropriate action. }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardGetReaderDeviceInstanceId as an alias which automatically selects the ANSI or Unicode version of
/// this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that
/// not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgetreaderdeviceinstanceida LONG
// SCardGetReaderDeviceInstanceIdA( [in] SCARDCONTEXT hContext, [in] LPCSTR szReaderName, [out, optional] LPSTR szDeviceInstanceId, [in,
// out] LPDWORD pcchDeviceInstanceId );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetReaderDeviceInstanceIdA")]
public static extern SCARD_RET SCardGetReaderDeviceInstanceId([In] SCARDCONTEXT hContext, [In, MarshalAs(UnmanagedType.LPTStr)] string szReaderName,
[Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szDeviceInstanceId, ref uint pcchDeviceInstanceId);
/// <summary>
/// The <c>SCardGetReaderIcon</c> function gets an icon of the smart card reader for a given reader's name. This function does not affect
/// the state of the card reader.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. You can set the resource manager context by a previous call to the
/// SCardEstablishContext function. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szReaderName">Reader name. You can get this value by calling the SCardListReaders function.</param>
/// <param name="pbIcon">
/// Pointer to a buffer that contains a BLOB of the smart card reader icon as read from the icon file. If this value is <c>NULL</c>, the
/// function ignores the buffer length supplied in the <c>pcbIcon</c> parameter, writes the length of the buffer that would have been
/// returned to <c>pcbIcon</c> if this parameter had not been NULL, and returns a success code.
/// </param>
/// <param name="pcbIcon">
/// Length, in characters, of the <c>pbIcon</c> buffer. This parameter receives the actual length of the received attribute. If the
/// buffer length is specified as SCARD_AUTOALLOCATE, then <c>pbIcon</c> is converted from a pointer to a byte pointer and receives the
/// address of a block of memory that contains the attribute. This block of memory must be deallocated with the SCardFreeMemory function.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The icon should be 256 × 256 pixels with no alpha channel.</para>
/// <para>Examples</para>
/// <para>
/// <code>PBYTE pbIcon = NULL; DWORD cbIcon = SCARD_AUTOALLOCATE; DWORD i; LONG lReturn; LPTSTR szReaderName = "USB Smart Card Reader 0"; // Retrieve the reader's icon. // hContext was set by a previous call to SCardEstablishContext. lReturn = SCardGetReaderIcon(hContext, szReaderName, (PBYTE)&amp;pbIcon, &amp;cbIcon); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardGetReaderIcon - %x\n", lReturn); // Take appropriate action. } else { // Free the memory when done. lReturn = SCardFreeMemory(hContext, pbIcon); }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardGetReaderIcon as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgetreadericona LONG SCardGetReaderIconA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szReaderName, [out] LPBYTE pbIcon, [in, out] LPDWORD pcbIcon );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetReaderIconA")]
public static extern SCARD_RET SCardGetReaderIcon([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szReaderName, [Out] IntPtr pbIcon, ref uint pcbIcon);
/// <summary>
/// <para>
/// The <c>SCardGetStatusChange</c> function blocks execution until the current availability of the cards in a specific set of readers changes.
/// </para>
/// <para>
/// The caller supplies a list of readers to be monitored by an SCARD_READERSTATE array and the maximum amount of time (in milliseconds)
/// that it is willing to wait for an action to occur on one of the listed readers. Note that <c>SCardGetStatusChange</c> uses the
/// user-supplied value in the <c>dwCurrentState</c> members of the <c>rgReaderStates</c> SCARD_READERSTATE array as the definition of
/// the current state of the readers. The function returns when there is a change in availability, having filled in the
/// <c>dwEventState</c> members of <c>rgReaderStates</c> appropriately.
/// </para>
/// </summary>
/// <param name="hContext">
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to the
/// SCardEstablishContext function.
/// </param>
/// <param name="dwTimeout">
/// The maximum amount of time, in milliseconds, to wait for an action. A value of zero causes the function to return immediately. A
/// value of INFINITE causes this function never to time out.
/// </param>
/// <param name="rgReaderStates">
/// <para>An array of SCARD_READERSTATE structures that specify the readers to watch, and that receives the result.</para>
/// <para>
/// To be notified of the arrival of a new smart card reader, set the <c>szReader</c> member of a SCARD_READERSTATE structure to
/// "\\?PnP?\Notification", and set all of the other members of that structure to zero.
/// </para>
/// <para>
/// <c>Important</c> Each member of each structure in this array must be initialized to zero and then set to specific values as
/// necessary. If this is not done, the function will fail in situations that involve remote card readers.
/// </para>
/// </param>
/// <param name="cReaders">The number of elements in the <c>rgReaderStates</c> array.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardGetStatusChange</c> function is a smart card tracking function. For more information about other tracking functions, see
/// Smart Card Tracking Functions.
/// </para>
/// <para>Examples</para>
/// <para>For information about how to call this function, see the example in SCardLocateCards.</para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardGetStatusChange as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgetstatuschangea LONG SCardGetStatusChangeA( [in]
// SCARDCONTEXT hContext, [in] DWORD dwTimeout, [in, out] LPSCARD_READERSTATEA rgReaderStates, [in] DWORD cReaders );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetStatusChangeA")]
public static extern SCARD_RET SCardGetStatusChange([In] SCARDCONTEXT hContext, [In] uint dwTimeout,
[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] SCARD_READERSTATE[] rgReaderStates, [In] uint cReaders);
/// <summary>
/// The <c>SCardGetTransmitCount</c> function retrieves the number of transmit operations that have completed since the specified card
/// reader was inserted.
/// </summary>
/// <param name="hCard">A handle to a smart card obtained from a previous call to SCardConnect.</param>
/// <param name="pcTransmitCount">
/// A pointer to the number of transmit operations that have completed since the specified card reader was inserted.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns <c>SCARD_S_SUCCESS</c>.</para>
/// <para>If the function fails, it returns an error code. For more information, see Smart Card Return Values.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgettransmitcount LONG SCardGetTransmitCount( [in]
// SCARDHANDLE hCard, [out] LPDWORD pcTransmitCount );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetTransmitCount")]
public static extern SCARD_RET SCardGetTransmitCount([In] SCARDHANDLE hCard, out uint pcTransmitCount);
/// <summary>
/// The <c>SCardIntroduceCardType</c> function introduces a smart card to the smart card subsystem (for the active user) by adding it to
/// the smart card database.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szCardName">Name by which the user can recognize the card.</param>
/// <param name="pguidPrimaryProvider">Pointer to the identifier (GUID) for the smart card's primary service provider.</param>
/// <param name="rgguidInterfaces">Array of identifiers (GUIDs) that identify the interfaces supported by the smart card.</param>
/// <param name="dwInterfaceCount">Number of identifiers in the <c>rgguidInterfaces</c> array.</param>
/// <param name="pbAtr">
/// ATR string that can be used for matching purposes when querying the smart card database (for more information, see SCardListCards).
/// The length of this string is determined by normal ATR parsing.
/// </param>
/// <param name="pbAtrMask">
/// Optional bitmask to use when comparing the ATRs of smart cards to the ATR supplied in <c>pbAtr</c>. If this value is non-
/// <c>NULL</c>, it must point to a string of bytes the same length as the ATR string supplied in <c>pbAtr</c>. When a given ATR string
/// <c>A</c> is compared to the ATR supplied in <c>pbAtr</c>, it matches if and only if <c>A &amp; M</c> = <c>pbAtr</c>, where <c>M</c>
/// is the supplied mask, and <c>&amp;</c> represents bitwise AND.
/// </param>
/// <param name="cbAtrLen">
/// Length of the ATR and optional ATR mask. If this value is zero, then the length of the ATR is determined by normal ATR parsing. This
/// value cannot be zero if a <c>pbAtr</c> value is supplied.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when inside a Remote Desktop session will not result in an error. It only
/// means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>
/// The <c>SCardIntroduceCardType</c> function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
/// </para>
/// <para>To remove a smart card, use SCardForgetCardType.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows how to introduce a card type. The example assumes that hContext is a valid handle obtained from a
/// previous call to the SCardEstablishContext function.
/// </para>
/// <para>
/// <code>GUID MyGuid = { 0xABCDEF00, 0xABCD, 0xABCD, 0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD }; static const BYTE MyATR[] = { 0xaa, 0xbb, 0xcc, 0x00, 0xdd }; static const BYTE MyATRMask[] = { 0xff, 0xff, 0xff, 0x00, 0xff}; LONG lReturn; lReturn = SCardIntroduceCardType(hContext, L"MyCardName", &amp;MyGuid, NULL, // No interface array 0, // Interface count = 0 MyATR, MyATRMask, sizeof(MyATR)); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardIntroduceCardType\n");</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardIntroduceCardType as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardintroducecardtypea LONG SCardIntroduceCardTypeA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szCardName, [in, optional] LPCGUID pguidPrimaryProvider, [in, optional] LPCGUID rgguidInterfaces,
// [in] DWORD dwInterfaceCount, [in] LPCBYTE pbAtr, [in] LPCBYTE pbAtrMask, [in] DWORD cbAtrLen );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardIntroduceCardTypeA")]
public static extern SCARD_RET SCardIntroduceCardType([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCardName,
in Guid pguidPrimaryProvider, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] Guid[]? rgguidInterfaces,
[In] uint dwInterfaceCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] byte[] pbAtr,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] byte[] pbAtrMask, [In] uint cbAtrLen);
/// <summary>
/// The <c>SCardIntroduceCardType</c> function introduces a smart card to the smart card subsystem (for the active user) by adding it to
/// the smart card database.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szCardName">Name by which the user can recognize the card.</param>
/// <param name="pguidPrimaryProvider">Pointer to the identifier (GUID) for the smart card's primary service provider.</param>
/// <param name="rgguidInterfaces">Array of identifiers (GUIDs) that identify the interfaces supported by the smart card.</param>
/// <param name="dwInterfaceCount">Number of identifiers in the <c>rgguidInterfaces</c> array.</param>
/// <param name="pbAtr">
/// ATR string that can be used for matching purposes when querying the smart card database (for more information, see SCardListCards).
/// The length of this string is determined by normal ATR parsing.
/// </param>
/// <param name="pbAtrMask">
/// Optional bitmask to use when comparing the ATRs of smart cards to the ATR supplied in <c>pbAtr</c>. If this value is non-
/// <c>NULL</c>, it must point to a string of bytes the same length as the ATR string supplied in <c>pbAtr</c>. When a given ATR string
/// <c>A</c> is compared to the ATR supplied in <c>pbAtr</c>, it matches if and only if <c>A &amp; M</c> = <c>pbAtr</c>, where <c>M</c>
/// is the supplied mask, and <c>&amp;</c> represents bitwise AND.
/// </param>
/// <param name="cbAtrLen">
/// Length of the ATR and optional ATR mask. If this value is zero, then the length of the ATR is determined by normal ATR parsing. This
/// value cannot be zero if a <c>pbAtr</c> value is supplied.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when inside a Remote Desktop session will not result in an error. It only
/// means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>
/// The <c>SCardIntroduceCardType</c> function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
/// </para>
/// <para>To remove a smart card, use SCardForgetCardType.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows how to introduce a card type. The example assumes that hContext is a valid handle obtained from a
/// previous call to the SCardEstablishContext function.
/// </para>
/// <para>
/// <code>GUID MyGuid = { 0xABCDEF00, 0xABCD, 0xABCD, 0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD }; static const BYTE MyATR[] = { 0xaa, 0xbb, 0xcc, 0x00, 0xdd }; static const BYTE MyATRMask[] = { 0xff, 0xff, 0xff, 0x00, 0xff}; LONG lReturn; lReturn = SCardIntroduceCardType(hContext, L"MyCardName", &amp;MyGuid, NULL, // No interface array 0, // Interface count = 0 MyATR, MyATRMask, sizeof(MyATR)); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardIntroduceCardType\n");</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardIntroduceCardType as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardintroducecardtypea LONG SCardIntroduceCardTypeA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szCardName, [in, optional] LPCGUID pguidPrimaryProvider, [in, optional] LPCGUID rgguidInterfaces,
// [in] DWORD dwInterfaceCount, [in] LPCBYTE pbAtr, [in] LPCBYTE pbAtrMask, [in] DWORD cbAtrLen );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardIntroduceCardTypeA")]
public static extern SCARD_RET SCardIntroduceCardType([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCardName,
[In, Optional] IntPtr pguidPrimaryProvider, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] Guid[]? rgguidInterfaces,
[In] uint dwInterfaceCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] byte[] pbAtr,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] byte[] pbAtrMask, [In] uint cbAtrLen);
/// <summary>
/// <para>The <c>SCardIntroduceReader</c> function introduces a new name for an existing smart card reader.</para>
/// <para>
/// <c>Note</c> Smart card readers are automatically introduced to the system; a smart card reader vendor's setup program can also
/// introduce a smart card reader to the system.
/// </para>
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szReaderName">Display name to be assigned to the reader.</param>
/// <param name="szDeviceName">System name of the smart card reader, for example, "MyReader 01".</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// All readers installed on the system are automatically introduced by their system name. Typically, <c>SCardIntroduceReader</c> is
/// called only to change the name of an existing reader.
/// </para>
/// <para>
/// The <c>SCardIntroduceReader</c> function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
/// </para>
/// <para>To remove a reader, use SCardForgetReader.</para>
/// <para>Examples</para>
/// <para>The following example shows introducing a smart card reader.</para>
/// <para>
/// <code>// This example renames the reader name. // This is a two-step process (first add the new // name, then forget the old name). LPBYTE pbAttr = NULL; DWORD cByte = SCARD_AUTOALLOCATE; LONG lReturn; // Step 1: Add the new reader name. // The device name attribute is a necessary value. // hCardHandle was set by a previous call to SCardConnect. lReturn = SCardGetAttrib(hCardHandle, SCARD_ATTR_DEVICE_SYSTEM_NAME, (LPBYTE)&amp;pbAttr, &amp;cByte); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardGetAttrib\n"); exit(1); // Or other error action } // Add the reader name. // hContext was set earlier by SCardEstablishContext. lReturn = SCardIntroduceReader(hContext, TEXT("My New Reader Name"), (LPCTSTR)pbAttr ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardIntroduceReader\n"); exit(1); // Or other error action } // Step 2: Forget the old reader name. lReturn = SCardForgetReader(hContext, (LPCTSTR)pbAttr ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardForgetReader\n"); exit(1); // Or other error action } // Free the memory when done. lReturn = SCardFreeMemory( hContext, pbAttr );</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardIntroduceReader as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardintroducereadera LONG SCardIntroduceReaderA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szReaderName, [in] LPCSTR szDeviceName );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardIntroduceReaderA")]
public static extern SCARD_RET SCardIntroduceReader([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szReaderName, [MarshalAs(UnmanagedType.LPTStr)] string szDeviceName);
/// <summary>
/// The <c>SCardIntroduceReaderGroup</c> function introduces a reader group to the smart card subsystem. However, the reader group is not
/// created until the group is specified when adding a reader to the smart card database.
/// </summary>
/// <param name="hContext">
/// Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to the
/// SCardEstablishContext function. If this parameter is <c>NULL</c>, the scope of the resource manager is SCARD_SCOPE_SYSTEM.
/// </param>
/// <param name="szGroupName">
/// <para>Supplies the display name to be assigned to the new reader group.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ALL_READERS</c> TEXT("SCard$AllReaders\000")</term>
/// <term>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_DEFAULT_READERS</c> TEXT("SCard$DefaultReaders\000")</term>
/// <term>Default group to which all readers are added when introduced into the system.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LOCAL_READERS</c> TEXT("SCard$LocalReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_SYSTEM_READERS</c> TEXT("SCard$SystemReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardIntroduceReaderGroup</c> function is provided for PC/SC specification compatibility. Reader groups are not stored until a
/// reader is added to the group.
/// </para>
/// <para>
/// The <c>SCardIntroduceReaderGroup</c> function is a database management function. For a description of other database management
/// functions, see Smart Card Database Management Functions.
/// </para>
/// <para>To remove a reader group, use SCardForgetReaderGroup.</para>
/// <para>Examples</para>
/// <para>The following example shows introducing a smart card reader group.</para>
/// <para>
/// <code>// Introduce the reader group. // lReturn is of type LONG. // hContext was set by a previous call to SCardEstablishContext. lReturn = SCardIntroduceReaderGroup(hContext, L"MyReaderGroup"); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardIntroduceReaderGroup\n");</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardIntroduceReaderGroup as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardintroducereadergroupa LONG SCardIntroduceReaderGroupA(
// [in] SCARDCONTEXT hContext, [in] LPCSTR szGroupName );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardIntroduceReaderGroupA")]
public static extern SCARD_RET SCardIntroduceReaderGroup([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szGroupName);
/// <summary>The <c>SCardIsValidContext</c> function determines whether a smart card context handle is valid.</summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context can be set by a previous call to SCardEstablishContext.
/// </param>
/// <returns>
/// <para>This function returns one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_S_SUCCESS</c></term>
/// <term>The <c>hContext</c> parameter is valid.</term>
/// </item>
/// <item>
/// <term><c>ERROR_INVALID_HANDLE</c></term>
/// <term>The <c>hContext</c> parameter is not valid.</term>
/// </item>
/// <item>
/// <term><c>Other values</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Call this function to determine whether a smart card context handle is still valid. After a smart card context handle has been set by
/// SCardEstablishContext, it may become not valid if the resource manager service has been shut down.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows determining whether a smart card context handle is valid.</para>
/// <para>
/// <code>// Check the smart card context handle. // hContext was set previously by SCardEstablishContext. LONG lReturn; lReturn = SCardIsValidContext(hContext); if ( SCARD_S_SUCCESS != lReturn ) { // Function failed; check return value. if ( ERROR_INVALID_HANDLE == lReturn ) printf("Handle is invalid\n"); else { // Some unexpected error occurred; report and bail out. printf("Failed SCardIsValidContext - %x\n", lReturn); exit(1); // Or other appropriate error action. } } else { // Handle is valid; proceed as needed. // ... }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardisvalidcontext LONG SCardIsValidContext( [in]
// SCARDCONTEXT hContext );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardIsValidContext")]
public static extern SCARD_RET SCardIsValidContext([In] SCARDCONTEXT hContext);
/// <summary>
/// <para>
/// The <c>SCardListCards</c> function searches the smart card database and provides a list of named cards previously introduced to the
/// system by the user.
/// </para>
/// <para>
/// The caller specifies an ATR string, a set of interface identifiers (GUIDs), or both. If both an ATR string and an identifier array
/// are supplied, the cards returned will match the ATR string supplied and support the interfaces specified.
/// </para>
/// </summary>
/// <param name="hContext">
/// <para>
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
/// </para>
/// <para>If this parameter is set to <c>NULL</c>, the search for cards is not limited to any context.</para>
/// </param>
/// <param name="pbAtr">Address of an ATR string to compare to known cards, or <c>NULL</c> if no ATR matching is to be performed.</param>
/// <param name="rgquidInterfaces">
/// Array of identifiers (GUIDs), or <c>NULL</c> if no interface matching is to be performed. When an array is supplied, a card name will
/// be returned only if all the specified identifiers are supported by the card.
/// </param>
/// <param name="cguidInterfaceCount">
/// Number of entries in the <c>rgguidInterfaces</c> array. If <c>rgguidInterfaces</c> is <c>NULL</c>, then this value is ignored.
/// </param>
/// <param name="mszCards">
/// Multi-string that lists the smart cards found. If this value is <c>NULL</c>, <c>SCardListCards</c> ignores the buffer length supplied
/// in <c>pcchCards</c>, returning the length of the buffer that would have been returned if this parameter had not been <c>NULL</c> to
/// <c>pcchCards</c> and a success code.
/// </param>
/// <param name="pcchCards">
/// Length of the <c>mszCards</c> buffer in characters. Receives the actual length of the multi-string structure, including all trailing
/// <c>null</c> characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then <c>mszCards</c> is converted to a pointer to a
/// byte pointer, and receives the address of a block of memory containing the multi-string structure. This block of memory must be
/// deallocated with SCardFreeMemory.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when inside a Remote Desktop session will not result in an error. It only
/// means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>To return all smart cards introduced to the subsystem, set <c>pbAtr</c> and <c>rgguidInterfaces</c> to <c>NULL</c>.</para>
/// <para>
/// The <c>SCardListCards</c> function is a database query function. For more information on other database query functions, see Smart
/// Card Database Query Functions.
/// </para>
/// <para>
/// Calling this function should be done outside of a transaction. If an application begins a transaction with the SCardBeginTransaction
/// function and then calls this function, it resets the <c>hCard</c> parameter (of type <c>SCARDHANDLE</c>) of the
/// <c>SCardBeginTransaction</c> function.
/// </para>
/// <para>
/// <c>Windows Server 2008 R2 and Windows 7:</c> Calling this function within a transaction could result in your computer becoming unresponsive.
/// </para>
/// <para><c>Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> Not applicable.</para>
/// <para>Examples</para>
/// <para>The following example shows listing of the smart cards.</para>
/// <para>
/// <code>LPTSTR pmszCards = NULL; LPTSTR pCard; LONG lReturn; DWORD cch = SCARD_AUTOALLOCATE; // Retrieve the list of cards. lReturn = SCardListCards(NULL, NULL, NULL, NULL, (LPTSTR)&amp;pmszCards, &amp;cch ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardListCards\n"); exit(1); // Or other appropriate error action } // Do something with the multi string of cards. // Output the values. // A double-null terminates the list of values. pCard = pmszCards; while ( '\0' != *pCard ) { // Display the value. printf("%S\n", pCard ); // Advance to the next value. pCard = pCard + wcslen(pCard) + 1; } // Remember to free pmszCards (by calling SCardFreeMemory). // ...</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardListCards as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardlistcardsa LONG SCardListCardsA( [in] SCARDCONTEXT
// hContext, [in, optional] LPCBYTE pbAtr, [in] LPCGUID rgquidInterfaces, [in] DWORD cguidInterfaceCount, [out] CHAR *mszCards, [in, out]
// LPDWORD pcchCards );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListCardsA")]
public static extern SCARD_RET SCardListCards([In] SCARDCONTEXT hContext, [In, Optional, MarshalAs(UnmanagedType.LPArray)] byte[]? pbAtr,
[In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] Guid[]? rgquidInterfaces, [In] uint cguidInterfaceCount,
[Out] IntPtr mszCards, ref uint pcchCards);
/// <summary>
/// <para>
/// The <c>SCardListCards</c> function searches the smart card database and provides a list of named cards previously introduced to the
/// system by the user.
/// </para>
/// <para>
/// The caller specifies an ATR string, a set of interface identifiers (GUIDs), or both. If both an ATR string and an identifier array
/// are supplied, the cards returned will match the ATR string supplied and support the interfaces specified.
/// </para>
/// </summary>
/// <param name="hContext">
/// <para>
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
/// </para>
/// <para>If this parameter is set to <c>NULL</c>, the search for cards is not limited to any context.</para>
/// </param>
/// <param name="pbAtr">Address of an ATR string to compare to known cards, or <c>NULL</c> if no ATR matching is to be performed.</param>
/// <param name="rgquidInterfaces">
/// Array of identifiers (GUIDs), or <c>NULL</c> if no interface matching is to be performed. When an array is supplied, a card name will
/// be returned only if all the specified identifiers are supported by the card.
/// </param>
/// <param name="mszCards">
/// Multi-string that lists the smart cards found. If this value is <c>NULL</c>, <c>SCardListCards</c> ignores the buffer length supplied
/// in <c>pcchCards</c>, returning the length of the buffer that would have been returned if this parameter had not been <c>NULL</c> to
/// <c>pcchCards</c> and a success code.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when inside a Remote Desktop session will not result in an error. It only
/// means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>To return all smart cards introduced to the subsystem, set <c>pbAtr</c> and <c>rgguidInterfaces</c> to <c>NULL</c>.</para>
/// <para>
/// The <c>SCardListCards</c> function is a database query function. For more information on other database query functions, see Smart
/// Card Database Query Functions.
/// </para>
/// <para>
/// Calling this function should be done outside of a transaction. If an application begins a transaction with the SCardBeginTransaction
/// function and then calls this function, it resets the <c>hCard</c> parameter (of type <c>SCARDHANDLE</c>) of the
/// <c>SCardBeginTransaction</c> function.
/// </para>
/// <para>
/// <c>Windows Server 2008 R2 and Windows 7:</c> Calling this function within a transaction could result in your computer becoming unresponsive.
/// </para>
/// <para><c>Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> Not applicable.</para>
/// </remarks>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListCardsA")]
public static SCARD_RET SCardListCards(SCARDCONTEXT hContext, [Optional] byte[]? pbAtr, [Optional] Guid[]? rgquidInterfaces, out string[] mszCards) =>
ListSCardFunc((IntPtr p, ref uint c) => SCardListCards(hContext, pbAtr, rgquidInterfaces, (uint)(rgquidInterfaces?.Length ?? 0), p, ref c), out mszCards);
/// <summary>
/// <para>The <c>SCardListInterfaces</c> function provides a list of interfaces supplied by a given card.</para>
/// <para>
/// The caller supplies the name of a smart card previously introduced to the subsystem, and receives the list of interfaces supported by
/// the card.
/// </para>
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to
/// SCardEstablishContext. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szCard">Name of the smart card already introduced to the smart card subsystem.</param>
/// <param name="pguidInterfaces">
/// Array of interface identifiers (GUIDs) that indicate the interfaces supported by the smart card. If this value is <c>NULL</c>,
/// <c>SCardListInterfaces</c> ignores the array length supplied in <c>pcguidInterfaces</c>, returning the size of the array that would
/// have been returned if this parameter had not been <c>NULL</c> to <c>pcguidInterfaces</c> and a success code.
/// </param>
/// <param name="pcguidInterfaces">
/// Size of the <c>pcguidInterfaces</c> array, and receives the actual size of the returned array. If the array size is specified as
/// SCARD_AUTOALLOCATE, then <c>pcguidInterfaces</c> is converted to a pointer to a GUID pointer, and receives the address of a block of
/// memory containing the array. This block of memory must be deallocated with SCardFreeMemory.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when attempting a Remote Desktop session will not result in an error. It
/// only means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>
/// The <c>SCardListInterfaces</c> function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows listing the interfaces for a smart card.</para>
/// <para>
/// <code>LPGUID pGuids = NULL; LONG lReturn; DWORD cGuid = SCARD_AUTOALLOCATE; // Retrieve the list of interfaces. lReturn = SCardListInterfaces(NULL, (LPCSTR) "MyCard", (LPGUID)&amp;pGuids, &amp;cGuid ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardListInterfaces\n"); exit(1); // Or other appropriate action } if ( 0 != cGuid ) { // Do something with the array of Guids. // Remember to free pGuids when done (by SCardFreeMemory). // ... }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardListInterfaces as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardlistinterfacesa LONG SCardListInterfacesA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szCard, [out] LPGUID pguidInterfaces, [in, out] LPDWORD pcguidInterfaces );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListInterfacesA")]
public static extern SCARD_RET SCardListInterfaces([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCard,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] Guid[] pguidInterfaces, ref uint pcguidInterfaces);
/// <summary>
/// <para>The <c>SCardListInterfaces</c> function provides a list of interfaces supplied by a given card.</para>
/// <para>
/// The caller supplies the name of a smart card previously introduced to the subsystem, and receives the list of interfaces supported by
/// the card.
/// </para>
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to
/// SCardEstablishContext. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szCard">Name of the smart card already introduced to the smart card subsystem.</param>
/// <param name="pguidInterfaces">
/// Array of interface identifiers (GUIDs) that indicate the interfaces supported by the smart card. If this value is <c>NULL</c>,
/// <c>SCardListInterfaces</c> ignores the array length supplied in <c>pcguidInterfaces</c>, returning the size of the array that would
/// have been returned if this parameter had not been <c>NULL</c> to <c>pcguidInterfaces</c> and a success code.
/// </param>
/// <param name="pcguidInterfaces">
/// Size of the <c>pcguidInterfaces</c> array, and receives the actual size of the returned array. If the array size is specified as
/// SCARD_AUTOALLOCATE, then <c>pcguidInterfaces</c> is converted to a pointer to a GUID pointer, and receives the address of a block of
/// memory containing the array. This block of memory must be deallocated with SCardFreeMemory.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when attempting a Remote Desktop session will not result in an error. It
/// only means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>
/// The <c>SCardListInterfaces</c> function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows listing the interfaces for a smart card.</para>
/// <para>
/// <code>LPGUID pGuids = NULL; LONG lReturn; DWORD cGuid = SCARD_AUTOALLOCATE; // Retrieve the list of interfaces. lReturn = SCardListInterfaces(NULL, (LPCSTR) "MyCard", (LPGUID)&amp;pGuids, &amp;cGuid ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardListInterfaces\n"); exit(1); // Or other appropriate action } if ( 0 != cGuid ) { // Do something with the array of Guids. // Remember to free pGuids when done (by SCardFreeMemory). // ... }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardListInterfaces as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardlistinterfacesa LONG SCardListInterfacesA( [in]
// SCARDCONTEXT hContext, [in] LPCSTR szCard, [out] LPGUID pguidInterfaces, [in, out] LPDWORD pcguidInterfaces );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListInterfacesA")]
public static extern SCARD_RET SCardListInterfaces([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCard,
[Out] IntPtr pguidInterfaces, ref uint pcguidInterfaces);
/// <summary>
/// <para>The <c>SCardListInterfaces</c> function provides a list of interfaces supplied by a given card.</para>
/// <para>
/// The caller supplies the name of a smart card previously introduced to the subsystem, and receives the list of interfaces supported by
/// the card.
/// </para>
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to
/// SCardEstablishContext. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szCard">Name of the smart card already introduced to the smart card subsystem.</param>
/// <param name="pguidInterfaces">Array of interface identifiers (GUIDs) that indicate the interfaces supported by the smart card.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when attempting a Remote Desktop session will not result in an error. It
/// only means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>
/// The <c>SCardListInterfaces</c> function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
/// </para>
/// </remarks>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListInterfacesA")]
public static SCARD_RET SCardListInterfaces([In] SCARDCONTEXT hContext, string szCard, out Guid[] pguidInterfaces) =>
ListSCardFunc((IntPtr p, ref uint c) => SCardListInterfaces(hContext, szCard, p, ref c), out pguidInterfaces);
/// <summary>
/// The <c>SCardListReaderGroups</c> function provides the list of reader groups that have previously been introduced to the system.
/// </summary>
/// <param name="hContext">
/// <para>
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
/// </para>
/// <para>If this parameter is set to <c>NULL</c>, the search for reader groups is not limited to any context.</para>
/// </param>
/// <param name="mszGroups">
/// <para>
/// Multi-string that lists the reader groups defined to the system and available to the current user on the current terminal. If this
/// value is <c>NULL</c>, <c>SCardListReaderGroups</c> ignores the buffer length supplied in <c>pcchGroups</c>, writes the length of the
/// buffer that would have been returned if this parameter had not been <c>NULL</c> to <c>pcchGroups</c>, and returns a success code.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ALL_READERS</c> TEXT("SCard$AllReaders\000")</term>
/// <term>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_DEFAULT_READERS</c> TEXT("SCard$DefaultReaders\000")</term>
/// <term>Default group to which all readers are added when introduced into the system.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LOCAL_READERS</c> TEXT("SCard$LocalReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_SYSTEM_READERS</c> TEXT("SCard$SystemReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pcchGroups">
/// Length of the <c>mszGroups</c> buffer in characters, and receives the actual length of the multi-string structure, including all
/// trailing <c>null</c> characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then <c>mszGroups</c> is converted to a
/// pointer to a byte pointer, and receives the address of a block of memory containing the multi-string structure. This block of memory
/// must be deallocated with SCardFreeMemory.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// A group is returned only if it contains at least one reader. This includes the group SCard$DefaultReaders. The group SCard$AllReaders
/// cannot be returned, since it only exists implicitly.
/// </para>
/// <para>
/// The <c>SCardListReaderGroups</c> function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows listing the reader groups.</para>
/// <para>
/// <code>LPTSTR pmszReaderGroups = NULL; LPTSTR pReaderGroup; LONG lReturn; DWORD cch = SCARD_AUTOALLOCATE; // Retrieve the list the reader groups. // hSC was set by a previous call to SCardEstablishContext. lReturn = SCardListReaderGroups(hSC, (LPTSTR)&amp;pmszReaderGroups, &amp;cch ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardListReaderGroups\n"); else { // Do something with the multi string of reader groups. // Output the values. // A double-null terminates the list of values. pReaderGroup = pmszReaderGroups; while ( '\0' != *pReaderGroup ) { // Display the value. printf("%S\n", pReaderGroup ); // Advance to the next value. pReaderGroup = pReaderGroup + wcslen((wchar_t *) pReaderGroup) + 1; } // Remember to free pmszReaderGroups by a call to SCardFreeMemory. // ... }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardListReaderGroups as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardlistreadergroupsa LONG SCardListReaderGroupsA( [in]
// SCARDCONTEXT hContext, [out] LPSTR mszGroups, [in, out] LPDWORD pcchGroups );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListReaderGroupsA")]
public static extern SCARD_RET SCardListReaderGroups([In, Optional] SCARDCONTEXT hContext, [Out] IntPtr mszGroups, ref uint pcchGroups);
/// <summary>
/// The <c>SCardListReaderGroups</c> function provides the list of reader groups that have previously been introduced to the system.
/// </summary>
/// <param name="hContext">
/// <para>
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
/// </para>
/// <para>If this parameter is set to <c>NULL</c>, the search for reader groups is not limited to any context.</para>
/// </param>
/// <param name="mszGroups">
/// <para>String array that lists the reader groups defined to the system and available to the current user on the current terminal.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ALL_READERS</c> TEXT("SCard$AllReaders\000")</term>
/// <term>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_DEFAULT_READERS</c> TEXT("SCard$DefaultReaders\000")</term>
/// <term>Default group to which all readers are added when introduced into the system.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LOCAL_READERS</c> TEXT("SCard$LocalReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_SYSTEM_READERS</c> TEXT("SCard$SystemReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// A group is returned only if it contains at least one reader. This includes the group SCard$DefaultReaders. The group SCard$AllReaders
/// cannot be returned, since it only exists implicitly.
/// </para>
/// <para>
/// The <c>SCardListReaderGroups</c> function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
/// </para>
/// </remarks>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListReaderGroupsA")]
public static SCARD_RET SCardListReaderGroups([In, Optional] SCARDCONTEXT hContext, out string[] mszGroups) =>
ListSCardFunc((IntPtr p, ref uint c) => SCardListReaderGroups(hContext, p, ref c), out mszGroups);
/// <summary>
/// <para>The <c>SCardListReaders</c> function provides the list of readers within a set of named reader groups, eliminating duplicates.</para>
/// <para>
/// The caller supplies a list of reader groups, and receives the list of readers within the named groups. Unrecognized group names are
/// ignored. This function only returns readers within the named groups that are currently attached to the system and available for use.
/// </para>
/// </summary>
/// <param name="hContext">
/// <para>
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
/// </para>
/// <para>If this parameter is set to <c>NULL</c>, the search for readers is not limited to any context.</para>
/// </param>
/// <param name="mszGroups">
/// <para>
/// Names of the reader groups defined to the system, as a multi-string. Use a <c>NULL</c> value to list all readers in the system (that
/// is, the SCard$AllReaders group).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ALL_READERS</c> TEXT("SCard$AllReaders\000")</term>
/// <term>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_DEFAULT_READERS</c> TEXT("SCard$DefaultReaders\000")</term>
/// <term>Default group to which all readers are added when introduced into the system.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LOCAL_READERS</c> TEXT("SCard$LocalReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_SYSTEM_READERS</c> TEXT("SCard$SystemReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="mszReaders">
/// Multi-string that lists the card readers within the supplied reader groups. If this value is <c>NULL</c>, <c>SCardListReaders</c>
/// ignores the buffer length supplied in <c>pcchReaders</c>, writes the length of the buffer that would have been returned if this
/// parameter had not been <c>NULL</c> to <c>pcchReaders</c>, and returns a success code.
/// </param>
/// <param name="pcchReaders">
/// Length of the <c>mszReaders</c> buffer in characters. This parameter receives the actual length of the multi-string structure,
/// including all trailing <c>null</c> characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then <c>mszReaders</c> is
/// converted to a pointer to a byte pointer, and receives the address of a block of memory containing the multi-string structure. This
/// block of memory must be deallocated with SCardFreeMemory.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code/value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c> 0 (0x0)</term>
/// <term>SCARD_S_SUCCESS</term>
/// </item>
/// <item>
/// <term><c>Group contains no readers</c> 2148532270 (0x8010002E)</term>
/// <term>SCARD_E_NO_READERS_AVAILABLE</term>
/// </item>
/// <item>
/// <term><c>Specified reader is not currently available for use</c> 2148532247 (0x80100017)</term>
/// <term>SCARD_E_READER_UNAVAILABLE</term>
/// </item>
/// <item>
/// <term><c>Other</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardListReaders</c> function is a database query function. For more information on other database query functions, see Smart
/// Card Database Query Functions.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows listing the readers.</para>
/// <para>
/// <code>LPTSTR pmszReaders = NULL; LPTSTR pReader; LONG lReturn, lReturn2; DWORD cch = SCARD_AUTOALLOCATE; // Retrieve the list the readers. // hSC was set by a previous call to SCardEstablishContext. lReturn = SCardListReaders(hSC, NULL, (LPTSTR)&amp;pmszReaders, &amp;cch ); switch( lReturn ) { case SCARD_E_NO_READERS_AVAILABLE: printf("Reader is not in groups.\n"); // Take appropriate action. // ... break; case SCARD_S_SUCCESS: // Do something with the multi string of readers. // Output the values. // A double-null terminates the list of values. pReader = pmszReaders; while ( '\0' != *pReader ) { // Display the value. printf("Reader: %S\n", pReader ); // Advance to the next value. pReader = pReader + wcslen((wchar_t *)pReader) + 1; } // Free the memory. lReturn2 = SCardFreeMemory( hSC, pmszReaders ); if ( SCARD_S_SUCCESS != lReturn2 ) printf("Failed SCardFreeMemory\n"); break; default: printf("Failed SCardListReaders\n"); // Take appropriate action. // ... break; }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardListReaders as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardlistreadersa LONG SCardListReadersA( [in] SCARDCONTEXT
// hContext, [in, optional] LPCSTR mszGroups, [out] LPSTR mszReaders, [in, out] LPDWORD pcchReaders );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListReadersA")]
public static extern SCARD_RET SCardListReaders([In, Optional] SCARDCONTEXT hContext,
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[]? mszGroups,
[Out] IntPtr mszReaders, ref uint pcchReaders);
/// <summary>
/// <para>The <c>SCardListReaders</c> function provides the list of readers within a set of named reader groups, eliminating duplicates.</para>
/// <para>
/// The caller supplies a list of reader groups, and receives the list of readers within the named groups. Unrecognized group names are
/// ignored. This function only returns readers within the named groups that are currently attached to the system and available for use.
/// </para>
/// </summary>
/// <param name="hContext">
/// <para>
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
/// </para>
/// <para>If this parameter is set to <c>NULL</c>, the search for readers is not limited to any context.</para>
/// </param>
/// <param name="mszGroups">
/// <para>
/// Names of the reader groups defined to the system, as a string array. Use a <c>NULL</c> value to list all readers in the system (that
/// is, the SCard$AllReaders group).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ALL_READERS</c> TEXT("SCard$AllReaders\000")</term>
/// <term>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_DEFAULT_READERS</c> TEXT("SCard$DefaultReaders\000")</term>
/// <term>Default group to which all readers are added when introduced into the system.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LOCAL_READERS</c> TEXT("SCard$LocalReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_SYSTEM_READERS</c> TEXT("SCard$SystemReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="mszReaders">String array that lists the card readers within the supplied reader groups.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code/value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c> 0 (0x0)</term>
/// <term>SCARD_S_SUCCESS</term>
/// </item>
/// <item>
/// <term><c>Group contains no readers</c> 2148532270 (0x8010002E)</term>
/// <term>SCARD_E_NO_READERS_AVAILABLE</term>
/// </item>
/// <item>
/// <term><c>Specified reader is not currently available for use</c> 2148532247 (0x80100017)</term>
/// <term>SCARD_E_READER_UNAVAILABLE</term>
/// </item>
/// <item>
/// <term><c>Other</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardListReaders</c> function is a database query function. For more information on other database query functions, see Smart
/// Card Database Query Functions.
/// </para>
/// </remarks>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListReadersA")]
public static SCARD_RET SCardListReaders([In, Optional] SCARDCONTEXT hContext, [In, Optional] string[]? mszGroups, out string[]? mszReaders) =>
ListSCardFunc((IntPtr p, ref uint c) => SCardListReaders(hContext, mszGroups, p, ref c), out mszReaders);
/// <summary>
/// The <c>SCardListReadersWithDeviceInstanceId</c> function gets the list of readers that have provided a device instance identifier.
/// This function does not affect the state of the reader.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. You can set the resource manager context by a previous call to the
/// SCardEstablishContext function. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szDeviceInstanceId">
/// Device instance ID of the reader. You can get this value by calling the SCardGetReaderDeviceInstanceId function with the reader name
/// or by calling the SetupDiGetDeviceInstanceId function from the DDK.
/// </param>
/// <param name="mszReaders">
/// A multi-string that contain the smart card readers within the supplied device instance identifier. If this value is <c>NULL</c>, then
/// the function ignores the buffer length supplied in the <c>pcchReaders</c> parameter, writes the length of the buffer that would have
/// been returned if this parameter had not been <c>NULL</c> to <c>pcchReaders</c>, and returns a success code.
/// </param>
/// <param name="pcchReaders">
/// The length, in characters, of the <c>mszReaders</c> buffer. This parameter receives the actual length of the multiple-string
/// structure, including all terminating null characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then <c>mszReaders</c>
/// is converted to a pointer to a byte pointer, and receives the address of a block of memory that contains the multiple-string
/// structure. When you have finished using this memory, deallocated it by using the SCardFreeMemory function.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected. Calling the <c>SCardListReadersWithDeviceInstanceId</c> function when inside a Remote Desktop
/// session fails with the SCARD_E_READER_UNAVAILABLE error code.
/// </para>
/// <para>Examples</para>
/// <para>
/// <code> szDeviceInstanceIdcchReaderNameLONG lReturn, lReturn2; LPTSTR pmszReaders = NULL; LPTSTR pReader = NULL;WCHAR DWORD cchReaderName = SCARD_AUTOALLOCATE; // Retrieve the reader’s name from it’s device instance ID // hContext was set by a previous call to SCardEstablishContext. // szDeviceInstanceId was obtained by calling SetupDiGetDeviceInstanceId lReturn = SCardListReadersWithDeviceInstanceId (hContext, szDeviceInstanceId, (LPTSTR)&amp;pmszReaders, &amp;cchReaderName); switch( lReturn ) { case SCARD_E_NO_READERS_AVAILABLE: printf("No readers have the provided device instance ID.\n"); // Take appropriate action. // ... break; case SCARD_S_SUCCESS: // Do something with the multi string of readers. // Output the values. // A double-null terminates the list of values. pReader = pmszReaders; while ( '\0' != *pReader ) { // Display the value. printf("Reader: %S\n", pReader ); // Advance to the next value. pReader = pReader + wcslen((wchar_t *)pReader) + 1; } // Free the memory. lReturn2 = SCardFreeMemory( hContext, pmszReaders ); if ( SCARD_S_SUCCESS != lReturn2 ) printf("Failed SCardFreeMemory\n"); break; default: printf("Failed SCardListReaders\n"); // Take appropriate action. // ... break;</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardListReadersWithDeviceInstanceId as an alias which automatically selects the ANSI or Unicode
/// version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias
/// with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see
/// Conventions for Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardlistreaderswithdeviceinstanceida LONG
// SCardListReadersWithDeviceInstanceIdA( [in] SCARDCONTEXT hContext, [in] LPCSTR szDeviceInstanceId, [out, optional] LPSTR mszReaders,
// [in, out] LPDWORD pcchReaders );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListReadersWithDeviceInstanceIdA")]
public static extern SCARD_RET SCardListReadersWithDeviceInstanceId([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szDeviceInstanceId, [Out, Optional] IntPtr mszReaders, ref uint pcchReaders);
/// <summary>
/// The <c>SCardListReadersWithDeviceInstanceId</c> function gets the list of readers that have provided a device instance identifier.
/// This function does not affect the state of the reader.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context for the query. You can set the resource manager context by a previous call to the
/// SCardEstablishContext function. This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szDeviceInstanceId">
/// Device instance ID of the reader. You can get this value by calling the SCardGetReaderDeviceInstanceId function with the reader name
/// or by calling the SetupDiGetDeviceInstanceId function from the DDK.
/// </param>
/// <param name="mszReaders">A string array that contain the smart card readers within the supplied device instance identifier.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected. Calling the <c>SCardListReadersWithDeviceInstanceId</c> function when inside a Remote Desktop
/// session fails with the SCARD_E_READER_UNAVAILABLE error code.
/// </para>
/// </remarks>
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListReadersWithDeviceInstanceIdA")]
public static SCARD_RET SCardListReadersWithDeviceInstanceId([In] SCARDCONTEXT hContext, string szDeviceInstanceId, out string[] mszReaders) =>
ListSCardFunc((IntPtr p, ref uint c) => SCardListReadersWithDeviceInstanceId(hContext, szDeviceInstanceId, p, ref c), out mszReaders);
/// <summary>
/// The <c>SCardLocateCards</c> function searches the readers listed in the <c>rgReaderStates</c> parameter for a card with an ATR string
/// that matches one of the card names specified in <c>mszCards</c>, returning immediately with the result.
/// </summary>
/// <param name="hContext">
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// </param>
/// <param name="mszCards">A multiple string that contains the names of the cards to search for.</param>
/// <param name="rgReaderStates">
/// An array of SCARD_READERSTATE structures that, on input, specify the readers to search and that, on output, receives the result.
/// </param>
/// <param name="cReaders">The number of elements in the <c>rgReaderStates</c> array.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This service is especially useful when used in conjunction with SCardGetStatusChange. If no matching cards are found by means of
/// <c>SCardLocateCards</c>, the calling application may use <c>SCardGetStatusChange</c> to wait for card availability changes.
/// </para>
/// <para>
/// The <c>SCardLocateCards</c> function is a smart card tracking function. For more information on other tracking functions, see Smart
/// Card Tracking Functions.
/// </para>
/// <para>
/// Calling this function should be done outside of a transaction. If an application begins a transaction with the SCardBeginTransaction
/// function and then calls this function, it resets the <c>hCard</c> parameter (of type <c>SCARDHANDLE</c>) of the
/// <c>SCardBeginTransaction</c> function.
/// </para>
/// <para>
/// <c>Windows Server 2008 R2 and Windows 7:</c> Calling this function within a transaction could result in your computer becoming unresponsive.
/// </para>
/// <para><c>Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:</c> Not applicable.</para>
/// <para>Examples</para>
/// <para>The following example shows locating smart cards.</para>
/// <para>
/// <code>// Copyright (C) Microsoft. All rights reserved. #include &lt;stdio.h&gt; #include &lt;winscard.h&gt; #include &lt;tchar.h&gt; #pragma comment(lib, "winscard.lib") HRESULT __cdecl main() { HRESULT hr = S_OK; LPTSTR szReaders, szRdr; DWORD cchReaders = SCARD_AUTOALLOCATE; DWORD dwI, dwRdrCount; SCARD_READERSTATE rgscState[MAXIMUM_SMARTCARD_READERS]; TCHAR szCard[MAX_PATH]; SCARDCONTEXT hSC; LONG lReturn; // Establish the card to watch for. // Multiple cards can be looked for, but // this sample looks for only one card. _tcscat_s ( szCard, MAX_PATH * sizeof(TCHAR), TEXT("GemSAFE")); szCard[lstrlen(szCard) + 1] = 0; // Double trailing zero. // Establish a context. lReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &amp;hSC ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardEstablishContext\n"); exit(1); } // Determine which readers are available. lReturn = SCardListReaders(hSC, NULL, (LPTSTR)&amp;szReaders, &amp;cchReaders ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardListReaders\n"); exit(1); } // Place the readers into the state array. szRdr = szReaders; for ( dwI = 0; dwI &lt; MAXIMUM_SMARTCARD_READERS; dwI++ ) { if ( 0 == *szRdr ) break; rgscState[dwI].szReader = szRdr; rgscState[dwI].dwCurrentState = SCARD_STATE_UNAWARE; szRdr += lstrlen(szRdr) + 1; } dwRdrCount = dwI; // If any readers are available, proceed. if ( 0 != dwRdrCount ) { for (;;) { // Look for the card. lReturn = SCardLocateCards(hSC, szCard, rgscState, dwRdrCount ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardLocateCards\n"); exit(1); } // Look through the array of readers. for ( dwI=0; dwI &lt; dwRdrCount; dwI++) { if ( 0 != ( SCARD_STATE_ATRMATCH &amp; rgscState[dwI].dwEventState)) { _tprintf( TEXT("Card '%s' found in reader '%s'.\n"), szCard, rgscState[dwI].szReader ); SCardFreeMemory( hSC, szReaders ); return 0; // Context will be release automatically. } // Update the state. rgscState[dwI].dwCurrentState = rgscState[dwI].dwEventState; } // Card not found yet; wait until there is a change. lReturn = SCardGetStatusChange(hSC, INFINITE, // infinite wait rgscState, dwRdrCount ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardGetStatusChange\n"); exit(1); } } // for (;;) } else printf("No readers available\n"); // Release the context. lReturn = SCardReleaseContext(hSC); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardReleaseContext\n"); exit(1); } SCardFreeMemory( hSC, szReaders ); return hr; }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardLocateCards as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardlocatecardsa LONG SCardLocateCardsA( [in] SCARDCONTEXT
// hContext, [in] LPCSTR mszCards, [in, out] LPSCARD_READERSTATEA rgReaderStates, [in] DWORD cReaders );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardLocateCardsA")]
public static extern SCARD_RET SCardLocateCards([In] SCARDCONTEXT hContext, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[] mszCards,
[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] SCARD_READERSTATE[] rgReaderStates, [In] uint cReaders);
/// <summary>
/// The <c>SCardLocateCardsByATR</c> function searches the readers listed in the <c>rgReaderStates</c> parameter for a card with a name
/// that matches one of the card names contained in one of the SCARD_ATRMASK structures specified by the <c>rgAtrMasks</c> parameter.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// </param>
/// <param name="rgAtrMasks">Array of SCARD_ATRMASK structures that contain the names of the cards for which to search.</param>
/// <param name="cAtrs">Number of elements in the <c>rgAtrMasks</c> array.</param>
/// <param name="rgReaderStates">Array of SCARD_READERSTATE structures that specify the readers to search, and receive the result.</param>
/// <param name="cReaders">Number of elements in the <c>rgReaderStates</c> array.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>Error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This service is especially useful when used in conjunction with SCardGetStatusChange. If no matching cards are found by means of
/// SCardLocateCards, the calling application may use <c>SCardGetStatusChange</c> to wait for card availability changes.
/// </para>
/// <para>
/// The <c>SCardLocateCardsByATR</c> function is a smart card tracking function. For information about other tracking functions, see
/// Smart Card Tracking Functions.
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardLocateCardsByATR as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardlocatecardsbyatra LONG SCardLocateCardsByATRA( [in]
// SCARDCONTEXT hContext, [in] LPSCARD_ATRMASK rgAtrMasks, [in] DWORD cAtrs, [in, out] LPSCARD_READERSTATEA rgReaderStates, [in] DWORD
// cReaders );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardLocateCardsByATRA")]
public static extern SCARD_RET SCardLocateCardsByATR([In] SCARDCONTEXT hContext, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] SCARD_ATRMASK[] rgAtrMasks,
[In] uint cAtrs, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] SCARD_READERSTATE[] rgReaderStates, [In] uint cReaders);
/// <summary>
/// The <c>SCardReadCache</c> function retrieves the value portion of a name-value pair from the global cache maintained by the Smart
/// Card Resource Manager.
/// </summary>
/// <param name="hContext">
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// </param>
/// <param name="CardIdentifier">
/// A pointer to a value that uniquely identifies a smart card. The name-value pair that this function reads from the global cache is
/// associated with this smart card.
/// </param>
/// <param name="FreshnessCounter">The current revision of the cached data.</param>
/// <param name="LookupName">
/// A pointer to a null-terminated string that contains the name portion of the name-value pair for which to retrieve the value portion.
/// </param>
/// <param name="Data">
/// A pointer to an array of byte values that contain the value portion of the name-value pair specified by the <c>LookupName</c> parameter.
/// </param>
/// <param name="DataLen">A pointer to the size, in bytes, of the <c>Data</c> buffer.</param>
/// <returns>
/// <para>If the function succeeds, it returns <c>SCARD_S_SUCCESS</c>.</para>
/// <para>If the function fails, it returns one of the following error codes. For more information, see Smart Card Return Values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code/value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_W_CACHE_ITEM_NOT_FOUND</c> 0x80100070</term>
/// <term>The specified name-value pair was not found in the global cache.</term>
/// </item>
/// <item>
/// <term><c>SCARD_W_CACHE_ITEM_STALE</c> 0x80100071</term>
/// <term>The specified name-value pair was older than requested and has been deleted from the cache.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardReadCache as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardreadcachea LONG SCardReadCacheA( [in] SCARDCONTEXT
// hContext, [in] UUID *CardIdentifier, [in] DWORD FreshnessCounter, [in] LPSTR LookupName, [out] PBYTE Data, [out] DWORD *DataLen );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardReadCacheA")]
public static extern SCARD_RET SCardReadCache([In] SCARDCONTEXT hContext, in Guid CardIdentifier, [In] uint FreshnessCounter,
[In] SafeLPTSTR LookupName, [Out] IntPtr Data, out uint DataLen);
/// <summary>
/// The <c>SCardReconnect</c> function reestablishes an existing connection between the calling application and a smart card. This
/// function moves a card handle from direct access to general access, or acknowledges and clears an error condition that is preventing
/// further access to the card.
/// </summary>
/// <param name="hCard">Reference value obtained from a previous call to SCardConnect.</param>
/// <param name="dwShareMode">
/// <para>Flag that indicates whether other applications may form connections to this card.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_SHARE_SHARED</c></term>
/// <term>This application will share this card with other applications.</term>
/// </item>
/// <item>
/// <term><c>SCARD_SHARE_EXCLUSIVE</c></term>
/// <term>This application will not share this card with other applications.</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwPreferredProtocols">
/// <para>Bitmask of acceptable protocols for this connection. Possible values may be combined with the <c>OR</c> operation.</para>
/// <para>
/// The value of this parameter should include the current protocol. Attempting to reconnect with a protocol other than the current
/// protocol will result in an error.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_PROTOCOL_T0</c></term>
/// <term>T=0 is an acceptable protocol.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROTOCOL_T1</c></term>
/// <term>T=1 is an acceptable protocol.</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwInitialization">
/// <para>Type of initialization that should be performed on the card.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_LEAVE_CARD</c></term>
/// <term>Do not do anything special on reconnect.</term>
/// </item>
/// <item>
/// <term><c>SCARD_RESET_CARD</c></term>
/// <term>Reset the card (Warm Reset).</term>
/// </item>
/// <item>
/// <term><c>SCARD_UNPOWER_CARD</c></term>
/// <term>Power down the card and reset it (Cold Reset).</term>
/// </item>
/// </list>
/// </param>
/// <param name="pdwActiveProtocol">
/// <para>Flag that indicates the established active protocol.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_PROTOCOL_T0</c></term>
/// <term>T=0 is the active protocol.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROTOCOL_T1</c></term>
/// <term>T=1 is the active protocol.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>SCardReconnect</c> is a smart card and reader access function. For information about other access functions, see Smart Card and
/// Reader Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows reestablishing a connection.</para>
/// <para>
/// <code>DWORD dwAP; LONG lReturn; // Reconnect. // hCardHandle was set by a previous call to SCardConnect. lReturn = SCardReconnect(hCardHandle, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_LEAVE_CARD, &amp;dwAP ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardReconnect\n");</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardreconnect LONG SCardReconnect( [in] SCARDHANDLE hCard,
// [in] DWORD dwShareMode, [in] DWORD dwPreferredProtocols, [in] DWORD dwInitialization, [out, optional] LPDWORD pdwActiveProtocol );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardReconnect")]
public static extern SCARD_RET SCardReconnect([In] SCARDHANDLE hCard, [In] SCARD_SHARE dwShareMode, [In] SCARD_PROTOCOL dwPreferredProtocols,
[In] SCARD_ACTION dwInitialization, out SCARD_PROTOCOL pdwActiveProtocol);
/// <summary>
/// The <c>SCardReleaseContext</c> function closes an established resource manager context, freeing any resources allocated under that
/// context, including SCARDHANDLE objects and memory allocated using the SCARD_AUTOALLOCATE length designator.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardreleasecontext LONG SCardReleaseContext( [in]
// SCARDCONTEXT hContext );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardReleaseContext")]
public static extern SCARD_RET SCardReleaseContext([In] SCARDCONTEXT hContext);
/// <summary>
/// The <c>SCardReleaseStartedEvent</c> function decrements the reference count for a handle acquired by a previous call to the
/// SCardAccessStartedEvent function.
/// </summary>
/// <returns>None</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardreleasestartedevent void SCardReleaseStartedEvent();
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardReleaseStartedEvent")]
public static extern void SCardReleaseStartedEvent();
/// <summary>
/// The <c>SCardRemoveReaderFromGroup</c> function removes a reader from an existing reader group. This function has no effect on the reader.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be <c>NULL</c>.
/// </param>
/// <param name="szReaderName">Display name of the reader to be removed.</param>
/// <param name="szGroupName">
/// <para>Display name of the group from which the reader should be removed.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ALL_READERS</c> TEXT("SCard$AllReaders\000")</term>
/// <term>
/// Group used when no group name is provided when listing readers. Returns a list of all readers, regardless of what group or groups the
/// readers are in.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_DEFAULT_READERS</c> TEXT("SCard$DefaultReaders\000")</term>
/// <term>Default group to which all readers are added when introduced into the system.</term>
/// </item>
/// <item>
/// <term><c>SCARD_LOCAL_READERS</c> TEXT("SCard$LocalReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_SYSTEM_READERS</c> TEXT("SCard$SystemReaders\000")</term>
/// <term>
/// Unused legacy value. This is an internally managed group that cannot be modified by using any reader group APIs. It is intended to be
/// used for enumeration only.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>When the last reader is removed from a group, the group is automatically forgotten.</para>
/// <para>
/// The <c>SCardRemoveReaderFromGroup</c> function is a database management function. For information about other database management
/// functions, see Smart Card Database Management Functions.
/// </para>
/// <para>To add a reader to a reader group, use SCardAddReaderToGroup.</para>
/// <para>Examples</para>
/// <para>The following example shows how to remove a reader from the group.</para>
/// <para>
/// <code>// Remove a reader from the group. // lReturn is of type LONG. // hContext was set by a previous call to SCardEstablishContext. // The group is automatically forgotten if no readers remain in it. lReturn = SCardRemoveReaderFromGroup(hContext, L"MyReader", L"MyReaderGroup"); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardRemoveReaderFromGroup\n");</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardRemoveReaderFromGroup as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardremovereaderfromgroupa LONG SCardRemoveReaderFromGroupA(
// [in] SCARDCONTEXT hContext, [in] LPCSTR szReaderName, [in] LPCSTR szGroupName );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardRemoveReaderFromGroupA")]
public static extern SCARD_RET SCardRemoveReaderFromGroup([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szReaderName, [MarshalAs(UnmanagedType.LPTStr)] string szGroupName);
/// <summary>
/// The <c>SCardSetAttrib</c> function sets the given reader attribute for the given handle. It does not affect the state of the reader,
/// reader driver, or smart card. Not all attributes are supported by all readers (nor can they be set at all times) as many of the
/// attributes are under direct control of the transport protocol.
/// </summary>
/// <param name="hCard">Reference value returned from SCardConnect.</param>
/// <param name="dwAttrId">
/// <para>Identifier for the attribute to set. The values are write-only. Note that vendors may not support all attributes.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ATTR_SUPRESS_T1_IFS_REQUEST</c></term>
/// <term>
/// Suppress sending of T=1 IFSD packet from the reader to the card. (Can be used if the currently inserted card does not support an IFSD request.)
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pbAttr">Pointer to a buffer that supplies the attribute whose ID is supplied in <c>dwAttrId</c>.</param>
/// <param name="cbAttrLen">Length (in bytes) of the attribute value in the <c>pbAttr</c> buffer.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardSetAttrib</c> function is a direct card access function. For information about other direct access functions, see Direct
/// Card Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows how to set an attribute.</para>
/// <para>
/// <code>// Set the attribute. // hCardHandle was set by a previous call to SCardConnect. // dwAttrID is a DWORD value, specifying the attribute ID. // pbAttr points to the buffer of the new value. // cByte is the count of bytes in the buffer. lReturn = SCardSetAttrib(hCardHandle, dwAttrID, (LPBYTE)pbAttr, cByte); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardSetAttrib\n");</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardsetattrib LONG SCardSetAttrib( [in] SCARDHANDLE hCard,
// [in] DWORD dwAttrId, [in] LPCBYTE pbAttr, [in] DWORD cbAttrLen );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardSetAttrib")]
public static extern SCARD_RET SCardSetAttrib([In] SCARDHANDLE hCard, [In] uint dwAttrId, [In] IntPtr pbAttr, [In] uint cbAttrLen);
/// <summary>
/// The <c>SCardSetCardTypeProviderName</c> function specifies the name of the module (dynamic link library) containing the provider for
/// a given card name and provider type.
/// </summary>
/// <param name="hContext">
/// Handle that identifies the resource manager context. The resource manager context can be set by a previous call to
/// SCardEstablishContext. This value can be <c>NULL</c> if the call to <c>SCardSetCardTypeProviderName</c> is not directed to a specific context.
/// </param>
/// <param name="szCardName">Name of the card type with which this provider name is associated.</param>
/// <param name="dwProviderId">
/// <para>Identifier for the provider associated with this card type.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_PROVIDER_PRIMARY</c> 1</term>
/// <term>The function retrieves the name of the smart card's primary service provider as a GUID string.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROVIDER_CSP</c> 2</term>
/// <term>The function retrieves the name of the cryptographic service provider (CSP).</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROVIDER_KSP</c> 3</term>
/// <term>The function retrieves the name of the smart card key storage provider (KSP).</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROVIDER_CARD_MODULE</c> 0x80000001</term>
/// <term>The function retrieves the name of the card module.</term>
/// </item>
/// </list>
/// </param>
/// <param name="szProvider">A string that contains the provider name that is representing the CSP.</param>
/// <returns>
/// <para>This function returns different values depending on whether it succeeds or fails.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>Success</c></term>
/// <term>SCARD_S_SUCCESS.</term>
/// </item>
/// <item>
/// <term><c>Failure</c></term>
/// <term>An error code. For more information, see Smart Card Return Values.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function is not redirected, but calling the function when inside a Remote Desktop session will not result in an error. It only
/// means that the result will be from the remote computer instead of the local computer.
/// </para>
/// <para>This function sets the provider name, while SCardGetCardTypeProviderName can be used to retrieve the provider name.</para>
/// <para>Examples</para>
/// <para>The following example shows how to specify the card type provider name.</para>
/// <para>
/// <code>LPTSTR szNewProvName = _T("My Provider Name"); LPTSTR szCardName = _T("WindowsCard"); LONG lReturn = SCARD_S_SUCCESS; // Set the card type provider name. // hContext was set by SCardEstablishContext. lReturn = SCardSetCardTypeProviderName(hContext, szCardName, SCARD_PROVIDER_CSP, szNewProvName); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardSetCardTypeProviderName - %x\n", lReturn); exit(1); }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardSetCardTypeProviderName as an alias which automatically selects the ANSI or Unicode version of
/// this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that
/// not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardsetcardtypeprovidernamea LONG
// SCardSetCardTypeProviderNameA( [in] SCARDCONTEXT hContext, [in] LPCSTR szCardName, [in] DWORD dwProviderId, [in] LPCSTR szProvider );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardSetCardTypeProviderNameA")]
public static extern SCARD_RET SCardSetCardTypeProviderName([In] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCardName, [In] SCARD_PROVIDER dwProviderId,
[MarshalAs(UnmanagedType.LPTStr)] string szProvider);
/// <summary>
/// The <c>SCardStatus</c> function provides the current status of a smart card in a reader. You can call it any time after a successful
/// call to SCardConnect and before a successful call to SCardDisconnect. It does not affect the state of the reader or reader driver.
/// </summary>
/// <param name="hCard">Reference value returned from SCardConnect.</param>
/// <param name="mszReaderNames">List of display names (multiple string) by which the currently connected reader is known.</param>
/// <param name="pcchReaderLen">
/// <para>On input, supplies the length of the <c>szReaderName</c> buffer.</para>
/// <para>
/// On output, receives the actual length (in characters) of the reader name list, including the trailing <c>NULL</c> character. If this
/// buffer length is specified as SCARD_AUTOALLOCATE, then <c>szReaderName</c> is converted to a pointer to a byte pointer, and it
/// receives the address of a block of memory that contains the multiple-string structure.
/// </para>
/// </param>
/// <param name="pdwState">
/// <para>Current state of the smart card in the reader. Upon success, it receives one of the following state indicators.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_ABSENT</c></term>
/// <term>There is no card in the reader.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PRESENT</c></term>
/// <term>There is a card in the reader, but it has not been moved into position for use.</term>
/// </item>
/// <item>
/// <term><c>SCARD_SWALLOWED</c></term>
/// <term>There is a card in the reader in position for use. The card is not powered.</term>
/// </item>
/// <item>
/// <term><c>SCARD_POWERED</c></term>
/// <term>Power is being provided to the card, but the reader driver is unaware of the mode of the card.</term>
/// </item>
/// <item>
/// <term><c>SCARD_NEGOTIABLE</c></term>
/// <term>The card has been reset and is awaiting PTS negotiation.</term>
/// </item>
/// <item>
/// <term><c>SCARD_SPECIFIC</c></term>
/// <term>The card has been reset and specific communication protocols have been established.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pdwProtocol">
/// <para>Current protocol, if any. The returned value is meaningful only if the returned value of <c>pdwState</c> is SCARD_SPECIFICMODE.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_PROTOCOL_RAW</c></term>
/// <term>The Raw Transfer protocol is in use.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROTOCOL_T0</c></term>
/// <term>The ISO 7816/3 T=0 protocol is in use.</term>
/// </item>
/// <item>
/// <term><c>SCARD_PROTOCOL_T1</c></term>
/// <term>The ISO 7816/3 T=1 protocol is in use.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbAtr">Pointer to a 32-byte buffer that receives the ATR string from the currently inserted card, if available.</param>
/// <param name="pcbAtrLen">
/// On input, supplies the length of the <c>pbAtr</c> buffer. On output, receives the number of bytes in the ATR string (32 bytes
/// maximum). If this buffer length is specified as SCARD_AUTOALLOCATE, then <c>pbAtr</c> is converted to a pointer to a byte pointer,
/// and it receives the address of a block of memory that contains the multiple-string structure.
/// </param>
/// <returns>
/// <para>If the function successfully provides the current status of a smart card in a reader, the return value is SCARD_S_SUCCESS.</para>
/// <para>If the function fails, it returns an error code. For more information, see Smart Card Return Values.</para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardStatus</c> function is a smart card and reader access function. For information about other access functions, see Smart
/// Card and Reader Access Functions.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows how to determine the state of the smart card.</para>
/// <para>
/// <code>WCHAR szReader[200]; DWORD cch = 200; BYTE bAttr[32]; DWORD cByte = 32; DWORD dwState, dwProtocol; LONG lReturn; // Determine the status. // hCardHandle was set by an earlier call to SCardConnect. lReturn = SCardStatus(hCardHandle, szReader, &amp;cch, &amp;dwState, &amp;dwProtocol, (LPBYTE)&amp;bAttr, &amp;cByte); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardStatus\n"); exit(1); // or other appropriate action } // Examine retrieved status elements. // Look at the reader name and card state. printf("%S\n", szReader ); switch ( dwState ) { case SCARD_ABSENT: printf("Card absent.\n"); break; case SCARD_PRESENT: printf("Card present.\n"); break; case SCARD_SWALLOWED: printf("Card swallowed.\n"); break; case SCARD_POWERED: printf("Card has power.\n"); break; case SCARD_NEGOTIABLE: printf("Card reset and waiting PTS negotiation.\n"); break; case SCARD_SPECIFIC: printf("Card has specific communication protocols set.\n"); break; default: printf("Unknown or unexpected card state.\n"); break; }</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardStatus as an alias which automatically selects the ANSI or Unicode version of this function based
/// on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardstatusa LONG SCardStatusA( [in] SCARDHANDLE hCard, [out]
// LPSTR mszReaderNames, [in, out, optional] LPDWORD pcchReaderLen, [out, optional] LPDWORD pdwState, [out, optional] LPDWORD
// pdwProtocol, [out] LPBYTE pbAtr, [in, out, optional] LPDWORD pcbAtrLen );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardStatusA")]
public static extern SCARD_RET SCardStatus([In] SCARDHANDLE hCard, [Out][MarshalAs(UnmanagedType.LPTStr)] StringBuilder mszReaderNames, ref uint pcchReaderLen,
out uint pdwState, out SCARD_PROTOCOL pdwProtocol, [Out] IntPtr pbAtr, ref uint pcbAtrLen);
/// <summary>
/// The <c>SCardTransmit</c> function sends a service request to the smart card and expects to receive data back from the card.
/// </summary>
/// <param name="hCard">A reference value returned from the SCardConnect function.</param>
/// <param name="pioSendPci">
/// <para>
/// A pointer to the protocol header structure for the instruction. This buffer is in the format of an SCARD_IO_REQUEST structure,
/// followed by the specific protocol control information (PCI).
/// </para>
/// <para>
/// For the T=0, T=1, and Raw protocols, the PCI structure is constant. The smart card subsystem supplies a global T=0, T=1, or Raw PCI
/// structure, which you can reference by using the symbols SCARD_PCI_T0, SCARD_PCI_T1, and SCARD_PCI_RAW respectively.
/// </para>
/// </param>
/// <param name="pbSendBuffer">
/// <para>A pointer to the actual data to be written to the card.</para>
/// <para>For T=0, the data parameters are placed into the address pointed to by <c>pbSendBuffer</c> according to the following structure:</para>
/// <para>
/// The data sent to the card should immediately follow the send buffer. In the special case where no data is sent to the card and no
/// data is expected in return, <c>bP3</c> is not sent.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Member</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c><c>bCla</c></c></term>
/// <term>The T=0 instruction class.</term>
/// </item>
/// <item>
/// <term><c><c>bIns</c></c></term>
/// <term>An instruction code in the T=0 instruction class.</term>
/// </item>
/// <item>
/// <term><c><c>bP1</c>, <c>bP2</c></c></term>
/// <term>Reference codes that complete the instruction code.</term>
/// </item>
/// <item>
/// <term><c><c>bP3</c></c></term>
/// <term>The number of data bytes to be transmitted during the command, per ISO 7816-4, Section 8.2.1.</term>
/// </item>
/// </list>
/// </param>
/// <param name="cbSendLength">
/// <para>The length, in bytes, of the <c>pbSendBuffer</c> parameter.</para>
/// <para>
/// For T=0, in the special case where no data is sent to the card and no data expected in return, this length must reflect that the
/// <c>bP3</c> member is not being sent; the length should be
/// <code>sizeof(CmdBytes) - sizeof(BYTE)</code>
/// .
/// </para>
/// </param>
/// <param name="pioRecvPci">
/// Pointer to the protocol header structure for the instruction, followed by a buffer in which to receive any returned protocol control
/// information (PCI) specific to the protocol in use. This parameter can be <c>NULL</c> if no PCI is returned.
/// </param>
/// <param name="pbRecvBuffer">
/// <para>Pointer to any data returned from the card.</para>
/// <para>
/// For T=0, the data is immediately followed by the SW1 and SW2 status bytes. If no data is returned from the card, then this buffer
/// will only contain the SW1 and SW2 status bytes.
/// </para>
/// </param>
/// <param name="pcbRecvLength">
/// <para>
/// Supplies the length, in bytes, of the <c>pbRecvBuffer</c> parameter and receives the actual number of bytes received from the smart card.
/// </para>
/// <para>This value cannot be SCARD_AUTOALLOCATE because <c>SCardTransmit</c> does not support SCARD_AUTOALLOCATE.</para>
/// <para>For T=0, the receive buffer must be at least two bytes long to receive the SW1 and SW2 status bytes.</para>
/// </param>
/// <returns>
/// <para>If the function successfully sends a service request to the smart card, the return value is SCARD_S_SUCCESS.</para>
/// <para>If the function fails, it returns an error code. For more information, see Smart Card Return Values.</para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardTransmit</c> function is a smart card and reader access function. For information about other access functions, see Smart
/// Card and Reader Access Functions.
/// </para>
/// <para>
/// For the T=0 protocol, the data received back are the SW1 and SW2 status codes, possibly preceded by response data. The following
/// paragraphs provide information about the send and receive buffers used to transfer data and issue a command.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows sending a service request to the smart card.</para>
/// <para>
/// <code>// Transmit the request. // lReturn is of type LONG. // hCardHandle was set by a previous call to SCardConnect. // pbSend points to the buffer of bytes to send. // dwSend is the DWORD value for the number of bytes to send. // pbRecv points to the buffer for returned bytes. // dwRecv is the DWORD value for the number of returned bytes. lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T0, pbSend, dwSend, NULL, pbRecv, &amp;dwRecv ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardTransmit\n"); exit(1); // or other appropriate error action }</code>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardtransmit LONG SCardTransmit( [in] SCARDHANDLE hCard, [in]
// LPCSCARD_IO_REQUEST pioSendPci, [in] LPCBYTE pbSendBuffer, [in] DWORD cbSendLength, [in, out, optional] LPSCARD_IO_REQUEST pioRecvPci,
// [out] LPBYTE pbRecvBuffer, [in, out] LPDWORD pcbRecvLength );
[DllImport(Lib_Winscard, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardTransmit")]
public static extern SCARD_RET SCardTransmit([In] SCARDHANDLE hCard, [In] SafeCoTaskMemStruct<SCARD_IO_REQUEST> pioSendPci, [In] IntPtr pbSendBuffer, [In] uint cbSendLength,
[In, Out, Optional] SafeCoTaskMemStruct<SCARD_IO_REQUEST> pioRecvPci, [Out] IntPtr pbRecvBuffer, ref uint pcbRecvLength);
/// <summary>The <c>SCardUIDlgSelectCard</c> function displays the smart card <c>Select Card</c> dialog box.</summary>
/// <param name="unnamedParam1">Pointer to the OPENCARDNAME_EX structure for the <c>Select Card</c> dialog box.</param>
/// <returns>
/// <para>If the function successfully displays the <c>Select Card</c> dialog box, the return value is SCARD_S_SUCCESS.</para>
/// <para>If the function fails, it returns an error code. For more information, see Smart Card Return Values.</para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>SCardUIDlgSelectCard</c> function provides a method for connecting to a specific smart card. When called, this function
/// performs a search for appropriate smart cards matching the OPENCARD_SEARCH_CRITERIA member specified by the <c>pDlgStruc</c>
/// parameter. Depending on the <c>dwFlags</c> member of <c>pDlgStruc</c>, this function takes the following actions.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Action</term>
/// </listheader>
/// <item>
/// <term>SC_DLG_FORCE_UI</term>
/// <term>Connects to the card selected by the user from the smart card <c>Select Card</c> dialog box.</term>
/// </item>
/// <item>
/// <term>SC_DLG_MINIMAL_UI</term>
/// <term>
/// Selects the smart card if only one smart card meets the criteria, or returns information about the user's selection if more than one
/// smart card meets the criteria.
/// </term>
/// </item>
/// <item>
/// <term>SC_DLG_NO_UI</term>
/// <term>Selects the first available card.</term>
/// </item>
/// </list>
/// <para>
/// This function replaces GetOpenCardName. The <c>GetOpenCardName</c> function is maintained for backward compatibility with version 1.0
/// of the Microsoft Smart Card Base Components.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows how to display the smart card <c>Select Card</c> dialog box.</para>
/// <para>
/// <code>SCARDCONTEXT hSC; OPENCARDNAME_EX dlgStruct; WCHAR szReader[256]; WCHAR szCard[256]; LONG lReturn; // Establish a context. // It will be assigned to the structure's hSCardContext field. lReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &amp;hSC ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardEstablishContext\n"); exit(1); } // Initialize the structure. memset(&amp;dlgStruct, 0, sizeof(dlgStruct)); dlgStruct.dwStructSize = sizeof(dlgStruct); dlgStruct.hSCardContext = hSC; dlgStruct.dwFlags = SC_DLG_FORCE_UI; dlgStruct.lpstrRdr = (LPSTR) szReader; dlgStruct.nMaxRdr = 256; dlgStruct.lpstrCard = (LPSTR) szCard; dlgStruct.nMaxCard = 256; dlgStruct.lpstrTitle = (LPSTR) "My Select Card Title"; // Display the select card dialog box. lReturn = SCardUIDlgSelectCard(&amp;dlgStruct); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardUIDlgSelectCard - %x\n", lReturn ); else printf("Reader: %S\nCard: %S\n", szReader, szCard ); // Release the context (by SCardReleaseContext - not shown here).</code>
/// </para>
/// <para>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardUIDlgSelectCard as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scarduidlgselectcarda LONG SCardUIDlgSelectCardA( [in]
// LPOPENCARDNAMEA_EX unnamedParam1 );
[DllImport(Lib_Scarddlg, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardUIDlgSelectCardA")]
public static extern SCARD_RET SCardUIDlgSelectCard(in OPENCARDNAME_EX unnamedParam1);
/// <summary>
/// The <c>SCardWriteCache</c> function writes a name-value pair from a smart card to the global cache maintained by the Smart Card
/// Resource Manager.
/// </summary>
/// <param name="hContext">
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// </param>
/// <param name="CardIdentifier">A pointer to a value that uniquely identifies the smart card from which the name-value pair was read.</param>
/// <param name="FreshnessCounter">The current revision of the cached data.</param>
/// <param name="LookupName">
/// A pointer to a null-terminated string that contains the name portion of the name-value pair to write to the global cache.
/// </param>
/// <param name="Data">
/// A pointer to an array of byte values that contain the value portion of the name-value pair to write to the global cache.
/// </param>
/// <param name="DataLen">The size, in bytes, of the <c>Data</c> buffer.</param>
/// <returns>
/// <para>If the function succeeds, it returns <c>SCARD_S_SUCCESS</c>.</para>
/// <para>If the function fails, it returns one of the following error codes. For more information, see Smart Card Return Values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code/value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_W_CACHE_ITEM_TOO_BIG</c> 0x80100072</term>
/// <term>The size of the specified name-value pair exceeds the maximum size defined for the global cache.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCardWriteCache as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardwritecachea LONG SCardWriteCacheA( [in] SCARDCONTEXT
// hContext, [in] UUID *CardIdentifier, [in] DWORD FreshnessCounter, [in] LPSTR LookupName, [in] PBYTE Data, [in] DWORD DataLen );
[DllImport(Lib_Winscard, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardWriteCacheA")]
public static extern SCARD_RET SCardWriteCache([In] SCARDCONTEXT hContext, in Guid CardIdentifier, [In] uint FreshnessCounter,
[MarshalAs(UnmanagedType.LPTStr)] string LookupName, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)] byte[] Data, [In] uint DataLen);
private static SCARD_RET ListSCardFunc<T>(SCardListCardsDelegate d, out T[] msz)
{
msz = new T[0];
uint cch = 0;
SCARD_RET ret = d(default, ref cch);
if (ret.Failed) return ret;
using SafeCoTaskMemHandle ptr = new(Len(cch));
ret = d(ptr, ref cch);
if (ret.Succeeded)
msz = typeof(T) == typeof(string) ? (T[])(object)ptr.ToStringEnum().ToArray() : ptr.ToArray<T>((int)cch);
return ret;
static int Len(uint cch) => typeof(T) == typeof(string) ? (1 + (int)cch) * Marshal.SystemDefaultCharSize : InteropExtensions.SizeOf<T>() * cch;
}
/// <summary>
/// The <c>OPENCARD_SEARCH_CRITERIA</c> structure is used by the SCardUIDlgSelectCard function in order to recognize cards that meet the
/// requirements set forth by the caller. You can, however, call <c>SCardUIDlgSelectCard</c> without using this structure.
/// </summary>
/// <remarks>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines OPENCARD_SEARCH_CRITERIA as an alias which automatically selects the ANSI or Unicode version of this
/// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/ns-winscard-opencard_search_criteriaa typedef struct { DWORD dwStructSize;
// LPSTR lpstrGroupNames; DWORD nMaxGroupNames; LPCGUID rgguidInterfaces; DWORD cguidInterfaces; LPSTR lpstrCardNames; DWORD
// nMaxCardNames; LPOCNCHKPROC lpfnCheck; LPOCNCONNPROCA lpfnConnect; LPOCNDSCPROC lpfnDisconnect; LPVOID pvUserData; DWORD dwShareMode;
// DWORD dwPreferredProtocols; } OPENCARD_SEARCH_CRITERIAA, *POPENCARD_SEARCH_CRITERIAA, *LPOPENCARD_SEARCH_CRITERIAA;
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.__unnamed_struct_2")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct OPENCARD_SEARCH_CRITERIA
{
/// <summary>The length, in bytes, of the structure. Must not be <c>NULL</c>.</summary>
public uint dwStructSize;
/// <summary>
/// A pointer to a buffer containing null-terminated group name strings. The last string in the buffer must be terminated by two null
/// characters. Each string is the name of a group of cards that is to be included in the search. If <c>lpstrGroupNames</c> is
/// <c>NULL</c>, the default group (Scard$DefaultReaders) is searched.
/// </summary>
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")]
public string[] lpstrGroupNames;
/// <summary>The maximum number of bytes (ANSI version) or characters (Unicode version) in the <c>lpstrGroupNames</c> string.</summary>
public uint nMaxGroupNames;
/// <summary>Reserved for future use. An array of GUIDs that identifies the interfaces required. Set this member to <c>NULL</c>.</summary>
public IntPtr rgguidInterfaces;
/// <summary>Reserved for future use. The number of interfaces in the <c>rgguidInterfaces</c> array. Set this member to <c>NULL</c>.</summary>
public uint cguidInterfaces;
/// <summary>
/// A pointer to a buffer that contains null-terminated card name strings. The last string in the buffer must be terminated by two
/// null characters. Each string is the name of a card that is to be located.
/// </summary>
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")]
public string[] lpstrCardNames;
/// <summary>The maximum number of bytes (ANSI version) or characters (Unicode version) in the <c>lpstrGroupNames</c> string.</summary>
public uint nMaxCardNames;
/// <summary>
/// <para>
/// A pointer to the caller's card verify routine. If no special card verification is required, this pointer is <c>NULL</c>. If the
/// card is rejected by the verify routine, <c>FALSE</c> is returned, and the card will be disconnected. If the card is accepted by
/// the verify routine, <c>TRUE</c> is returned.
/// </para>
/// </summary>
[MarshalAs(UnmanagedType.FunctionPtr)]
public LPOCNCHKPROC lpfnCheck;
/// <summary>
/// <para>
/// A pointer to the caller's card connect routine. If the caller needs to perform additional processing to connect to the card, this
/// function pointer is set to the user's connect function. If the connect function is successful, the card is left connected and
/// initialized, and the card handle is returned.
/// </para>
/// </summary>
[MarshalAs(UnmanagedType.FunctionPtr)]
public LPOCNCONNPROC lpfnConnect;
/// <summary>
/// <para>A pointer to the caller's card disconnect routine.</para>
/// </summary>
[MarshalAs(UnmanagedType.FunctionPtr)]
public LPOCNDSCPROC lpfnDisconnect;
/// <summary>Void pointer to user data. This pointer is passed back to the caller on the Connect, Check, and Disconnect routines.</summary>
public IntPtr pvUserData;
/// <summary>
/// If <c>lpfnConnect</c> is not <c>NULL</c>, the <c>dwShareMode</c> and <c>dwPreferredProtocols</c> members are ignored. If
/// <c>lpfnConnect</c> is <c>NULL</c> and <c>dwShareMode</c> is nonzero, an internal call is made to SCardConnect that uses
/// <c>dwShareMode</c> and <c>dwPreferredProtocols</c> as the parameter.
/// </summary>
public SCARD_SHARE dwShareMode;
/// <summary>Used for internal connection as described in <c>dwShareMode</c>.</summary>
public SCARD_PROTOCOL dwPreferredProtocols;
}
/// <summary>
/// The <c>OPENCARDNAME</c> structure contains the information that the GetOpenCardName function uses to initialize a smart card
/// <c>Select Card</c> dialog box. Calling SCardUIDlgSelectCard with OPENCARDNAME_EX is recommended over calling GetOpenCardName with
/// <c>OPENCARDNAME</c>. <c>OPENCARDNAME</c> is provided for backward compatibility.
/// </summary>
/// <remarks>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines OPENCARDNAME as an alias which automatically selects the ANSI or Unicode version of this function based
/// on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/ns-winscard-opencardnamea typedef struct { DWORD dwStructSize; HWND
// hwndOwner; SCARDCONTEXT hSCardContext; LPSTR lpstrGroupNames; DWORD nMaxGroupNames; LPSTR lpstrCardNames; DWORD nMaxCardNames; LPCGUID
// rgguidInterfaces; DWORD cguidInterfaces; LPSTR lpstrRdr; DWORD nMaxRdr; LPSTR lpstrCard; DWORD nMaxCard; LPCSTR lpstrTitle; DWORD
// dwFlags; LPVOID pvUserData; DWORD dwShareMode; DWORD dwPreferredProtocols; DWORD dwActiveProtocol; LPOCNCONNPROCA lpfnConnect;
// LPOCNCHKPROC lpfnCheck; LPOCNDSCPROC lpfnDisconnect; SCARDHANDLE hCardHandle; } OPENCARDNAMEA, *POPENCARDNAMEA, *LPOPENCARDNAMEA;
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.__unnamed_struct_8")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct OPENCARDNAME
{
/// <summary>Specifies the length, in bytes, of the structure. This member must not be <c>NULL</c>.</summary>
public uint dwStructSize;
/// <summary>
/// The window that owns the dialog box. This member can be any valid window handle, or it can be <c>NULL</c> for desktop default.
/// </summary>
public HWND hwndOwner;
/// <summary>
/// The context used for communication with the smart card resource manager. Call SCardEstablishContext to set the resource manager
/// context and SCardReleaseContext to release it. This member must not be <c>NULL</c>.
/// </summary>
public SCARDCONTEXT hSCardContext;
/// <summary>
/// A pointer to a buffer that contains null-terminated group name strings. The last string in the buffer must be terminated by two
/// null characters. Each string is the name of a group of cards that is to be included in the search. If <c>lpstrGroupNames</c> is
/// <c>NULL</c>, the default group (Scard$DefaultReaders) is searched.
/// </summary>
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")]
public string[] lpstrGroupNames;
/// <summary>The maximum number of bytes (ANSI version) or characters (Unicode version) in the <c>lpstrGroupNames</c> string.</summary>
public uint nMaxGroupNames;
/// <summary>
/// A pointer to a buffer that contains null-terminated card name strings. The last string in the buffer must be terminated by two
/// null characters. Each string is the name of a card that is to be located.
/// </summary>
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")]
public string[] lpstrCardNames;
/// <summary>The maximum number of bytes (ANSI version) or characters (Unicode version) in the <c>lpstrCardNames</c> string.</summary>
public uint nMaxCardNames;
/// <summary>Reserved for future use. Set to <c>NULL</c>. An array of GUIDs that identify the interfaces required.</summary>
public IntPtr rgguidInterfaces;
/// <summary>Reserved for futures use. Set to <c>NULL</c>. The number of interfaces in the <c>rgguidInterfaces</c> array.</summary>
public uint cguidInterfaces;
/// <summary>
/// If the card is located, the <c>lpstrRdr</c> buffer contains the name of the reader that contains the located card. The buffer
/// should be at least 256 characters long.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrRdr;
/// <summary>
/// The size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by <c>lpstrRdr</c>. If the buffer is
/// too small to contain the reader information, GetOpenCardName returns SCARD_E_NO_MEMORY and the required size of the buffer
/// pointed to by <c>lpstrRdr</c>.
/// </summary>
public uint nMaxRdr;
/// <summary>
/// If the card is located, the <c>lpstrCard</c> buffer contains the name of the located card. The buffer should be at least 256
/// characters long.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrCard;
/// <summary>
/// The size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by <c>lpstrCard</c>. If the buffer is
/// too small to contain the card information, GetOpenCardName returns SCARD_E_NO_MEMORY and the required size of the buffer in <c>nMaxCard</c>.
/// </summary>
public uint nMaxCard;
/// <summary>
/// A pointer to a string to be placed in the title bar of the dialog box. If this member is <c>NULL</c>, the system uses the default
/// title "Select Card:".
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrTitle;
/// <summary>
/// <para>
/// A set of bit flags you can use to initialize the dialog box. When the dialog box returns, it sets these flags to indicate the
/// input of the user. This member can be a combination of the following flags.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SC_DLG_MINIMAL_UI</c></term>
/// <term>
/// Displays the dialog box only if the card being searched for by the calling application is not located and available for use in a
/// reader. This allows the card to be found, connected (either through the internal dialog box mechanism or the user callback
/// functions), and returned to the calling application.
/// </term>
/// </item>
/// <item>
/// <term><c>SC_DLG_NO_UI</c></term>
/// <term>Force no display of the <c>Select Card</c> user interface (UI), regardless of search outcome.</term>
/// </item>
/// <item>
/// <term><c>SC_DLG_FORCE_UI</c></term>
/// <term>Force display of the <c>Select Card</c> UI, regardless of the search outcome.</term>
/// </item>
/// </list>
/// </summary>
public SC_DLG dwFlags;
/// <summary>A void pointer to user data. This pointer is passed back to the caller on the Connect, Check, and Disconnect routines.</summary>
public IntPtr pvUserData;
/// <summary>
/// <para>If <c>lpfnConnect</c> is not <c>NULL</c>, the <c>dwShareMode</c> and <c>dwPreferredProtocols</c> members are ignored.</para>
/// <para>
/// If <c>lpfnConnect</c> is <c>NULL</c> and <c>dwShareMode</c> is nonzero, then an internal call is made to SCardConnect that uses
/// <c>dwShareMode</c> and <c>dwPreferredProtocols</c> as the <c>dwShareMode</c> and <c>dwPreferredProtocols</c> parameters. If the
/// connect succeeds, <c>hCardHandle</c> is set to the handle returned by <c>hSCardConnect</c>.
/// </para>
/// <para>If <c>lpfnConnect</c> is <c>NULL</c> and <c>dwShareMode</c> is zero, the dialog box returns <c>hCardHandle</c> as <c>NULL</c>.</para>
/// </summary>
public SCARD_SHARE dwShareMode;
/// <summary>Used for internal connection as described in <c>dwShareMode</c>.</summary>
public SCARD_PROTOCOL dwPreferredProtocols;
/// <summary>Returns the actual protocol in use when the dialog box makes a connection to a card.</summary>
public SCARD_PROTOCOL dwActiveProtocol;
/// <summary>
/// <para>
/// A pointer to the card connect routine of the caller. If the caller needs to perform additional processing to connect to the card,
/// this function pointer is set to the connect function for the user. If the connect function is successful, the card is left
/// connected and initialized, and the card handle is returned.
/// </para>
/// <para>The prototype for the connect routine is as follows.</para>
/// </summary>
public LPOCNCONNPROC lpfnConnect;
/// <summary>
/// <para>A pointer to the card verify routine of the caller. If no special card verification is required, this pointer is <c>NULL</c>.</para>
/// <para>If the card is rejected by the verify routine, <c>FALSE</c> is returned and the card is disconnected, as indicated by <c>lpfnDisconnect</c>.</para>
/// <para>
/// If the card is accepted by the verify routine, <c>TRUE</c> is returned. When the user accepts the card, all other cards currently
/// connected will be disconnected, as indicated by <c>lpfnDisconnect</c>, and this card will be returned as the located card. The
/// located card will remain connected.
/// </para>
/// <para>The prototype for the check routine is as follows.</para>
/// </summary>
public LPOCNCHKPROC lpfnCheck;
/// <summary>
/// <para>A pointer to the card disconnect routine of the caller.</para>
/// <para>The prototype for the disconnect routine is as follows.</para>
/// </summary>
public LPOCNDSCPROC lpfnDisconnect;
/// <summary>
/// <c>Note</c> When using <c>lpfnConnect</c>, <c>lpfnCheck</c>, and <c>lpfnDisconnect</c>, all three callback procedures should be
/// present. Using these callbacks allows further verification that the calling application has found the appropriate card. This is
/// the best way to ensure the appropriate card is selected.
/// </summary>
/// <summary>A handle of the connected card (either through an internal dialog box connect or an <c>lpfnConnect</c> callback).</summary>
public SCARDHANDLE hCardHandle;
}
/// <summary>
/// The <c>OPENCARDNAME_EX</c> structure contains the information that the SCardUIDlgSelectCard function uses to initialize a smart card
/// <c>Select Card</c> dialog box.
/// </summary>
/// <remarks>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines OPENCARDNAME_EX as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/ns-winscard-opencardname_exa typedef struct { DWORD dwStructSize;
// SCARDCONTEXT hSCardContext; HWND hwndOwner; DWORD dwFlags; LPCSTR lpstrTitle; LPCSTR lpstrSearchDesc; HICON hIcon;
// POPENCARD_SEARCH_CRITERIAA pOpenCardSearchCriteria; LPOCNCONNPROCA lpfnConnect; LPVOID pvUserData; DWORD dwShareMode; DWORD
// dwPreferredProtocols; LPSTR lpstrRdr; DWORD nMaxRdr; LPSTR lpstrCard; DWORD nMaxCard; DWORD dwActiveProtocol; SCARDHANDLE hCardHandle;
// } OPENCARDNAME_EXA, *POPENCARDNAME_EXA, *LPOPENCARDNAME_EXA;
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.__unnamed_struct_4")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct OPENCARDNAME_EX
{
/// <summary>The length, in bytes, of the structure. The value of this member must not be <c>NULL</c>.</summary>
public uint dwStructSize;
/// <summary>
/// The context used for communication with the smart card resource manager. Call SCardEstablishContext to set the resource manager
/// context and SCardReleaseContext to release it. The value of this member must not be <c>NULL</c>.
/// </summary>
public SCARDCONTEXT hSCardContext;
/// <summary>
/// The window that owns the dialog box. This member can be any valid window handle, or it can be <c>NULL</c> for the desktop default.
/// </summary>
public HWND hwndOwner;
/// <summary>
/// <para>
/// A set of bit flags that you can use to initialize the dialog box. When the dialog box returns, it sets these flags to indicate
/// the user's input. This member can be one of the following flags.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SC_DLG_MINIMAL_UI</c></term>
/// <term>
/// Display the dialog box only if the card being searched for by the calling application is not located and available for use in a
/// reader. This allows the card to be found, connected (either through the internal dialog box mechanism or the user callback
/// functions), and returned to the calling application.
/// </term>
/// </item>
/// <item>
/// <term><c>SC_DLG_NO_UI</c></term>
/// <term>Force no display of the <c>Select Card</c> user interface (UI), regardless of search outcome.</term>
/// </item>
/// <item>
/// <term><c>SC_DLG_FORCE_UI</c></term>
/// <term>Force display of the <c>Select Card</c> UI, regardless of the search outcome.</term>
/// </item>
/// </list>
/// </summary>
public SC_DLG dwFlags;
/// <summary>
/// A pointer to a string to be placed in the title bar of the dialog box. If this member is <c>NULL</c>, the system uses the default
/// title "Select Card:".
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrTitle;
/// <summary>
/// A pointer to a string to be displayed to the user as a prompt to insert the smart card. If this member is <c>NULL</c>, the system
/// uses the default text "Please insert a smart card".
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrSearchDesc;
/// <summary>
/// A handle to an icon (32 x 32 pixels). You can specify a vendor-specific icon to display in the dialog box. If this value is
/// <c>NULL</c>, a generic, smart card reader–loaded icon is displayed.
/// </summary>
public HICON hIcon;
/// <summary>A pointer to the <see cref="OPENCARD_SEARCH_CRITERIA"/> structure to be used, or <c>NULL</c>, if one is not used.</summary>
public IntPtr pOpenCardSearchCriteria;
/// <summary>
/// <para>
/// A pointer to the caller's card connect routine. If the caller needs to perform additional processing to connect to the card, this
/// function pointer is set to the user's connect function. If the connect function is successful, the card is left connected and
/// initialized, and the card handle is returned.
/// </para>
/// <para>The prototype for the connect routine is as follows.</para>
/// </summary>
public LPOCNCONNPROC lpfnConnect;
/// <summary>A void pointer to user data. This pointer is passed back to the caller on the Connect routine.</summary>
public IntPtr pvUserData;
/// <summary>
/// If <c>lpfnConnect</c> is not <c>NULL</c>, the <c>dwShareMode</c> and <c>dwPreferredProtocols</c> members are ignored. If
/// <c>lpfnConnect</c> is <c>NULL</c> and <c>dwShareMode</c> is nonzero, an internal call is made to SCardConnect that uses
/// <c>dwShareMode</c> and <c>dwPreferredProtocols</c> as the <c>dwShareMode</c> and <c>dwPreferredProtocols</c> parameters. If the
/// connect succeeds, <c>hCardHandle</c> is set to the handle returned by <c>SCardConnect</c>. If <c>lpfnConnect</c> is <c>NULL</c>
/// and <c>dwShareMode</c> is zero, <c>hCardHandle</c> is set to <c>NULL</c>.
/// </summary>
public SCARD_SHARE dwShareMode;
/// <summary>Used for internal connection as described in <c>dwShareMode</c>.</summary>
public SCARD_PROTOCOL dwPreferredProtocols;
/// <summary>
/// If the card is located, the <c>lpstrRdr</c> buffer contains the name of the reader that contains the located card. The buffer
/// should be at least 256 characters long.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrRdr;
/// <summary>
/// Size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by <c>lpstrRdr</c>. If the buffer is too
/// small to contain the reader information, SCardUIDlgSelectCard returns SCARD_E_NO_MEMORY and the required size of the buffer
/// pointed to by <c>lpstrRdr</c>.
/// </summary>
public uint nMaxRdr;
/// <summary>
/// If the card is located, the <c>lpstrCard</c> buffer contains the name of the located card. The buffer should be at least 256
/// characters long.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrCard;
/// <summary>
/// Size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by <c>lpstrCard</c>. If the buffer is too
/// small to contain the card information, SCardUIDlgSelectCard returns SCARD_E_NO_MEMORY and the required size of the buffer in <c>nMaxCard</c>.
/// </summary>
public uint nMaxCard;
/// <summary>The actual protocol in use when the dialog box makes a connection to a card.</summary>
public SCARD_PROTOCOL dwActiveProtocol;
/// <summary>A handle of the connected card (either through an internal dialog box connect or an <c>lpfnConnect</c> callback).</summary>
public SCARDHANDLE hCardHandle;
}
/// <summary>The <c>SCARD_ATRMASK</c> structure is used by the SCardLocateCardsByATR function to locate cards.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/ns-winscard-scard_atrmask typedef struct _SCARD_ATRMASK { DWORD cbAtr;
// BYTE rgbAtr[36]; BYTE rgbMask[36]; } SCARD_ATRMASK, *PSCARD_ATRMASK, *LPSCARD_ATRMASK;
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard._SCARD_ATRMASK")]
[StructLayout(LayoutKind.Sequential)]
public struct SCARD_ATRMASK
{
/// <summary>The number of bytes in the ATR and the mask.</summary>
public uint cbAtr;
/// <summary>An array of <c>BYTE</c> values for the ATR of the card with extra alignment bytes.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public byte[] rgbAtr;
/// <summary>An array of <c>BYTE</c> values for the mask for the ATR with extra alignment bytes.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public byte[] rgbMask;
}
/// <summary>The <c>SCARD_READERSTATE</c> structure is used by functions for tracking smart cards within readers.</summary>
/// <remarks>
/// <para>Note</para>
/// <para>
/// The winscard.h header defines SCARD_READERSTATE as an alias which automatically selects the ANSI or Unicode version of this function
/// based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not
/// encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for
/// Function Prototypes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winscard/ns-winscard-scard_readerstatea typedef struct { LPCSTR szReader; LPVOID
// pvUserData; DWORD dwCurrentState; DWORD dwEventState; DWORD cbAtr; BYTE rgbAtr[36]; } SCARD_READERSTATEA, *PSCARD_READERSTATEA, *LPSCARD_READERSTATEA;
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.__unnamed_struct_0")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SCARD_READERSTATE
{
/// <summary>
/// <para>A pointer to the name of the reader being monitored.</para>
/// <para>
/// Set the value of this member to "\\?PnP?\Notification" and the values of all other members to zero to be notified of the arrival
/// of a new smart card reader.
/// </para>
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string szReader;
/// <summary>Not used by the smart card subsystem. This member is used by the application.</summary>
public IntPtr pvUserData;
/// <summary>
/// <para>
/// Current state of the reader, as seen by the application. This field can take on any of the following values, in combination, as a bitmask.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_STATE_UNAWARE</c></term>
/// <term>
/// The application is unaware of the current state, and would like to know. The use of this value results in an immediate return
/// from state transition monitoring services. This is represented by all bits set to zero.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_IGNORE</c></term>
/// <term>
/// The application is not interested in this reader, and it should not be considered during monitoring operations. If this bit value
/// is set, all other bits are ignored.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_UNAVAILABLE</c></term>
/// <term>
/// The application expects that this reader is not available for use. If this bit is set, then all the following bits are ignored.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_EMPTY</c></term>
/// <term>The application expects that there is no card in the reader. If this bit is set, all the following bits are ignored.</term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_PRESENT</c></term>
/// <term>The application expects that there is a card in the reader.</term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_ATRMATCH</c></term>
/// <term>
/// The application expects that there is a card in the reader with an ATR that matches one of the target cards. If this bit is set,
/// SCARD_STATE_PRESENT is assumed. This bit has no meaning to SCardGetStatusChange beyond SCARD_STATE_PRESENT.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_EXCLUSIVE</c></term>
/// <term>
/// The application expects that the card in the reader is allocated for exclusive use by another application. If this bit is set,
/// SCARD_STATE_PRESENT is assumed.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_INUSE</c></term>
/// <term>
/// The application expects that the card in the reader is in use by one or more other applications, but may be connected to in
/// shared mode. If this bit is set, SCARD_STATE_PRESENT is assumed.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_MUTE</c></term>
/// <term>The application expects that there is an unresponsive card in the reader.</term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_UNPOWERED</c></term>
/// <term>This implies that the card in the reader has not been powered up.</term>
/// </item>
/// </list>
/// </summary>
public SCARD_STATE dwCurrentState;
/// <summary>
/// <para>
/// Current state of the reader, as known by the smart card resource manager. This field can take on any of the following values, in
/// combination, as a bitmask.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>SCARD_STATE_IGNORE</c></term>
/// <term>This reader should be ignored.</term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_CHANGED</c></term>
/// <term>
/// There is a difference between the state believed by the application, and the state known by the resource manager. When this bit
/// is set, the application may assume a significant state change has occurred on this reader.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_UNKNOWN</c></term>
/// <term>
/// The given reader name is not recognized by the resource manager. If this bit is set, then SCARD_STATE_CHANGED and
/// SCARD_STATE_IGNORE will also be set.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_UNAVAILABLE</c></term>
/// <term>The actual state of this reader is not available. If this bit is set, then all the following bits are clear.</term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_EMPTY</c></term>
/// <term>There is no card in the reader. If this bit is set, all the following bits will be clear.</term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_PRESENT</c></term>
/// <term>There is a card in the reader.</term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_ATRMATCH</c></term>
/// <term>
/// There is a card in the reader with an ATR matching one of the target cards. If this bit is set, SCARD_STATE_PRESENT will also be
/// set. This bit is only returned on the SCardLocateCards function.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_EXCLUSIVE</c></term>
/// <term>
/// The card in the reader is allocated for exclusive use by another application. If this bit is set, SCARD_STATE_PRESENT will also
/// be set.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_INUSE</c></term>
/// <term>
/// The card in the reader is in use by one or more other applications, but may be connected to in shared mode. If this bit is set,
/// SCARD_STATE_PRESENT will also be set.
/// </term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_MUTE</c></term>
/// <term>There is an unresponsive card in the reader.</term>
/// </item>
/// <item>
/// <term><c>SCARD_STATE_UNPOWERED</c></term>
/// <term>This implies that the card in the reader has not been powered up.</term>
/// </item>
/// </list>
/// </summary>
public SCARD_STATE dwEventState;
/// <summary>Number of bytes in the returned ATR.</summary>
public uint cbAtr;
/// <summary>ATR of the inserted card, with extra alignment bytes.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public byte[] rgbAtr;
}
/// <summary>Provides a handle to a smartcard.</summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct SCARDHANDLE : IHandle
{
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="SCARDHANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public SCARDHANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="SCARDHANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static SCARDHANDLE NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Implements the operator !.</summary>
/// <param name="h1">The handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !(SCARDHANDLE h1) => h1.IsNull;
/// <summary>Performs an explicit conversion from <see cref="SCARDHANDLE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(SCARDHANDLE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="SCARDHANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator SCARDHANDLE(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(SCARDHANDLE h1, SCARDHANDLE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(SCARDHANDLE h1, SCARDHANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is SCARDHANDLE h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="SCARDHANDLE"/> that is disposed using <see cref="SCardDisconnect"/>.</summary>
public class SafeSCARDHANDLE : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeSCARDHANDLE"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeSCARDHANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeSCARDHANDLE"/> class.</summary>
private SafeSCARDHANDLE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeSCARDHANDLE"/> to <see cref="SCARDHANDLE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator SCARDHANDLE(SafeSCARDHANDLE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => SCardDisconnect(handle, SCARD_ACTION.SCARD_LEAVE_CARD).Succeeded;
}
}