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; } }