global using System;
global using System.Runtime.InteropServices;
global using Vanara.InteropServices;
using System.Linq;
using SCARDCONTEXT = System.UIntPtr;
namespace Vanara.PInvoke;
///
/// Provides the definitions and symbols necessary for an Application or Smart Card Service Provider to access the Smartcard Subsystem from WinSCard.dll.
///
public static partial class WinSCard
{
///
/// 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.
///
public const string SCARD_ALL_READERS = "SCard$AllReaders\000";
/// Value used to indicate that memory for a return value should be allocated by the function and freed using .
public const uint SCARD_AUTOALLOCATE = unchecked((uint)-1);
/// Default group to which all readers are added when introduced into the system.
public const string SCARD_DEFAULT_READERS = "SCard$DefaultReaders\000";
///
/// 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.
///
public const string SCARD_LOCAL_READERS = "SCard$LocalReaders\000";
///
/// 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.
///
public const string SCARD_SYSTEM_READERS = "SCard$SystemReaders\000";
private const string Lib_Scarddlg = "scarddlg.dll";
private const string Lib_Winscard = "winscard.dll";
/// A card verify routine delegate.
/// The card context passed in the parameter block.
/// The card handle.
/// Pointer to user data passed in the parameter block.
///
/// If the card is rejected by the verify routine, is returned, and the card will be disconnected. If the card is
/// accepted by the verify routine, is returned.
///
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Auto)]
public delegate bool LPOCNCHKPROC([In] SCARDCONTEXT hSCardContext, [In] SCARDHANDLE hcard, [In] IntPtr pvUserData);
/// A card connect routine delegate.
/// The card context passed in the parameter block.
/// The name of the reader.
/// The possible card names in the reader.
/// Pointer to user data passed in the parameter block.
/// If the connect function is successful, the card is left connected and initialized, and the card handle is returned.
[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);
/// A card disconnect routine delegate.
/// The card context passed in the parameter block.
/// The card handle.
/// Pointer to user data passed in the parameter block.
[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);
///
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.__unnamed_struct_4")]
[Flags]
public enum SC_DLG : uint
{
///
/// 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.
///
SC_DLG_MINIMAL_UI = 0x01,
/// Force no display of the Select Card user interface (UI), regardless of search outcome.
SC_DLG_NO_UI = 0x02,
/// Force display of the Select Card UI, regardless of the search outcome.
SC_DLG_FORCE_UI = 0x04,
}
/// Action to take on the card in the connected reader.
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardDisconnect")]
public enum SCARD_ACTION
{
/// Do not do anything special.
SCARD_LEAVE_CARD = 0,
/// Reset the card.
SCARD_RESET_CARD = 1,
/// Power down the card.
SCARD_UNPOWER_CARD = 2,
/// Eject the card.
SCARD_EJECT_CARD = 3,
}
/// The event to log.
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardAudit")]
[Flags]
public enum SCARD_AUDIT_CHV : uint
{
/// A smart card holder verification (CHV) attempt failed.
SCARD_AUDIT_CHV_FAILURE = 0x0,
/// A smart card holder verification (CHV) attempt succeeded.
SCARD_AUDIT_CHV_SUCCESS = 0x1,
}
///
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetCardTypeProviderNameA")]
public enum SCARD_PROVIDER
{
/// The function retrieves the name of the smart card's primary service provider as a GUID string.
SCARD_PROVIDER_PRIMARY = 1,
/// The function retrieves the name of the cryptographic service provider.
SCARD_PROVIDER_CSP = 2,
/// The function retrieves the name of the smart card key storage provider (KSP).
SCARD_PROVIDER_KSP = 3,
}
/// Scope of the resource manager context.
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardEstablishContext")]
public enum SCARD_SCOPE
{
/// Database operations are performed within the domain of the user.
SCARD_SCOPE_USER = 0,
/// Database operations are performed within the terminal session context.
SCARD_SCOPE_TERMINAL = 1,
///
/// Database operations are performed within the domain of the system. The calling application must have appropriate access
/// permissions for any database actions.
///
SCARD_SCOPE_SYSTEM = 2,
}
/// A flag that indicates whether other applications may form connections to the card.
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.nf-winscard-scardconnecta")]
public enum SCARD_SHARE : uint
{
/// This application is not willing to share the card with other applications.
SCARD_SHARE_EXCLUSIVE = 1,
/// This application is willing to share the card with other applications.
SCARD_SHARE_SHARED = 2,
///
/// This application is allocating the reader for its private use, and will be controlling it directly. No other applications are
/// allowed access to it.
///
SCARD_SHARE_DIRECT = 3,
}
/// State of the reader, as seen by the application.
[PInvokeData("winscard.h", MSDNShortId = "NS:winscard.__unnamed_struct_0")]
[Flags]
public enum SCARD_STATE : uint
{
///
/// 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.
///
SCARD_STATE_UNAWARE = 0x00000000,
///
/// 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.
///
SCARD_STATE_IGNORE = 0x00000001,
///
/// 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.
///
SCARD_STATE_CHANGED = 0x00000002,
///
/// 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.
///
SCARD_STATE_UNKNOWN = 0x00000004,
///
/// The application expects that this reader is not available for use. If this bit is set, then all the following bits are ignored.
///
SCARD_STATE_UNAVAILABLE = 0x00000008,
/// The application expects that there is no card in the reader. If this bit is set, all the following bits are ignored.
SCARD_STATE_EMPTY = 0x00000010,
/// The application expects that there is a card in the reader.
SCARD_STATE_PRESENT = 0x00000020,
///
/// 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.
///
SCARD_STATE_ATRMATCH = 0x00000040,
///
/// 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.
///
SCARD_STATE_EXCLUSIVE = 0x00000080,
///
/// 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.
///
SCARD_STATE_INUSE = 0x00000100,
/// The application expects that there is an unresponsive card in the reader.
SCARD_STATE_MUTE = 0x00000200,
/// This implies that the card in the reader has not been powered up.
SCARD_STATE_UNPOWERED = 0x00000400,
}
///
/// The GetOpenCardName function displays the smart card "select card" dialog box. Call the function SCardUIDlgSelectCard instead
/// of GetOpenCardName. The GetOpenCardName function is maintained for backward compatibility with version 1.0 of the
/// Microsoft Smart Card Base Components, but calls to GetOpenCardName are mapped to SCardUIDlgSelectCard.
///
/// A pointer to the OPENCARDNAME structure for the "select card" dialog box.
///
/// The function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
/// Note
///
/// 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.
///
///
// 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);
///
/// The SCardAccessStartedEvent 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.
///
///
/// The function returns an event HANDLE if it succeeds or NULL if it fails.
/// If the function fails, the GetLastError function provides information on the cause of the failure.
///
///
/// The event-object handle returned can be specified in a call to one of the wait functions.
///
/// 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.
///
///
// 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();
/// The SCardAddReaderToGroup function adds a reader to a reader group.
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be NULL.
///
/// Display name of the reader that you are adding.
///
/// Display name of the group to which you are adding the reader.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ALL_READERS TEXT("SCard$AllReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_DEFAULT_READERS TEXT("SCard$DefaultReaders\000")
/// Default group to which all readers are added when introduced into the system.
///
/// -
/// SCARD_LOCAL_READERS TEXT("SCard$LocalReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_SYSTEM_READERS TEXT("SCard$SystemReaders\000")
///
/// 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.
///
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
/// SCardAddReaderToGroup automatically creates the reader group specified if it does not already exist.
///
/// The SCardAddReaderToGroup function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
///
/// Examples
///
/// 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 LONG, that hContext 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.
///
///
/// lReturn = SCardAddReaderToGroup( hContext, L"MyReader", L"MyReaderGroup"); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardAddReaderToGroup\n");
///
///
/// Note
///
/// 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.
///
///
///
// 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);
/// The SCardAudit function writes event messages to the Windows application log Microsoft-Windows-SmartCard-Audit/Authentication.
///
/// 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 NULL.
///
///
/// The event to log.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_AUDIT_CHV_FAILURE 0x0
/// A smart card holder verification (CHV) attempt failed.
///
/// -
/// SCARD_AUDIT_CHV_SUCCESS 0x1
/// A smart card holder verification (CHV) attempt succeeded.
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// This function is not redirected. An application calling the SCardAudit function from within a Remote Desktop session will log
/// the event on the remote system.
///
/// Examples
///
/// // 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 }
///
///
// 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);
///
/// The SCardBeginTransaction function starts a transaction.
///
/// 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.
///
///
/// A reference value obtained from a previous call to SCardConnect.
///
/// If the function succeeds, it returns SCARD_S_SUCCESS.
/// If the function fails, it returns an error code. For more information, see Smart Card Return Values.
/// If another process or thread has reset the card, SCARD_W_RESET_CARD is returned as expected.
///
/// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This function
/// returns SCARD_S_SUCCESS 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.
///
///
///
///
/// 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.
///
///
/// The SCardBeginTransaction function is a smart card and reader access function. For more information about other access
/// functions, see Smart Card and Reader Access Functions.
///
/// Examples
/// The following example demonstrates how to begin a smart card transaction. The example assumes that
/// lReturn
/// is an existing variable of type LONG and that
/// hCard
/// is a valid handle received from a previous call to SCardConnect.
///
///
/// lReturn = SCardBeginTransaction( hCard ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardBeginTransaction\n");
///
///
// 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);
///
/// The SCardCancel function terminates all outstanding actions within a specific resource manager context.
///
/// 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.
///
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardCancel function is a smart card tracking function. For a description of other tracking functions, see Smart Card
/// Tracking Functions.
///
/// Examples
///
/// The following example cancels all outstanding actions in the specified context. The example assumes that lReturn is an existing
/// variable of type LONG and that hContext is a valid handle received from a previous call to SCardEstablishContext.
///
///
/// lReturn = SCardCancel( hContext ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardCancel\n");
///
///
// 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);
///
/// The SCardConnect 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.
///
///
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
///
/// The name of the reader that contains the target card.
///
/// A flag that indicates whether other applications may form connections to the card.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_SHARE_SHARED
/// This application is willing to share the card with other applications.
///
/// -
/// SCARD_SHARE_EXCLUSIVE
/// This application is not willing to share the card with other applications.
///
/// -
/// SCARD_SHARE_DIRECT
///
/// This application is allocating the reader for its private use, and will be controlling it directly. No other applications are allowed
/// access to it.
///
///
///
///
///
/// A bitmask of acceptable protocols for the connection. Possible values may be combined with the OR operation.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_PROTOCOL_T0
/// T=0 is an acceptable protocol.
///
/// -
/// SCARD_PROTOCOL_T1
/// T=1 is an acceptable protocol.
///
/// -
/// 0
///
/// This parameter may be zero only if dwShareMode 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.
///
///
///
///
/// A handle that identifies the connection to the smart card in the designated reader.
///
/// A flag that indicates the established active protocol.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_PROTOCOL_T0
/// T=0 is the active protocol.
///
/// -
/// SCARD_PROTOCOL_T1
/// T=1 is the active protocol.
///
/// -
/// SCARD_PROTOCOL_UNDEFINED
///
/// SCARD_SHARE_DIRECT has been specified, so that no protocol negotiation has occurred. It is possible that there is no card in the reader.
///
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
/// -
/// SCARD_E_NOT_READY
/// The reader was unable to connect to the card.
///
///
///
///
///
/// The SCardConnect function is a smart card and reader access function. For more information about other access functions, see
/// Smart Card and Reader Access Functions.
///
/// Examples
///
/// The following example creates a connection to a reader. The example assumes that hContext is a valid handle of type
/// SCARDCONTEXT received from a previous call to SCardEstablishContext.
///
///
/// SCARDHANDLE hCardHandle; LONG lReturn; DWORD dwAP; lReturn = SCardConnect( hContext, (LPCTSTR)"Rainbow Technologies SCR3531 0", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCardHandle, &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). // ...
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardControl 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.
///
/// Reference value returned from SCardConnect.
/// Control code for the operation. This value identifies the specific operation to be performed.
///
/// Pointer to a buffer that contains the data required to perform the operation. This parameter can be NULL if the
/// dwControlCode parameter specifies an operation that does not require input data.
///
/// Size, in bytes, of the buffer pointed to by lpInBuffer.
///
/// Pointer to a buffer that receives the operation's output data. This parameter can be NULL if the dwControlCode
/// parameter specifies an operation that does not produce output data.
///
/// Size, in bytes, of the buffer pointed to by lpOutBuffer.
///
/// Pointer to a DWORD that receives the size, in bytes, of the data stored into the buffer pointed to by lpOutBuffer.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardControl function is a direct card access function. For more information on other direct access functions, see Direct
/// Card Access Functions.
///
/// Examples
///
/// 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 DWORD previously initialized to a valid control code. This
/// particular control code requires no input data and expects no output data.
///
///
/// lReturn = SCardControl( hCardHandle, dwControlCode, NULL, 0, NULL, 0, 0 ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardControl\n");
///
///
// 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);
///
/// The SCardDisconnect function terminates a connection previously opened between the calling application and a smart card in the
/// target reader.
///
/// Reference value obtained from a previous call to SCardConnect.
///
/// Action to take on the card in the connected reader on close.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_LEAVE_CARD
/// Do not do anything special.
///
/// -
/// SCARD_RESET_CARD
/// Reset the card.
///
/// -
/// SCARD_UNPOWER_CARD
/// Power down the card.
///
/// -
/// SCARD_EJECT_CARD
/// Eject the card.
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// If an application (which previously called SCardConnect) exits without calling SCardDisconnect, the card is automatically reset.
///
///
/// The SCardDisconnect function is a smart card and reader access function. For more information on other access functions, see
/// Smart Card and Reader Access Functions.
///
/// Examples
///
/// The following example terminates the specified smart card connection. The example assumes that lReturn is a variable of type
/// LONG, and that hCardHandle is a valid handle received from a previous call to SCardConnect.
///
///
/// lReturn = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardDisconnect\n"); exit(1); // Or other appropriate action. }
///
///
// 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);
///
/// The SCardEndTransaction function completes a previously declared transaction, allowing other applications to resume
/// interactions with the card.
///
///
/// Reference value obtained from a previous call to SCardConnect. This value would also have been used in an earlier call to SCardBeginTransaction.
///
///
/// Action to take on the card in the connected reader on close.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_EJECT_CARD
/// Eject the card.
///
/// -
/// SCARD_LEAVE_CARD
/// Do not do anything special.
///
/// -
/// SCARD_RESET_CARD
/// Reset the card.
///
/// -
/// SCARD_UNPOWER_CARD
/// Power down the card.
///
///
///
///
/// If the function succeeds, the function returns SCARD_S_SUCCESS.
/// If the function fails, it returns an error code. For more information, see Smart Card Return Values. Possible error codes follow.
///
///
/// Return code/value
/// Description
///
/// -
/// SCARD_W_RESET_CARD 0x80100068L
///
/// The transaction was released. Any future communication with the card requires a call to the SCardReconnect function. Windows
/// Server 2008, Windows Vista, Windows Server 2003 and Windows XP: 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.
///
///
///
///
///
///
/// The SCardEndTransaction function is a smart card and reader access function. For more information on other access functions,
/// see Smart Card and Reader Access Functions.
///
/// Examples
///
/// The following example ends a smart card transaction. The example assumes that lReturn is a valid variable of type LONG, 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.
///
///
/// lReturn = SCardEndTransaction(hCard, SCARD_LEAVE_CARD); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardEndTransaction\n");
///
///
// 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);
///
/// The SCardEstablishContext function establishes the resource manager context (the scope) within which database operations are performed.
///
///
/// Scope of the resource manager context. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_SCOPE_USER
/// Database operations are performed within the domain of the user.
///
/// -
/// SCARD_SCOPE_SYSTEM
///
/// Database operations are performed within the domain of the system. The calling application must have appropriate access permissions
/// for any database actions.
///
///
///
///
///
/// Reserved for future use and must be NULL. This parameter will allow a suitably privileged management application to act on
/// behalf of another user.
///
/// Reserved for future use and must be NULL.
///
/// A handle to the established resource manager context. This handle can now be supplied to other functions attempting to do work within
/// this context.
///
///
/// If the function succeeds, the function returns SCARD_S_SUCCESS.
/// If the function fails, it returns an error code. For more information, see Smart Card Return Values.
///
///
///
/// The context handle returned by SCardEstablishContext can be used by database query and management functions. For more
/// information, see Smart Card Database Query Functions and Smart Card Database Management Functions.
///
/// To release an established resource manager context, use SCardReleaseContext.
///
/// 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.
///
/// Examples
/// The following example establishes a resource manager context.
///
/// SCARDCONTEXT hSC; LONG lReturn; // Establish the context. lReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSC); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardEstablishContext\n"); else { // Use the context as needed. When done, // free the context by calling SCardReleaseContext. // ... }
///
///
// 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);
/// The SCardForgetCardType function removes an introduced smart card from the smart card subsystem.
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be NULL.
///
/// Display name of the card to be removed from the smart card database.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// This function is not redirected, but calling the function SCardForgetCardType 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.
///
///
/// The SCardForgetCardType function is a database management function. For more information about other database management
/// functions, see Smart Card Database Management Functions.
///
/// Examples
///
/// The following example removes the specified card type from the system. The example assumes that lReturn is a valid variable of type
/// LONG, that hContext 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.
///
///
/// lReturn = SCardForgetCardType(hContext, L"MyCardName"); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardForgetCardType\n");
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardForgetReader 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.
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be NULL.
///
/// Display name of the reader to be removed from the smart card database.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
/// If the specified reader is the last member of a reader group, the reader group is automatically removed as well.
///
/// The SCardForgetReader function is a database management function. For more information on other database management functions,
/// see Smart Card Database Management Functions.
///
/// Examples
///
/// 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 LONG and that hContext is a valid handle received from a previous call to the SCardEstablishContext function.
///
///
/// lReturn = SCardForgetReader(hContext, TEXT("MyReader")); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardForgetReader\n");
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardForgetReaderGroup 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.
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be NULL.
///
///
/// Display name of the reader group to be removed. System-defined reader groups cannot be removed from the database.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ALL_READERS TEXT("SCard$AllReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_DEFAULT_READERS TEXT("SCard$DefaultReaders\000")
/// Default group to which all readers are added when introduced into the system.
///
/// -
/// SCARD_LOCAL_READERS TEXT("SCard$LocalReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_SYSTEM_READERS TEXT("SCard$SystemReaders\000")
///
/// 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.
///
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardForgetReaderGroup function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
///
/// Examples
///
/// The following example shows how to remove a reader group from the system. The example assumes that lReturn is an existing variable of
/// type LONG, and that hContext is a valid handle to a resource manager context previously obtained from a call to the
/// SCardEstablishContext function.
///
///
/// lReturn = SCardForgetReaderGroup(hContext, L"MyReaderGroup"); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardForgetReaderGroup\n");
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardFreeMemory function releases memory that has been returned from the resource manager using the SCARD_AUTOALLOCATE
/// length designator.
///
///
/// Handle that identifies the resource manager context returned from SCardEstablishContext, or NULL if the creating function also
/// specified NULL for its hContext parameter. For more information, see Smart Card Database Query Functions.
///
/// Memory block to be released.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
// 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, Optional] SCARDCONTEXT hContext, [In] IntPtr pvMem);
///
/// The SCardGetAttrib function retrieves the current reader attributes for the given handle. It does not affect the state of the
/// reader, driver, or card.
///
/// Reference value returned from SCardConnect.
///
///
/// Identifier for the attribute to get. The following table lists possible values for dwAttrId. These values are read-only. Note
/// that vendors may not support all attributes.
///
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ATTR_ATR_STRING
/// Answer to reset (ATR) string.
///
/// -
/// SCARD_ATTR_CHANNEL_ID
/// DWORD encoded as 0x DDDDCCCC, where DDDD = data channel type and CCCC = channel number:
///
/// -
/// SCARD_ATTR_CHARACTERISTICS
///
/// DWORD 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).
///
///
/// -
/// SCARD_ATTR_CURRENT_BWT
/// Current block waiting time.
///
/// -
/// SCARD_ATTR_CURRENT_CLK
/// Current clock rate, in kHz.
///
/// -
/// SCARD_ATTR_CURRENT_CWT
/// Current character waiting time.
///
/// -
/// SCARD_ATTR_CURRENT_D
/// Bit rate conversion factor.
///
/// -
/// SCARD_ATTR_CURRENT_EBC_ENCODING
/// Current error block control encoding. 0 = longitudinal redundancy check (LRC) 1 = cyclical redundancy check (CRC)
///
/// -
/// SCARD_ATTR_CURRENT_F
/// Clock conversion factor.
///
/// -
/// SCARD_ATTR_CURRENT_IFSC
/// Current byte size for information field size card.
///
/// -
/// SCARD_ATTR_CURRENT_IFSD
/// Current byte size for information field size device.
///
/// -
/// SCARD_ATTR_CURRENT_N
/// Current guard time.
///
/// -
/// SCARD_ATTR_CURRENT_PROTOCOL_TYPE
///
/// DWORD encoded as 0x0 rrrpppp where rrr is RFU and should be 0x000. pppp 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.)
///
///
/// -
/// SCARD_ATTR_CURRENT_W
/// Current work waiting time.
///
/// -
/// SCARD_ATTR_DEFAULT_CLK
/// Default clock rate, in kHz.
///
/// -
/// SCARD_ATTR_DEFAULT_DATA_RATE
/// Default data rate, in bps.
///
/// -
/// SCARD_ATTR_DEVICE_FRIENDLY_NAME
/// Reader's display name.
///
/// -
/// SCARD_ATTR_DEVICE_IN_USE
/// Reserved for future use.
///
/// -
/// SCARD_ATTR_DEVICE_SYSTEM_NAME
/// Reader's system name.
///
/// -
/// SCARD_ATTR_DEVICE_UNIT
///
/// 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.
///
///
/// -
/// SCARD_ATTR_ICC_INTERFACE_STATUS
/// Single byte. Zero if smart card electrical contact is not active; nonzero if contact is active.
///
/// -
/// SCARD_ATTR_ICC_PRESENCE
///
/// 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.
///
///
/// -
/// SCARD_ATTR_ICC_TYPE_PER_ATR
/// Single byte indicating smart card type: 0 = unknown type 1 = 7816 Asynchronous 2 = 7816 Synchronous Other values RFU.
///
/// -
/// SCARD_ATTR_MAX_CLK
/// Maximum clock rate, in kHz.
///
/// -
/// SCARD_ATTR_MAX_DATA_RATE
/// Maximum data rate, in bps.
///
/// -
/// SCARD_ATTR_MAX_IFSD
/// Maximum bytes for information file size device.
///
/// -
/// SCARD_ATTR_POWER_MGMT_SUPPORT
/// Zero if device does not support power down while smart card is inserted. Nonzero otherwise.
///
/// -
/// SCARD_ATTR_PROTOCOL_TYPES
///
/// DWORD encoded as 0x0 rrrpppp where rrr is RFU and should be 0x000. pppp 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.
///
///
/// -
/// SCARD_ATTR_VENDOR_IFD_SERIAL_NO
/// Vendor-supplied interface device serial number.
///
/// -
/// SCARD_ATTR_VENDOR_IFD_TYPE
/// Vendor-supplied interface device type (model designation of reader).
///
/// -
/// SCARD_ATTR_VENDOR_IFD_VERSION
///
/// Vendor-supplied interface device version ( DWORD in the form 0x MMmmbbbb where MM = major version, mm =
/// minor version, and bbbb = build number).
///
///
/// -
/// SCARD_ATTR_VENDOR_NAME
/// Vendor name.
///
///
///
///
/// Pointer to a buffer that receives the attribute whose ID is supplied in dwAttrId. If this value is NULL,
/// SCardGetAttrib ignores the buffer length supplied in pcbAttrLen, writes the length of the buffer that would have been
/// returned if this parameter had not been NULL to pcbAttrLen, and returns a success code.
///
///
/// Length of the pbAttr buffer in bytes, and receives the actual length of the received attribute If the buffer length is
/// specified as SCARD_AUTOALLOCATE, then pbAttr 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Attribute value not supported.
/// ERROR_NOT_SUPPORTED.
///
/// -
/// Other Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardGetAttrib function is a direct card access function. For more information on other direct access functions, see
/// Direct Card Access Functions.
///
/// Examples
///
/// 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.
///
///
/// LPBYTE pbAttr = NULL; DWORD cByte = SCARD_AUTOALLOCATE; DWORD i; LONG lReturn; lReturn = SCardGetAttrib(hCardHandle, SCARD_ATTR_VENDOR_NAME, (LPBYTE)&pbAttr, &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 < cByte; i++) printf("%c", *(pbAttr+i)); printf("\n"); // Free the memory when done. // hContext was set earlier by SCardEstablishContext lReturn = SCardFreeMemory( hContext, pbAttr ); }
///
///
// 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);
///
/// The SCardGetAttrib function retrieves the current reader attributes for the given handle. It does not affect the state of the
/// reader, driver, or card.
///
/// The type of the value to return.
/// Reference value returned from SCardConnect.
///
///
/// Identifier for the attribute to get. The following table lists possible values for dwAttrId. These values are read-only. Note
/// that vendors may not support all attributes.
///
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ATTR_ATR_STRING
/// Answer to reset (ATR) string.
///
/// -
/// SCARD_ATTR_CHANNEL_ID
/// DWORD encoded as 0x DDDDCCCC, where DDDD = data channel type and CCCC = channel number:
///
/// -
/// SCARD_ATTR_CHARACTERISTICS
///
/// DWORD 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).
///
///
/// -
/// SCARD_ATTR_CURRENT_BWT
/// Current block waiting time.
///
/// -
/// SCARD_ATTR_CURRENT_CLK
/// Current clock rate, in kHz.
///
/// -
/// SCARD_ATTR_CURRENT_CWT
/// Current character waiting time.
///
/// -
/// SCARD_ATTR_CURRENT_D
/// Bit rate conversion factor.
///
/// -
/// SCARD_ATTR_CURRENT_EBC_ENCODING
/// Current error block control encoding. 0 = longitudinal redundancy check (LRC) 1 = cyclical redundancy check (CRC)
///
/// -
/// SCARD_ATTR_CURRENT_F
/// Clock conversion factor.
///
/// -
/// SCARD_ATTR_CURRENT_IFSC
/// Current byte size for information field size card.
///
/// -
/// SCARD_ATTR_CURRENT_IFSD
/// Current byte size for information field size device.
///
/// -
/// SCARD_ATTR_CURRENT_N
/// Current guard time.
///
/// -
/// SCARD_ATTR_CURRENT_PROTOCOL_TYPE
///
/// DWORD encoded as 0x0 rrrpppp where rrr is RFU and should be 0x000. pppp 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.)
///
///
/// -
/// SCARD_ATTR_CURRENT_W
/// Current work waiting time.
///
/// -
/// SCARD_ATTR_DEFAULT_CLK
/// Default clock rate, in kHz.
///
/// -
/// SCARD_ATTR_DEFAULT_DATA_RATE
/// Default data rate, in bps.
///
/// -
/// SCARD_ATTR_DEVICE_FRIENDLY_NAME
/// Reader's display name.
///
/// -
/// SCARD_ATTR_DEVICE_IN_USE
/// Reserved for future use.
///
/// -
/// SCARD_ATTR_DEVICE_SYSTEM_NAME
/// Reader's system name.
///
/// -
/// SCARD_ATTR_DEVICE_UNIT
///
/// 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.
///
///
/// -
/// SCARD_ATTR_ICC_INTERFACE_STATUS
/// Single byte. Zero if smart card electrical contact is not active; nonzero if contact is active.
///
/// -
/// SCARD_ATTR_ICC_PRESENCE
///
/// 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.
///
///
/// -
/// SCARD_ATTR_ICC_TYPE_PER_ATR
/// Single byte indicating smart card type: 0 = unknown type 1 = 7816 Asynchronous 2 = 7816 Synchronous Other values RFU.
///
/// -
/// SCARD_ATTR_MAX_CLK
/// Maximum clock rate, in kHz.
///
/// -
/// SCARD_ATTR_MAX_DATA_RATE
/// Maximum data rate, in bps.
///
/// -
/// SCARD_ATTR_MAX_IFSD
/// Maximum bytes for information file size device.
///
/// -
/// SCARD_ATTR_POWER_MGMT_SUPPORT
/// Zero if device does not support power down while smart card is inserted. Nonzero otherwise.
///
/// -
/// SCARD_ATTR_PROTOCOL_TYPES
///
/// DWORD encoded as 0x0 rrrpppp where rrr is RFU and should be 0x000. pppp 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.
///
///
/// -
/// SCARD_ATTR_VENDOR_IFD_SERIAL_NO
/// Vendor-supplied interface device serial number.
///
/// -
/// SCARD_ATTR_VENDOR_IFD_TYPE
/// Vendor-supplied interface device type (model designation of reader).
///
/// -
/// SCARD_ATTR_VENDOR_IFD_VERSION
///
/// Vendor-supplied interface device version ( DWORD in the form 0x MMmmbbbb where MM = major version, mm =
/// minor version, and bbbb = build number).
///
///
/// -
/// SCARD_ATTR_VENDOR_NAME
/// Vendor name.
///
///
///
/// The attribute whose ID is supplied in .
///
/// The SCardGetAttrib function is a direct card access function. For more information on other direct access functions, see
/// Direct Card Access Functions.
///
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetAttrib")]
public static T SCardGetAttrib([In] SCARDHANDLE hCard, [In] uint dwAttrId) where T : struct
{
uint len = SCARD_AUTOALLOCATE;
IntPtr attrib = IntPtr.Zero;
using var pAttrib = new PinnedObject(attrib);
var ret = SCardGetAttrib(hCard, dwAttrId, pAttrib, ref len);
try
{
ret.ThrowIfFailed();
return len > 0 ? attrib.ToStructure(len)! : default;
}
finally
{
SCardFreeMemory(hCard, attrib);
}
}
///
/// The SCardGetAttrib function retrieves the current reader string attributes for the given handle. It does not affect the state of the
/// reader, driver, or card.
///
/// Reference value returned from SCardConnect.
///
/// Identifier for the attribute to get. The following table lists possible values for dwAttrId. These values are read-only. Note
/// that vendors may not support all attributes.
///
///
///
/// Value
/// Meaning
///
/// -
///
/// SCARD_ATTR_ATR_STRING
///
/// Answer to reset (ATR) string.
///
/// -
///
/// SCARD_ATTR_CHANNEL_ID
///
///
/// DWORD encoded as 0x DDDDCCCC, where DDDD = data channel type and CCCC = channel number:
///
/// -
///
/// SCARD_ATTR_CHARACTERISTICS
///
///
/// DWORD 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).
///
///
/// -
///
/// SCARD_ATTR_CURRENT_BWT
///
/// Current block waiting time.
///
/// -
///
/// SCARD_ATTR_CURRENT_CLK
///
/// Current clock rate, in kHz.
///
/// -
///
/// SCARD_ATTR_CURRENT_CWT
///
/// Current character waiting time.
///
/// -
///
/// SCARD_ATTR_CURRENT_D
///
/// Bit rate conversion factor.
///
/// -
///
/// SCARD_ATTR_CURRENT_EBC_ENCODING
///
/// Current error block control encoding. 0 = longitudinal redundancy check (LRC) 1 = cyclical redundancy check (CRC)
///
/// -
///
/// SCARD_ATTR_CURRENT_F
///
/// Clock conversion factor.
///
/// -
///
/// SCARD_ATTR_CURRENT_IFSC
///
/// Current byte size for information field size card.
///
/// -
///
/// SCARD_ATTR_CURRENT_IFSD
///
/// Current byte size for information field size device.
///
/// -
///
/// SCARD_ATTR_CURRENT_N
///
/// Current guard time.
///
/// -
///
/// SCARD_ATTR_CURRENT_PROTOCOL_TYPE
///
///
/// DWORD encoded as 0x0 rrrpppp where rrr is RFU and should be 0x000. pppp 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.)
///
///
/// -
///
/// SCARD_ATTR_CURRENT_W
///
/// Current work waiting time.
///
/// -
///
/// SCARD_ATTR_DEFAULT_CLK
///
/// Default clock rate, in kHz.
///
/// -
///
/// SCARD_ATTR_DEFAULT_DATA_RATE
///
/// Default data rate, in bps.
///
/// -
///
/// SCARD_ATTR_DEVICE_FRIENDLY_NAME
///
/// Reader's display name.
///
/// -
///
/// SCARD_ATTR_DEVICE_IN_USE
///
/// Reserved for future use.
///
/// -
///
/// SCARD_ATTR_DEVICE_SYSTEM_NAME
///
/// Reader's system name.
///
/// -
///
/// SCARD_ATTR_DEVICE_UNIT
///
///
/// 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.
///
///
/// -
///
/// SCARD_ATTR_ICC_INTERFACE_STATUS
///
/// Single byte. Zero if smart card electrical contact is not active; nonzero if contact is active.
///
/// -
///
/// SCARD_ATTR_ICC_PRESENCE
///
///
/// 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.
///
///
/// -
///
/// SCARD_ATTR_ICC_TYPE_PER_ATR
///
/// Single byte indicating smart card type: 0 = unknown type 1 = 7816 Asynchronous 2 = 7816 Synchronous Other values RFU.
///
/// -
///
/// SCARD_ATTR_MAX_CLK
///
/// Maximum clock rate, in kHz.
///
/// -
///
/// SCARD_ATTR_MAX_DATA_RATE
///
/// Maximum data rate, in bps.
///
/// -
///
/// SCARD_ATTR_MAX_IFSD
///
/// Maximum bytes for information file size device.
///
/// -
///
/// SCARD_ATTR_POWER_MGMT_SUPPORT
///
/// Zero if device does not support power down while smart card is inserted. Nonzero otherwise.
///
/// -
///
/// SCARD_ATTR_PROTOCOL_TYPES
///
///
/// DWORD encoded as 0x0 rrrpppp where rrr is RFU and should be 0x000. pppp 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.
///
///
/// -
///
/// SCARD_ATTR_VENDOR_IFD_SERIAL_NO
///
/// Vendor-supplied interface device serial number.
///
/// -
///
/// SCARD_ATTR_VENDOR_IFD_TYPE
///
/// Vendor-supplied interface device type (model designation of reader).
///
/// -
///
/// SCARD_ATTR_VENDOR_IFD_VERSION
///
///
/// Vendor-supplied interface device version ( DWORD in the form 0x MMmmbbbb where MM = major version, mm =
/// minor version, and bbbb = build number).
///
///
/// -
///
/// SCARD_ATTR_VENDOR_NAME
///
/// Vendor name.
///
///
/// The character set for the string.
/// The string attribute whose ID is supplied in .
///
/// The SCardGetAttrib function is a direct card access function. For more information on other direct access functions, see
/// Direct Card Access Functions.
///
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardGetAttrib")]
public static string SCardGetAttribString([In] SCARDHANDLE hCard, [In] uint dwAttrId, CharSet charSet = CharSet.Auto)
{
uint len = SCARD_AUTOALLOCATE;
IntPtr attrib = IntPtr.Zero;
using var pAttrib = new PinnedObject(attrib);
var ret = SCardGetAttrib(hCard, dwAttrId, pAttrib, ref len);
try
{
ret.ThrowIfFailed();
return len == 0 || attrib == IntPtr.Zero ? string.Empty : StringHelper.GetString(attrib, charSet, len)!;
}
finally
{
SCardFreeMemory(hCard, attrib);
}
}
///
/// The SCardGetCardTypeProviderName function returns the name of the module (dynamic link library) that contains the provider for
/// a given card name and provider type.
///
///
/// Handle that identifies the resource manager context. The resource manager context can be set by a previous call to
/// SCardEstablishContext. This value can be NULL if the call to SCardGetCardTypeProviderName is not directed to a specific context.
///
/// Name of the card type with which this provider name is associated.
///
/// Identifier for the provider associated with this card type.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_PROVIDER_PRIMARY 1
/// The function retrieves the name of the smart card's primary service provider as a GUID string.
///
/// -
/// SCARD_PROVIDER_CSP 2
/// The function retrieves the name of the cryptographic service provider.
///
/// -
/// SCARD_PROVIDER_KSP 3
/// The function retrieves the name of the smart card key storage provider (KSP).
///
/// -
/// SCARD_PROVIDER_CARD_MODULE 0x80000001
/// The function retrieves the name of the card module.
///
///
///
/// String variable to receive the provider name upon successful completion of this function.
///
///
/// Pointer to DWORD value. On input, pcchProvider supplies the length of the szProvider buffer in characters. If
/// this value is SCARD_AUTOALLOCATE, then szProvider 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.
///
///
/// On output, this value represents the actual number of characters, including the null terminator, in the szProvider variable.
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// Upon successful completion of this function, the value in szProvider can be used as the third parameter in a call to CryptAcquireContext.
///
/// Examples
///
/// 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.
///
///
/// 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)&szProvider, &chProvider); if (SCARD_S_SUCCESS == lReturn) { BOOL fSts = TRUE; HCRYPTPROV hProv = NULL; // Acquire a Cryptographic operation context. fSts = CryptAcquireContext(&hProv, NULL, szProvider, PROV_RSA_FULL, 0); // Perform Cryptographic operations with smart card // ... // Free memory allocated by SCardGetCardTypeProviderName. lReturn = SCardFreeMemory(hContext, szProvider); }
///
///
/// Note
///
/// 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.
///
///
///
// 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, Optional] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCardName, [In] SCARD_PROVIDER dwProviderId,
[Out] StringBuilder szProvider, ref uint pcchProvider);
///
/// The SCardGetDeviceTypeId 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.
///
///
/// 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.
///
/// Reader name. You can get this value by calling the SCardListReaders function.
///
/// The actual device type identifier. The list of reader types returned by this function are listed under ReaderType member in
/// the SCARD_READER_CAPABILITIES structure.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
/// Note
///
/// 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.
///
///
// 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);
///
/// The SCardGetProviderId function returns the identifier (GUID) of the primary service provider for a given card.
///
/// 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.
///
///
///
/// 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 NULL.
///
/// Name of the card defined to the system.
///
/// Identifier (GUID) of the primary service provider. This provider may be activated using COM, and will supply access to other services
/// in the card.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// The SCardGetProviderId function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
///
/// Examples
///
/// 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.
///
///
/// GUID guidProv; LONG lReturn; lReturn = SCardGetProviderId(hContext, L"MyCardName", &guidProv); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardGetProviderId - %x\n", lReturn); else { // Use the provider GUID as needed. // ... }
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardGetReaderDeviceInstanceId 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.
///
///
/// 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 NULL.
///
/// Reader name. You can get this value by calling the SCardListReaders function.
///
/// Buffer that receives the device instance ID of the reader. If this value is NULL, the function ignores the buffer length
/// supplied in cchDeviceInstanceId parameter, writes the length of the buffer that would have been returned if this parameter had
/// not been NULL to cchDeviceInstanceId, and returns a success code.
///
///
/// Length, in characters, of the szDeviceInstanceId buffer, including the NULL terminator. If the buffer length is
/// specified as SCARD_AUTOALLOCATE, then the szDeviceInstanceId 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// This function is not redirected. Calling the SCardGetReaderDeviceInstanceId function when inside a Remote Desktop session
/// fails with the SCARD_E_READER_UNAVAILABLE error code.
///
/// Examples
///
/// 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, &cchDeviceInstanceId); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardGetReaderDeviceInstanceId - %x\n", lReturn); // Take appropriate action. }
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardGetReaderIcon 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.
///
///
/// 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 NULL.
///
/// Reader name. You can get this value by calling the SCardListReaders function.
///
/// Pointer to a buffer that contains a BLOB of the smart card reader icon as read from the icon file. If this value is NULL, the
/// function ignores the buffer length supplied in the pcbIcon parameter, writes the length of the buffer that would have been
/// returned to pcbIcon if this parameter had not been NULL, and returns a success code.
///
///
/// Length, in characters, of the pbIcon buffer. This parameter receives the actual length of the received attribute. If the
/// buffer length is specified as SCARD_AUTOALLOCATE, then pbIcon 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
/// The icon should be 256 × 256 pixels with no alpha channel.
/// Examples
///
/// 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)&pbIcon, &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); }
///
///
/// Note
///
/// 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.
///
///
///
// 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, Optional] IntPtr pbIcon, ref uint pcbIcon);
///
///
/// The SCardGetStatusChange function blocks execution until the current availability of the cards in a specific set of readers changes.
///
///
/// 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 SCardGetStatusChange uses the
/// user-supplied value in the dwCurrentState members of the rgReaderStates 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
/// dwEventState members of rgReaderStates appropriately.
///
///
///
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to the
/// SCardEstablishContext function.
///
///
/// 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.
///
///
/// An array of SCARD_READERSTATE structures that specify the readers to watch, and that receives the result.
///
/// To be notified of the arrival of a new smart card reader, set the szReader member of a SCARD_READERSTATE structure to
/// "\\?PnP?\Notification", and set all of the other members of that structure to zero.
///
///
/// Important 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.
///
///
/// The number of elements in the rgReaderStates array.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardGetStatusChange function is a smart card tracking function. For more information about other tracking functions, see
/// Smart Card Tracking Functions.
///
/// Examples
/// For information about how to call this function, see the example in SCardLocateCards.
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardGetTransmitCount function retrieves the number of transmit operations that have completed since the specified card
/// reader was inserted.
///
/// A handle to a smart card obtained from a previous call to SCardConnect.
///
/// A pointer to the number of transmit operations that have completed since the specified card reader was inserted.
///
///
/// If the function succeeds, it returns SCARD_S_SUCCESS.
/// If the function fails, it returns an error code. For more information, see Smart Card Return Values.
///
// 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);
///
/// The SCardIntroduceCardType function introduces a smart card to the smart card subsystem (for the active user) by adding it to
/// the smart card database.
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be NULL.
///
/// Name by which the user can recognize the card.
/// Pointer to the identifier (GUID) for the smart card's primary service provider.
/// Array of identifiers (GUIDs) that identify the interfaces supported by the smart card.
/// Number of identifiers in the rgguidInterfaces array.
///
/// 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.
///
///
/// Optional bitmask to use when comparing the ATRs of smart cards to the ATR supplied in pbAtr. If this value is non-
/// NULL, it must point to a string of bytes the same length as the ATR string supplied in pbAtr. When a given ATR string
/// A is compared to the ATR supplied in pbAtr, it matches if and only if A & M = pbAtr, where M
/// is the supplied mask, and & represents bitwise AND.
///
///
/// 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 pbAtr value is supplied.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// The SCardIntroduceCardType function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
///
/// To remove a smart card, use SCardForgetCardType.
/// Examples
///
/// 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.
///
///
/// 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", &MyGuid, NULL, // No interface array 0, // Interface count = 0 MyATR, MyATRMask, sizeof(MyATR)); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardIntroduceCardType\n");
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardIntroduceCardType function introduces a smart card to the smart card subsystem (for the active user) by adding it to
/// the smart card database.
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be NULL.
///
/// Name by which the user can recognize the card.
/// Pointer to the identifier (GUID) for the smart card's primary service provider.
/// Array of identifiers (GUIDs) that identify the interfaces supported by the smart card.
/// Number of identifiers in the rgguidInterfaces array.
///
/// 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.
///
///
/// Optional bitmask to use when comparing the ATRs of smart cards to the ATR supplied in pbAtr. If this value is non-
/// NULL, it must point to a string of bytes the same length as the ATR string supplied in pbAtr. When a given ATR string
/// A is compared to the ATR supplied in pbAtr, it matches if and only if A & M = pbAtr, where M
/// is the supplied mask, and & represents bitwise AND.
///
///
/// 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 pbAtr value is supplied.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// The SCardIntroduceCardType function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
///
/// To remove a smart card, use SCardForgetCardType.
/// Examples
///
/// 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.
///
///
/// 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", &MyGuid, NULL, // No interface array 0, // Interface count = 0 MyATR, MyATRMask, sizeof(MyATR)); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardIntroduceCardType\n");
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardIntroduceReader function introduces a new name for an existing smart card reader.
///
/// Note 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.
///
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be NULL.
///
/// Display name to be assigned to the reader.
/// System name of the smart card reader, for example, "MyReader 01".
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// All readers installed on the system are automatically introduced by their system name. Typically, SCardIntroduceReader is
/// called only to change the name of an existing reader.
///
///
/// The SCardIntroduceReader function is a database management function. For more information on other database management
/// functions, see Smart Card Database Management Functions.
///
/// To remove a reader, use SCardForgetReader.
/// Examples
/// The following example shows introducing a smart card reader.
///
/// // 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)&pbAttr, &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 );
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardIntroduceReaderGroup 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.
///
///
/// 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 NULL, the scope of the resource manager is SCARD_SCOPE_SYSTEM.
///
///
/// Supplies the display name to be assigned to the new reader group.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ALL_READERS TEXT("SCard$AllReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_DEFAULT_READERS TEXT("SCard$DefaultReaders\000")
/// Default group to which all readers are added when introduced into the system.
///
/// -
/// SCARD_LOCAL_READERS TEXT("SCard$LocalReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_SYSTEM_READERS TEXT("SCard$SystemReaders\000")
///
/// 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.
///
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardIntroduceReaderGroup function is provided for PC/SC specification compatibility. Reader groups are not stored until a
/// reader is added to the group.
///
///
/// The SCardIntroduceReaderGroup function is a database management function. For a description of other database management
/// functions, see Smart Card Database Management Functions.
///
/// To remove a reader group, use SCardForgetReaderGroup.
/// Examples
/// The following example shows introducing a smart card reader group.
///
/// // 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");
///
///
/// Note
///
/// 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.
///
///
///
// 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, Optional] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szGroupName);
/// The SCardIsValidContext function determines whether a smart card context handle is valid.
///
/// Handle that identifies the resource manager context. The resource manager context can be set by a previous call to SCardEstablishContext.
///
///
/// This function returns one of the following values.
///
///
/// Return code
/// Description
///
/// -
/// SCARD_S_SUCCESS
/// The hContext parameter is valid.
///
/// -
/// ERROR_INVALID_HANDLE
/// The hContext parameter is not valid.
///
/// -
/// Other values
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
/// Examples
/// The following example shows determining whether a smart card context handle is valid.
///
/// // 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. // ... }
///
///
// 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);
///
///
/// The SCardListCards function searches the smart card database and provides a list of named cards previously introduced to the
/// system by the user.
///
///
/// 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.
///
///
///
///
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
///
/// If this parameter is set to NULL, the search for cards is not limited to any context.
///
/// Address of an ATR string to compare to known cards, or NULL if no ATR matching is to be performed.
///
/// Array of identifiers (GUIDs), or NULL 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.
///
///
/// Number of entries in the rgguidInterfaces array. If rgguidInterfaces is NULL, then this value is ignored.
///
///
/// Multi-string that lists the smart cards found. If this value is NULL, SCardListCards ignores the buffer length supplied
/// in pcchCards, returning the length of the buffer that would have been returned if this parameter had not been NULL to
/// pcchCards and a success code.
///
///
/// Length of the mszCards buffer in characters. Receives the actual length of the multi-string structure, including all trailing
/// null characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then mszCards 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
/// To return all smart cards introduced to the subsystem, set pbAtr and rgguidInterfaces to NULL.
///
/// The SCardListCards function is a database query function. For more information on other database query functions, see Smart
/// Card Database Query Functions.
///
///
/// 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 hCard parameter (of type SCARDHANDLE) of the
/// SCardBeginTransaction function.
///
///
/// Windows Server 2008 R2 and Windows 7: Calling this function within a transaction could result in your computer becoming unresponsive.
///
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: Not applicable.
/// Examples
/// The following example shows listing of the smart cards.
///
/// LPTSTR pmszCards = NULL; LPTSTR pCard; LONG lReturn; DWORD cch = SCARD_AUTOALLOCATE; // Retrieve the list of cards. lReturn = SCardListCards(NULL, NULL, NULL, NULL, (LPTSTR)&pmszCards, &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). // ...
///
///
/// Note
///
/// 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.
///
///
///
// 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, Optional] SCARDCONTEXT hContext, [In, Optional, MarshalAs(UnmanagedType.LPArray)] byte[]? pbAtr,
[In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] Guid[]? rgquidInterfaces, [In, Optional] uint cguidInterfaceCount,
[Out, Optional] IntPtr mszCards, ref uint pcchCards);
///
///
/// The SCardListCards function searches the smart card database and provides a list of named cards previously introduced to the
/// system by the user.
///
///
/// 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.
///
///
///
///
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
///
/// If this parameter is set to NULL, the search for cards is not limited to any context.
///
/// Address of an ATR string to compare to known cards, or NULL if no ATR matching is to be performed.
///
/// Array of identifiers (GUIDs), or NULL 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.
///
///
/// Multi-string that lists the smart cards found. If this value is NULL, SCardListCards ignores the buffer length supplied
/// in pcchCards, returning the length of the buffer that would have been returned if this parameter had not been NULL to
/// pcchCards and a success code.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
/// To return all smart cards introduced to the subsystem, set pbAtr and rgguidInterfaces to NULL.
///
/// The SCardListCards function is a database query function. For more information on other database query functions, see Smart
/// Card Database Query Functions.
///
///
/// 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 hCard parameter (of type SCARDHANDLE) of the
/// SCardBeginTransaction function.
///
///
/// Windows Server 2008 R2 and Windows 7: Calling this function within a transaction could result in your computer becoming unresponsive.
///
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: Not applicable.
///
[PInvokeData("winscard.h", MSDNShortId = "NF:winscard.SCardListCardsA")]
public static SCARD_RET SCardListCards([In, Optional] 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);
///
/// The SCardListInterfaces function provides a list of interfaces supplied by a given card.
///
/// The caller supplies the name of a smart card previously introduced to the subsystem, and receives the list of interfaces supported by
/// the card.
///
///
///
/// 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 NULL.
///
/// Name of the smart card already introduced to the smart card subsystem.
///
/// Array of interface identifiers (GUIDs) that indicate the interfaces supported by the smart card. If this value is NULL,
/// SCardListInterfaces ignores the array length supplied in pcguidInterfaces, returning the size of the array that would
/// have been returned if this parameter had not been NULL to pcguidInterfaces and a success code.
///
///
/// Size of the pcguidInterfaces array, and receives the actual size of the returned array. If the array size is specified as
/// SCARD_AUTOALLOCATE, then pcguidInterfaces 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// The SCardListInterfaces function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
///
/// Examples
/// The following example shows listing the interfaces for a smart card.
///
/// LPGUID pGuids = NULL; LONG lReturn; DWORD cGuid = SCARD_AUTOALLOCATE; // Retrieve the list of interfaces. lReturn = SCardListInterfaces(NULL, (LPCSTR) "MyCard", (LPGUID)&pGuids, &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). // ... }
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardListInterfaces function provides a list of interfaces supplied by a given card.
///
/// The caller supplies the name of a smart card previously introduced to the subsystem, and receives the list of interfaces supported by
/// the card.
///
///
///
/// 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 NULL.
///
/// Name of the smart card already introduced to the smart card subsystem.
///
/// Array of interface identifiers (GUIDs) that indicate the interfaces supported by the smart card. If this value is NULL,
/// SCardListInterfaces ignores the array length supplied in pcguidInterfaces, returning the size of the array that would
/// have been returned if this parameter had not been NULL to pcguidInterfaces and a success code.
///
///
/// Size of the pcguidInterfaces array, and receives the actual size of the returned array. If the array size is specified as
/// SCARD_AUTOALLOCATE, then pcguidInterfaces 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// The SCardListInterfaces function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
///
/// Examples
/// The following example shows listing the interfaces for a smart card.
///
/// LPGUID pGuids = NULL; LONG lReturn; DWORD cGuid = SCARD_AUTOALLOCATE; // Retrieve the list of interfaces. lReturn = SCardListInterfaces(NULL, (LPCSTR) "MyCard", (LPGUID)&pGuids, &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). // ... }
///
///
/// Note
///
/// 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.
///
///
///
// 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, Optional] IntPtr pguidInterfaces, ref uint pcguidInterfaces);
///
/// The SCardListInterfaces function provides a list of interfaces supplied by a given card.
///
/// The caller supplies the name of a smart card previously introduced to the subsystem, and receives the list of interfaces supported by
/// the card.
///
///
///
/// 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 NULL.
///
/// Name of the smart card already introduced to the smart card subsystem.
/// Array of interface identifiers (GUIDs) that indicate the interfaces supported by the smart card.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// The SCardListInterfaces function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
///
///
[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);
///
/// The SCardListReaderGroups function provides the list of reader groups that have previously been introduced to the system.
///
///
///
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
///
/// If this parameter is set to NULL, the search for reader groups is not limited to any context.
///
///
///
/// 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 NULL, SCardListReaderGroups ignores the buffer length supplied in pcchGroups, writes the length of the
/// buffer that would have been returned if this parameter had not been NULL to pcchGroups, and returns a success code.
///
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ALL_READERS TEXT("SCard$AllReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_DEFAULT_READERS TEXT("SCard$DefaultReaders\000")
/// Default group to which all readers are added when introduced into the system.
///
/// -
/// SCARD_LOCAL_READERS TEXT("SCard$LocalReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_SYSTEM_READERS TEXT("SCard$SystemReaders\000")
///
/// 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.
///
///
///
///
///
/// Length of the mszGroups buffer in characters, and receives the actual length of the multi-string structure, including all
/// trailing null characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then mszGroups 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// The SCardListReaderGroups function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
///
/// Examples
/// The following example shows listing the reader groups.
///
/// 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)&pmszReaderGroups, &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. // ... }
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardListReaderGroups function provides the list of reader groups that have previously been introduced to the system.
///
///
///
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
///
/// If this parameter is set to NULL, the search for reader groups is not limited to any context.
///
///
/// String array that lists the reader groups defined to the system and available to the current user on the current terminal.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ALL_READERS TEXT("SCard$AllReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_DEFAULT_READERS TEXT("SCard$DefaultReaders\000")
/// Default group to which all readers are added when introduced into the system.
///
/// -
/// SCARD_LOCAL_READERS TEXT("SCard$LocalReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_SYSTEM_READERS TEXT("SCard$SystemReaders\000")
///
/// 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.
///
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
///
/// The SCardListReaderGroups function is a database query function. For more information on other database query functions, see
/// Smart Card Database Query Functions.
///
///
[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);
///
/// The SCardListReaders function provides the list of readers within a set of named reader groups, eliminating duplicates.
///
/// 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.
///
///
///
///
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
///
/// If this parameter is set to NULL, the search for readers is not limited to any context.
///
///
///
/// Names of the reader groups defined to the system, as a multi-string. Use a NULL value to list all readers in the system (that
/// is, the SCard$AllReaders group).
///
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ALL_READERS TEXT("SCard$AllReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_DEFAULT_READERS TEXT("SCard$DefaultReaders\000")
/// Default group to which all readers are added when introduced into the system.
///
/// -
/// SCARD_LOCAL_READERS TEXT("SCard$LocalReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_SYSTEM_READERS TEXT("SCard$SystemReaders\000")
///
/// 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.
///
///
///
///
///
/// Multi-string that lists the card readers within the supplied reader groups. If this value is NULL, SCardListReaders
/// ignores the buffer length supplied in pcchReaders, writes the length of the buffer that would have been returned if this
/// parameter had not been NULL to pcchReaders, and returns a success code.
///
///
/// Length of the mszReaders buffer in characters. This parameter receives the actual length of the multi-string structure,
/// including all trailing null characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then mszReaders 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code/value
/// Description
///
/// -
/// Success 0 (0x0)
/// SCARD_S_SUCCESS
///
/// -
/// Group contains no readers 2148532270 (0x8010002E)
/// SCARD_E_NO_READERS_AVAILABLE
///
/// -
/// Specified reader is not currently available for use 2148532247 (0x80100017)
/// SCARD_E_READER_UNAVAILABLE
///
/// -
/// Other
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardListReaders function is a database query function. For more information on other database query functions, see Smart
/// Card Database Query Functions.
///
/// Examples
/// The following example shows listing the readers.
///
/// 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)&pmszReaders, &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; }
///
///
/// Note
///
/// 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.
///
///
///
// 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, Optional] IntPtr mszReaders, ref uint pcchReaders);
///
/// The SCardListReaders function provides the list of readers within a set of named reader groups, eliminating duplicates.
///
/// 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.
///
///
///
///
/// Handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext.
///
/// If this parameter is set to NULL, the search for readers is not limited to any context.
///
///
///
/// Names of the reader groups defined to the system, as a string array. Use a NULL value to list all readers in the system (that
/// is, the SCard$AllReaders group).
///
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ALL_READERS TEXT("SCard$AllReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_DEFAULT_READERS TEXT("SCard$DefaultReaders\000")
/// Default group to which all readers are added when introduced into the system.
///
/// -
/// SCARD_LOCAL_READERS TEXT("SCard$LocalReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_SYSTEM_READERS TEXT("SCard$SystemReaders\000")
///
/// 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.
///
///
///
///
/// String array that lists the card readers within the supplied reader groups.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code/value
/// Description
///
/// -
/// Success 0 (0x0)
/// SCARD_S_SUCCESS
///
/// -
/// Group contains no readers 2148532270 (0x8010002E)
/// SCARD_E_NO_READERS_AVAILABLE
///
/// -
/// Specified reader is not currently available for use 2148532247 (0x80100017)
/// SCARD_E_READER_UNAVAILABLE
///
/// -
/// Other
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardListReaders function is a database query function. For more information on other database query functions, see Smart
/// Card Database Query Functions.
///
///
[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);
///
/// The SCardListReadersWithDeviceInstanceId function gets the list of readers that have provided a device instance identifier.
/// This function does not affect the state of the reader.
///
///
/// 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 NULL.
///
///
/// 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.
///
///
/// A multi-string that contain the smart card readers within the supplied device instance identifier. If this value is NULL, then
/// the function ignores the buffer length supplied in the pcchReaders parameter, writes the length of the buffer that would have
/// been returned if this parameter had not been NULL to pcchReaders, and returns a success code.
///
///
/// The length, in characters, of the mszReaders 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 mszReaders
/// 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.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// This function is not redirected. Calling the SCardListReadersWithDeviceInstanceId function when inside a Remote Desktop
/// session fails with the SCARD_E_READER_UNAVAILABLE error code.
///
/// Examples
///
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardListReadersWithDeviceInstanceId function gets the list of readers that have provided a device instance identifier.
/// This function does not affect the state of the reader.
///
///
/// 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 NULL.
///
///
/// 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.
///
/// A string array that contain the smart card readers within the supplied device instance identifier.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// This function is not redirected. Calling the SCardListReadersWithDeviceInstanceId function when inside a Remote Desktop
/// session fails with the SCARD_E_READER_UNAVAILABLE error code.
///
///
[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);
///
/// The SCardLocateCards function searches the readers listed in the rgReaderStates parameter for a card with an ATR string
/// that matches one of the card names specified in mszCards, returning immediately with the result.
///
///
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
///
/// A multiple string that contains the names of the cards to search for.
///
/// An array of SCARD_READERSTATE structures that, on input, specify the readers to search and that, on output, receives the result.
///
/// The number of elements in the rgReaderStates array.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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 SCardGetStatusChange to wait for card availability changes.
///
///
/// The SCardLocateCards function is a smart card tracking function. For more information on other tracking functions, see Smart
/// Card Tracking Functions.
///
///
/// 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 hCard parameter (of type SCARDHANDLE) of the
/// SCardBeginTransaction function.
///
///
/// Windows Server 2008 R2 and Windows 7: Calling this function within a transaction could result in your computer becoming unresponsive.
///
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: Not applicable.
/// Examples
/// The following example shows locating smart cards.
///
/// // Copyright (C) Microsoft. All rights reserved. #include <stdio.h> #include <winscard.h> #include <tchar.h> #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, &hSC ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardEstablishContext\n"); exit(1); } // Determine which readers are available. lReturn = SCardListReaders(hSC, NULL, (LPTSTR)&szReaders, &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 < 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 < dwRdrCount; dwI++) { if ( 0 != ( SCARD_STATE_ATRMATCH & 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; }
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardLocateCardsByATR function searches the readers listed in the rgReaderStates 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 rgAtrMasks parameter.
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
///
/// Array of SCARD_ATRMASK structures that contain the names of the cards for which to search.
/// Number of elements in the rgAtrMasks array.
/// Array of SCARD_READERSTATE structures that specify the readers to search, and receive the result.
/// Number of elements in the rgReaderStates array.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// Error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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 SCardGetStatusChange to wait for card availability changes.
///
///
/// The SCardLocateCardsByATR function is a smart card tracking function. For information about other tracking functions, see
/// Smart Card Tracking Functions.
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardReadCache function retrieves the value portion of a name-value pair from the global cache maintained by the Smart
/// Card Resource Manager.
///
///
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
///
///
/// 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.
///
/// The current revision of the cached data.
///
/// A pointer to a null-terminated string that contains the name portion of the name-value pair for which to retrieve the value portion.
///
///
/// A pointer to an array of byte values that contain the value portion of the name-value pair specified by the LookupName parameter.
///
/// A pointer to the size, in bytes, of the Data buffer.
///
/// If the function succeeds, it returns SCARD_S_SUCCESS.
/// If the function fails, it returns one of the following error codes. For more information, see Smart Card Return Values.
///
///
/// Return code/value
/// Description
///
/// -
/// SCARD_W_CACHE_ITEM_NOT_FOUND 0x80100070
/// The specified name-value pair was not found in the global cache.
///
/// -
/// SCARD_W_CACHE_ITEM_STALE 0x80100071
/// The specified name-value pair was older than requested and has been deleted from the cache.
///
///
///
///
/// Note
///
/// 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.
///
///
// 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);
///
/// The SCardReconnect 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.
///
/// Reference value obtained from a previous call to SCardConnect.
///
/// Flag that indicates whether other applications may form connections to this card.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_SHARE_SHARED
/// This application will share this card with other applications.
///
/// -
/// SCARD_SHARE_EXCLUSIVE
/// This application will not share this card with other applications.
///
///
///
///
/// Bitmask of acceptable protocols for this connection. Possible values may be combined with the OR operation.
///
/// 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.
///
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_PROTOCOL_T0
/// T=0 is an acceptable protocol.
///
/// -
/// SCARD_PROTOCOL_T1
/// T=1 is an acceptable protocol.
///
///
///
///
/// Type of initialization that should be performed on the card.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_LEAVE_CARD
/// Do not do anything special on reconnect.
///
/// -
/// SCARD_RESET_CARD
/// Reset the card (Warm Reset).
///
/// -
/// SCARD_UNPOWER_CARD
/// Power down the card and reset it (Cold Reset).
///
///
///
///
/// Flag that indicates the established active protocol.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_PROTOCOL_T0
/// T=0 is the active protocol.
///
/// -
/// SCARD_PROTOCOL_T1
/// T=1 is the active protocol.
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// SCardReconnect is a smart card and reader access function. For information about other access functions, see Smart Card and
/// Reader Access Functions.
///
/// Examples
/// The following example shows reestablishing a connection.
///
/// 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, &dwAP ); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardReconnect\n");
///
///
// 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);
///
/// The SCardReleaseContext 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.
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
// 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);
///
/// The SCardReleaseStartedEvent function decrements the reference count for a handle acquired by a previous call to the
/// SCardAccessStartedEvent function.
///
/// None
// 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();
///
/// The SCardRemoveReaderFromGroup function removes a reader from an existing reader group. This function has no effect on the reader.
///
///
/// Handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
/// This parameter cannot be NULL.
///
/// Display name of the reader to be removed.
///
/// Display name of the group from which the reader should be removed.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ALL_READERS TEXT("SCard$AllReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_DEFAULT_READERS TEXT("SCard$DefaultReaders\000")
/// Default group to which all readers are added when introduced into the system.
///
/// -
/// SCARD_LOCAL_READERS TEXT("SCard$LocalReaders\000")
///
/// 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.
///
///
/// -
/// SCARD_SYSTEM_READERS TEXT("SCard$SystemReaders\000")
///
/// 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.
///
///
///
///
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
/// When the last reader is removed from a group, the group is automatically forgotten.
///
/// The SCardRemoveReaderFromGroup function is a database management function. For information about other database management
/// functions, see Smart Card Database Management Functions.
///
/// To add a reader to a reader group, use SCardAddReaderToGroup.
/// Examples
/// The following example shows how to remove a reader from the group.
///
/// // 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");
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardSetAttrib 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.
///
/// Reference value returned from SCardConnect.
///
/// Identifier for the attribute to set. The values are write-only. Note that vendors may not support all attributes.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ATTR_SUPRESS_T1_IFS_REQUEST
///
/// 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.)
///
///
///
///
/// Pointer to a buffer that supplies the attribute whose ID is supplied in dwAttrId.
/// Length (in bytes) of the attribute value in the pbAttr buffer.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// The SCardSetAttrib function is a direct card access function. For information about other direct access functions, see Direct
/// Card Access Functions.
///
/// Examples
/// The following example shows how to set an attribute.
///
/// // 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");
///
///
// 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);
///
/// The SCardSetCardTypeProviderName function specifies the name of the module (dynamic link library) containing the provider for
/// a given card name and provider type.
///
///
/// Handle that identifies the resource manager context. The resource manager context can be set by a previous call to
/// SCardEstablishContext. This value can be NULL if the call to SCardSetCardTypeProviderName is not directed to a specific context.
///
/// Name of the card type with which this provider name is associated.
///
/// Identifier for the provider associated with this card type.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_PROVIDER_PRIMARY 1
/// The function retrieves the name of the smart card's primary service provider as a GUID string.
///
/// -
/// SCARD_PROVIDER_CSP 2
/// The function retrieves the name of the cryptographic service provider (CSP).
///
/// -
/// SCARD_PROVIDER_KSP 3
/// The function retrieves the name of the smart card key storage provider (KSP).
///
/// -
/// SCARD_PROVIDER_CARD_MODULE 0x80000001
/// The function retrieves the name of the card module.
///
///
///
/// A string that contains the provider name that is representing the CSP.
///
/// This function returns different values depending on whether it succeeds or fails.
///
///
/// Return code
/// Description
///
/// -
/// Success
/// SCARD_S_SUCCESS.
///
/// -
/// Failure
/// An error code. For more information, see Smart Card Return Values.
///
///
///
///
///
/// 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.
///
/// This function sets the provider name, while SCardGetCardTypeProviderName can be used to retrieve the provider name.
/// Examples
/// The following example shows how to specify the card type provider name.
///
/// 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); }
///
///
/// Note
///
/// 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.
///
///
///
// 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, Optional] SCARDCONTEXT hContext, [MarshalAs(UnmanagedType.LPTStr)] string szCardName, [In] SCARD_PROVIDER dwProviderId,
[MarshalAs(UnmanagedType.LPTStr)] string szProvider);
///
/// The SCardStatus 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.
///
/// Reference value returned from SCardConnect.
/// List of display names (multiple string) by which the currently connected reader is known.
///
/// On input, supplies the length of the szReaderName buffer.
///
/// On output, receives the actual length (in characters) of the reader name list, including the trailing NULL character. If this
/// buffer length is specified as SCARD_AUTOALLOCATE, then szReaderName 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.
///
///
///
/// Current state of the smart card in the reader. Upon success, it receives one of the following state indicators.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_ABSENT
/// There is no card in the reader.
///
/// -
/// SCARD_PRESENT
/// There is a card in the reader, but it has not been moved into position for use.
///
/// -
/// SCARD_SWALLOWED
/// There is a card in the reader in position for use. The card is not powered.
///
/// -
/// SCARD_POWERED
/// Power is being provided to the card, but the reader driver is unaware of the mode of the card.
///
/// -
/// SCARD_NEGOTIABLE
/// The card has been reset and is awaiting PTS negotiation.
///
/// -
/// SCARD_SPECIFIC
/// The card has been reset and specific communication protocols have been established.
///
///
///
///
/// Current protocol, if any. The returned value is meaningful only if the returned value of pdwState is SCARD_SPECIFICMODE.
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_PROTOCOL_RAW
/// The Raw Transfer protocol is in use.
///
/// -
/// SCARD_PROTOCOL_T0
/// The ISO 7816/3 T=0 protocol is in use.
///
/// -
/// SCARD_PROTOCOL_T1
/// The ISO 7816/3 T=1 protocol is in use.
///
///
///
/// Pointer to a 32-byte buffer that receives the ATR string from the currently inserted card, if available.
///
/// On input, supplies the length of the pbAtr 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 pbAtr 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.
///
///
/// If the function successfully provides the current status of a smart card in a reader, the return value is SCARD_S_SUCCESS.
/// If the function fails, it returns an error code. For more information, see Smart Card Return Values.
///
///
///
/// The SCardStatus function is a smart card and reader access function. For information about other access functions, see Smart
/// Card and Reader Access Functions.
///
/// Examples
/// The following example shows how to determine the state of the smart card.
///
/// 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, &cch, &dwState, &dwProtocol, (LPBYTE)&bAttr, &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; }
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardTransmit function sends a service request to the smart card and expects to receive data back from the card.
///
/// A reference value returned from the SCardConnect function.
///
///
/// 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).
///
///
/// 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.
///
///
///
/// A pointer to the actual data to be written to the card.
/// For T=0, the data parameters are placed into the address pointed to by pbSendBuffer according to the following structure:
///
/// 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, bP3 is not sent.
///
///
///
/// Member
/// Meaning
///
/// -
/// bCla
/// The T=0 instruction class.
///
/// -
/// bIns
/// An instruction code in the T=0 instruction class.
///
/// -
/// bP1, bP2
/// Reference codes that complete the instruction code.
///
/// -
/// bP3
/// The number of data bytes to be transmitted during the command, per ISO 7816-4, Section 8.2.1.
///
///
///
///
/// The length, in bytes, of the pbSendBuffer parameter.
///
/// 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
/// bP3 member is not being sent; the length should be
/// sizeof(CmdBytes) - sizeof(BYTE)
/// .
///
///
///
/// 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 NULL if no PCI is returned.
///
///
/// Pointer to any data returned from the card.
///
/// 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.
///
///
///
///
/// Supplies the length, in bytes, of the pbRecvBuffer parameter and receives the actual number of bytes received from the smart card.
///
/// This value cannot be SCARD_AUTOALLOCATE because SCardTransmit does not support SCARD_AUTOALLOCATE.
/// For T=0, the receive buffer must be at least two bytes long to receive the SW1 and SW2 status bytes.
///
///
/// If the function successfully sends a service request to the smart card, the return value is SCARD_S_SUCCESS.
/// If the function fails, it returns an error code. For more information, see Smart Card Return Values.
///
///
///
/// The SCardTransmit function is a smart card and reader access function. For information about other access functions, see Smart
/// Card and Reader Access Functions.
///
///
/// 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.
///
/// Examples
/// The following example shows sending a service request to the smart card.
///
/// // 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, &dwRecv ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardTransmit\n"); exit(1); // or other appropriate error action }
///
///
// 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] IntPtr /*SCARD_IO_REQUEST*/ pioSendPci, [In] IntPtr pbSendBuffer, [In] uint cbSendLength,
[In, Out, Optional] IntPtr /*SCARD_IO_REQUEST*/ pioRecvPci, [Out] IntPtr pbRecvBuffer, ref uint pcbRecvLength);
/// The SCardUIDlgSelectCard function displays the smart card Select Card dialog box.
/// Pointer to the OPENCARDNAME_EX structure for the Select Card dialog box.
///
/// If the function successfully displays the Select Card dialog box, the return value is SCARD_S_SUCCESS.
/// If the function fails, it returns an error code. For more information, see Smart Card Return Values.
///
///
///
/// The SCardUIDlgSelectCard 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 pDlgStruc
/// parameter. Depending on the dwFlags member of pDlgStruc, this function takes the following actions.
///
///
///
/// Value
/// Action
///
/// -
/// SC_DLG_FORCE_UI
/// Connects to the card selected by the user from the smart card Select Card dialog box.
///
/// -
/// SC_DLG_MINIMAL_UI
///
/// 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.
///
///
/// -
/// SC_DLG_NO_UI
/// Selects the first available card.
///
///
///
/// This function replaces GetOpenCardName. The GetOpenCardName function is maintained for backward compatibility with version 1.0
/// of the Microsoft Smart Card Base Components.
///
/// Examples
/// The following example shows how to display the smart card Select Card dialog box.
///
/// 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, &hSC ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardEstablishContext\n"); exit(1); } // Initialize the structure. memset(&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(&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).
///
///
/// Note
///
/// 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.
///
///
///
// 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);
///
/// The SCardWriteCache function writes a name-value pair from a smart card to the global cache maintained by the Smart Card
/// Resource Manager.
///
///
/// A handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
///
/// A pointer to a value that uniquely identifies the smart card from which the name-value pair was read.
/// The current revision of the cached data.
///
/// A pointer to a null-terminated string that contains the name portion of the name-value pair to write to the global cache.
///
///
/// A pointer to an array of byte values that contain the value portion of the name-value pair to write to the global cache.
///
/// The size, in bytes, of the Data buffer.
///
/// If the function succeeds, it returns SCARD_S_SUCCESS.
/// If the function fails, it returns one of the following error codes. For more information, see Smart Card Return Values.
///
///
/// Return code/value
/// Description
///
/// -
/// SCARD_W_CACHE_ITEM_TOO_BIG 0x80100072
/// The size of the specified name-value pair exceeds the maximum size defined for the global cache.
///
///
///
///
/// Note
///
/// 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.
///
///
// 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(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((int)cch);
return ret;
static int Len(uint cch) => typeof(T) == typeof(string) ? (1 + (int)cch) * Marshal.SystemDefaultCharSize : InteropExtensions.SizeOf() * cch;
}
///
/// The OPENCARD_SEARCH_CRITERIA 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 SCardUIDlgSelectCard without using this structure.
///
///
/// Note
///
/// 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.
///
///
// 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
{
/// The length, in bytes, of the structure. Must not be NULL.
public uint dwStructSize;
///
/// 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 lpstrGroupNames is
/// NULL, the default group (Scard$DefaultReaders) is searched.
///
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")]
public string[]? lpstrGroupNames;
/// The maximum number of bytes (ANSI version) or characters (Unicode version) in the lpstrGroupNames string.
public uint nMaxGroupNames;
/// Reserved for future use. An array of GUIDs that identifies the interfaces required. Set this member to NULL.
public IntPtr rgguidInterfaces;
/// Reserved for future use. The number of interfaces in the rgguidInterfaces array. Set this member to NULL.
public uint cguidInterfaces;
///
/// 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.
///
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")]
public string[] lpstrCardNames;
/// The maximum number of bytes (ANSI version) or characters (Unicode version) in the lpstrGroupNames string.
public uint nMaxCardNames;
///
///
/// A pointer to the caller's card verify routine. If no special card verification is required, this pointer is NULL. If the
/// card is rejected by the verify routine, FALSE is returned, and the card will be disconnected. If the card is accepted by
/// the verify routine, TRUE is returned.
///
///
[MarshalAs(UnmanagedType.FunctionPtr)]
public LPOCNCHKPROC? lpfnCheck;
///
///
/// 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.
///
///
[MarshalAs(UnmanagedType.FunctionPtr)]
public LPOCNCONNPROC? lpfnConnect;
///
/// A pointer to the caller's card disconnect routine.
///
[MarshalAs(UnmanagedType.FunctionPtr)]
public LPOCNDSCPROC lpfnDisconnect;
/// Void pointer to user data. This pointer is passed back to the caller on the Connect, Check, and Disconnect routines.
public IntPtr pvUserData;
///
/// If lpfnConnect is not NULL, the dwShareMode and dwPreferredProtocols members are ignored. If
/// lpfnConnect is NULL and dwShareMode is nonzero, an internal call is made to SCardConnect that uses
/// dwShareMode and dwPreferredProtocols as the parameter.
///
public SCARD_SHARE dwShareMode;
/// Used for internal connection as described in dwShareMode.
public SCARD_PROTOCOL dwPreferredProtocols;
}
///
/// The OPENCARDNAME structure contains the information that the GetOpenCardName function uses to initialize a smart card
/// Select Card dialog box. Calling SCardUIDlgSelectCard with OPENCARDNAME_EX is recommended over calling GetOpenCardName with
/// OPENCARDNAME. OPENCARDNAME is provided for backward compatibility.
///
///
/// Note
///
/// 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.
///
///
// 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
{
/// Specifies the length, in bytes, of the structure. This member must not be NULL.
public uint dwStructSize;
///
/// The window that owns the dialog box. This member can be any valid window handle, or it can be NULL for desktop default.
///
public HWND hwndOwner;
///
/// 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 NULL.
///
public SCARDCONTEXT hSCardContext;
///
/// 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 lpstrGroupNames is
/// NULL, the default group (Scard$DefaultReaders) is searched.
///
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")]
public string[]? lpstrGroupNames;
/// The maximum number of bytes (ANSI version) or characters (Unicode version) in the lpstrGroupNames string.
public uint nMaxGroupNames;
///
/// 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.
///
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")]
public string[] lpstrCardNames;
/// The maximum number of bytes (ANSI version) or characters (Unicode version) in the lpstrCardNames string.
public uint nMaxCardNames;
/// Reserved for future use. Set to NULL. An array of GUIDs that identify the interfaces required.
public IntPtr rgguidInterfaces;
/// Reserved for futures use. Set to NULL. The number of interfaces in the rgguidInterfaces array.
public uint cguidInterfaces;
///
/// If the card is located, the lpstrRdr buffer contains the name of the reader that contains the located card. The buffer
/// should be at least 256 characters long.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrRdr;
///
/// The size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpstrRdr. 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 lpstrRdr.
///
public uint nMaxRdr;
///
/// If the card is located, the lpstrCard buffer contains the name of the located card. The buffer should be at least 256
/// characters long.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrCard;
///
/// The size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpstrCard. 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 nMaxCard.
///
public uint nMaxCard;
///
/// A pointer to a string to be placed in the title bar of the dialog box. If this member is NULL, the system uses the default
/// title "Select Card:".
///
[MarshalAs(UnmanagedType.LPTStr)]
public string? lpstrTitle;
///
///
/// 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.
///
///
///
/// Value
/// Meaning
///
/// -
/// SC_DLG_MINIMAL_UI
///
/// 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.
///
///
/// -
/// SC_DLG_NO_UI
/// Force no display of the Select Card user interface (UI), regardless of search outcome.
///
/// -
/// SC_DLG_FORCE_UI
/// Force display of the Select Card UI, regardless of the search outcome.
///
///
///
public SC_DLG dwFlags;
/// A void pointer to user data. This pointer is passed back to the caller on the Connect, Check, and Disconnect routines.
public IntPtr pvUserData;
///
/// If lpfnConnect is not NULL, the dwShareMode and dwPreferredProtocols members are ignored.
///
/// If lpfnConnect is NULL and dwShareMode is nonzero, then an internal call is made to SCardConnect that uses
/// dwShareMode and dwPreferredProtocols as the dwShareMode and dwPreferredProtocols parameters. If the
/// connect succeeds, hCardHandle is set to the handle returned by hSCardConnect.
///
/// If lpfnConnect is NULL and dwShareMode is zero, the dialog box returns hCardHandle as NULL.
///
public SCARD_SHARE dwShareMode;
/// Used for internal connection as described in dwShareMode.
public SCARD_PROTOCOL dwPreferredProtocols;
/// Returns the actual protocol in use when the dialog box makes a connection to a card.
public SCARD_PROTOCOL dwActiveProtocol;
///
///
/// 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.
///
/// The prototype for the connect routine is as follows.
///
public LPOCNCONNPROC? lpfnConnect;
///
/// A pointer to the card verify routine of the caller. If no special card verification is required, this pointer is NULL.
/// If the card is rejected by the verify routine, FALSE is returned and the card is disconnected, as indicated by lpfnDisconnect.
///
/// If the card is accepted by the verify routine, TRUE is returned. When the user accepts the card, all other cards currently
/// connected will be disconnected, as indicated by lpfnDisconnect, and this card will be returned as the located card. The
/// located card will remain connected.
///
/// The prototype for the check routine is as follows.
///
public LPOCNCHKPROC? lpfnCheck;
///
/// A pointer to the card disconnect routine of the caller.
/// The prototype for the disconnect routine is as follows.
///
public LPOCNDSCPROC lpfnDisconnect;
///
/// Note When using lpfnConnect, lpfnCheck, and lpfnDisconnect, 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.
///
/// A handle of the connected card (either through an internal dialog box connect or an lpfnConnect callback).
public SCARDHANDLE hCardHandle;
}
///
/// The OPENCARDNAME_EX structure contains the information that the SCardUIDlgSelectCard function uses to initialize a smart card
/// Select Card dialog box.
///
///
/// Note
///
/// 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.
///
///
// 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
{
/// The length, in bytes, of the structure. The value of this member must not be NULL.
public uint dwStructSize;
///
/// 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 NULL.
///
public SCARDCONTEXT hSCardContext;
///
/// The window that owns the dialog box. This member can be any valid window handle, or it can be NULL for the desktop default.
///
public HWND hwndOwner;
///
///
/// 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.
///
///
///
/// Value
/// Meaning
///
/// -
/// SC_DLG_MINIMAL_UI
///
/// 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.
///
///
/// -
/// SC_DLG_NO_UI
/// Force no display of the Select Card user interface (UI), regardless of search outcome.
///
/// -
/// SC_DLG_FORCE_UI
/// Force display of the Select Card UI, regardless of the search outcome.
///
///
///
public SC_DLG dwFlags;
///
/// A pointer to a string to be placed in the title bar of the dialog box. If this member is NULL, the system uses the default
/// title "Select Card:".
///
[MarshalAs(UnmanagedType.LPTStr)]
public string? lpstrTitle;
///
/// A pointer to a string to be displayed to the user as a prompt to insert the smart card. If this member is NULL, the system
/// uses the default text "Please insert a smart card".
///
[MarshalAs(UnmanagedType.LPTStr)]
public string? lpstrSearchDesc;
///
/// 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
/// NULL, a generic, smart card reader–loaded icon is displayed.
///
public HICON hIcon;
/// A pointer to the structure to be used, or NULL, if one is not used.
public IntPtr pOpenCardSearchCriteria;
///
///
/// 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.
///
/// The prototype for the connect routine is as follows.
///
public LPOCNCONNPROC lpfnConnect;
/// A void pointer to user data. This pointer is passed back to the caller on the Connect routine.
public IntPtr pvUserData;
///
/// If lpfnConnect is not NULL, the dwShareMode and dwPreferredProtocols members are ignored. If
/// lpfnConnect is NULL and dwShareMode is nonzero, an internal call is made to SCardConnect that uses
/// dwShareMode and dwPreferredProtocols as the dwShareMode and dwPreferredProtocols parameters. If the
/// connect succeeds, hCardHandle is set to the handle returned by SCardConnect. If lpfnConnect is NULL
/// and dwShareMode is zero, hCardHandle is set to NULL.
///
public SCARD_SHARE dwShareMode;
/// Used for internal connection as described in dwShareMode.
public SCARD_PROTOCOL dwPreferredProtocols;
///
/// If the card is located, the lpstrRdr buffer contains the name of the reader that contains the located card. The buffer
/// should be at least 256 characters long.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrRdr;
///
/// Size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpstrRdr. 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 lpstrRdr.
///
public uint nMaxRdr;
///
/// If the card is located, the lpstrCard buffer contains the name of the located card. The buffer should be at least 256
/// characters long.
///
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrCard;
///
/// Size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpstrCard. 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 nMaxCard.
///
public uint nMaxCard;
/// The actual protocol in use when the dialog box makes a connection to a card.
public SCARD_PROTOCOL dwActiveProtocol;
/// A handle of the connected card (either through an internal dialog box connect or an lpfnConnect callback).
public SCARDHANDLE hCardHandle;
}
/// The SCARD_ATRMASK structure is used by the SCardLocateCardsByATR function to locate cards.
// 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
{
/// The number of bytes in the ATR and the mask.
public uint cbAtr;
/// An array of BYTE values for the ATR of the card with extra alignment bytes.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public byte[] rgbAtr;
/// An array of BYTE values for the mask for the ATR with extra alignment bytes.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public byte[] rgbMask;
}
/// The SCARD_READERSTATE structure is used by functions for tracking smart cards within readers.
///
/// Note
///
/// 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.
///
///
// 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
{
///
/// A pointer to the name of the reader being monitored.
///
/// 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.
///
///
[MarshalAs(UnmanagedType.LPTStr)]
public string szReader;
/// Not used by the smart card subsystem. This member is used by the application.
public IntPtr pvUserData;
///
///
/// 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.
///
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_STATE_UNAWARE
///
/// 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.
///
///
/// -
/// SCARD_STATE_IGNORE
///
/// 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.
///
///
/// -
/// SCARD_STATE_UNAVAILABLE
///
/// The application expects that this reader is not available for use. If this bit is set, then all the following bits are ignored.
///
///
/// -
/// SCARD_STATE_EMPTY
/// The application expects that there is no card in the reader. If this bit is set, all the following bits are ignored.
///
/// -
/// SCARD_STATE_PRESENT
/// The application expects that there is a card in the reader.
///
/// -
/// SCARD_STATE_ATRMATCH
///
/// 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.
///
///
/// -
/// SCARD_STATE_EXCLUSIVE
///
/// 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.
///
///
/// -
/// SCARD_STATE_INUSE
///
/// 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.
///
///
/// -
/// SCARD_STATE_MUTE
/// The application expects that there is an unresponsive card in the reader.
///
/// -
/// SCARD_STATE_UNPOWERED
/// This implies that the card in the reader has not been powered up.
///
///
///
public SCARD_STATE dwCurrentState;
///
///
/// 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.
///
///
///
/// Value
/// Meaning
///
/// -
/// SCARD_STATE_IGNORE
/// This reader should be ignored.
///
/// -
/// SCARD_STATE_CHANGED
///
/// 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.
///
///
/// -
/// SCARD_STATE_UNKNOWN
///
/// 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.
///
///
/// -
/// SCARD_STATE_UNAVAILABLE
/// The actual state of this reader is not available. If this bit is set, then all the following bits are clear.
///
/// -
/// SCARD_STATE_EMPTY
/// There is no card in the reader. If this bit is set, all the following bits will be clear.
///
/// -
/// SCARD_STATE_PRESENT
/// There is a card in the reader.
///
/// -
/// SCARD_STATE_ATRMATCH
///
/// 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.
///
///
/// -
/// SCARD_STATE_EXCLUSIVE
///
/// 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.
///
///
/// -
/// SCARD_STATE_INUSE
///
/// 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.
///
///
/// -
/// SCARD_STATE_MUTE
/// There is an unresponsive card in the reader.
///
/// -
/// SCARD_STATE_UNPOWERED
/// This implies that the card in the reader has not been powered up.
///
///
///
public SCARD_STATE dwEventState;
/// Number of bytes in the returned ATR.
public uint cbAtr;
/// ATR of the inserted card, with extra alignment bytes.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public byte[] rgbAtr;
}
/// Provides a handle to a smartcard.
[StructLayout(LayoutKind.Sequential)]
public readonly struct SCARDHANDLE : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public SCARDHANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static SCARDHANDLE NULL => new(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Implements the operator !.
/// The handle.
/// The result of the operator.
public static bool operator !(SCARDHANDLE h1) => h1.IsNull;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(SCARDHANDLE h) => h.handle;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static implicit operator UIntPtr(SCARDHANDLE h) => h.handle.ToUIntPtr();
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator SCARDHANDLE(IntPtr h) => new(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(SCARDHANDLE h1, SCARDHANDLE h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(SCARDHANDLE h1, SCARDHANDLE h2) => h1.Equals(h2);
///
public override bool Equals(object? obj) => obj is SCARDHANDLE h && handle == h.handle;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a for that is disposed using .
public class SafeSCARDHANDLE : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeSCARDHANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeSCARDHANDLE() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator SCARDHANDLE(SafeSCARDHANDLE h) => h.handle;
///
protected override bool InternalReleaseHandle() => SCardDisconnect(handle, SCARD_ACTION.SCARD_LEAVE_CARD).Succeeded;
}
}