public SCardError Status(out string[] ReaderName, out SCardState State, out SCardProtocol Protocol, out byte[] Atr) { SCardError rc; IntPtr dwState = IntPtr.Zero; IntPtr dwProtocol = IntPtr.Zero; rc = SCardAPI.Lib.Status(cardHandle, out ReaderName, out dwState, out dwProtocol, out Atr); if (rc == SCardError.Success) { Protocol = SCardHelper.ToProto(dwProtocol); State = SCardHelper.ToState(dwState); // update local copies activeprot = Protocol; if (ReaderName.Length >= 1) { readername = ReaderName[0]; } } else { Protocol = SCardProtocol.Unset; State = SCardState.Unknown; } return(rc); }
public byte[] GetAtr() => _atr?.ToArray(); // return copy or NULL /// <summary> /// Creates a new instance /// </summary> /// <param name="readerNames">The reader's friendly names</param> /// <param name="state">A bit mask that represents the reader status</param> /// <param name="protocol">The reader's currently used protocol.</param> /// <param name="atr">The card's ATR if available</param> public ReaderStatus(string[] readerNames, SCardState state, SCardProtocol protocol, byte[] atr = null) { State = state; Protocol = protocol; _readerNames = readerNames; _atr = atr; }
/// <inheritdoc /> public SCardError Status(out string[] readerName, out SCardState state, out SCardProtocol protocol, out byte[] atr) { var rc = Platform.Lib.Status( _cardHandle, out readerName, out var dwState, out var dwProtocol, out atr); if (rc == SCardError.Success) { protocol = SCardHelper.ToProto(dwProtocol); state = SCardHelper.ToState(dwState); // update local copies ActiveProtocol = protocol; if (readerName.Length >= 1) { ReaderName = readerName[0]; } } else { protocol = SCardProtocol.Unset; state = SCardState.Unknown; } return(rc); }
public SCardError Status(out string[] ReaderName, out SCardState State, out SCardProtocol Protocol, out byte[] Atr) { SCardError rc; IntPtr dwState = IntPtr.Zero; IntPtr dwProtocol = IntPtr.Zero; rc = SCardAPI.Lib.Status(cardHandle, out ReaderName, out dwState, out dwProtocol, out Atr); if (rc == SCardError.Success) { Protocol = SCardHelper.ToProto(dwProtocol); State = SCardHelper.ToState(dwState); // update local copies activeprot = Protocol; if (ReaderName.Length >= 1) readername = ReaderName[0]; } else { Protocol = SCardProtocol.Unset; State = SCardState.Unknown; } return rc; }
/// <summary>Returns the current status of the reader and the connected card.</summary> /// <param name="readerName">The connected readers's friendly name.</param> /// <param name="state">The current state.</param> /// <param name="protocol">The card's currently used protocol.</param> /// <param name="atr">The card's ATR.</param> /// <returns><list type="table"> /// <listheader> /// <term>Return value</term> /// <description>Description</description> /// </listheader> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.Success" /> /// </term> /// <description>Successful (SCARD_S_SUCCESS)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.InsufficientBuffer" /> /// </term> /// <description>The reader object did not allocate enough memory for <paramref name="readerName" /> or for <paramref name="atr" /> (SCARD_E_INSUFFICIENT_BUFFER)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.InvalidHandle" /> /// </term> /// <description>The reader object got invalid. Invalid card handle (SCARD_E_INVALID_HANDLE)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.InvalidParameter" /> /// </term> /// <description>The reader object passed a size of null for <paramref name="readerName" /> or <paramref name="atr" /> (SCARD_E_INVALID_PARAMETER)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.NoMemory" /> /// </term> /// <description>Memory allocation failed (SCARD_E_NO_MEMORY)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.NoService" /> /// </term> /// <description> The server is not runing (SCARD_E_NO_SERVICE)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.ReaderUnavailable" /> /// </term> /// <description>The reader has been removed (SCARD_E_READER_UNAVAILABLE)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.CommunicationError" /> /// </term> /// <description>An internal communications error has been detected (SCARD_F_COMM_ERROR)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.InternalError" /> /// </term> /// <description>An internal consistency check failed (SCARD_F_INTERNAL_ERROR)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.RemovedCard" /> /// </term> /// <description>The smart card has been removed (SCARD_W_REMOVED_CARD)</description> /// </item> /// <item> /// <term> /// <see cref="F:PCSC.SCardError.ResetCard" /> /// </term> /// <description>The smart card has been reset (SCARD_W_RESET_CARD)</description> /// </item> /// </list> /// </returns> /// <remarks> /// <para>The connected readers's friendly name will be stored in <paramref name="readerName" />. The card's ATR will be stored in <paramref name="atr" />. The current state, and protocol will be stored in <paramref name="state" /> and <paramref name="protocol" /> respectively.</para> /// <para>This method calls the API function SCardStatus().</para> /// </remarks> public SCardError Status(out string[] readerName, out SCardState state, out SCardProtocol protocol, out byte[] atr) { IntPtr dwState; IntPtr dwProtocol; var rc = Platform.Lib.Status( _cardHandle, out readerName, out dwState, out dwProtocol, out atr); if (rc == SCardError.Success) { protocol = SCardHelper.ToProto(dwProtocol); state = SCardHelper.ToState(dwState); // update local copies _activeprot = protocol; if (readerName.Length >= 1) { _readername = readerName[0]; } } else { protocol = SCardProtocol.Unset; state = SCardState.Unknown; } return rc; }
public void Connect(SCardShareMode shareMode = SCardShareMode.Shared) { PCSCResult result; // Are we already connected? if (myHandle != IntPtr.Zero) { return; } // Establish a new session context for this card result = NativeMethods.SCardEstablishContext(SCardScope.User, IntPtr.Zero, IntPtr.Zero, out myContext); if (PCSCResult.None != result) { throw PCSCException.ThrowByResult(result); } // Connect to the card result = NativeMethods.SCardConnect(myContext, myReaderName, shareMode, DefaultRequestedProtocols, ref myHandle, ref myCommsProtocol); if (PCSCResult.None != result) { // Disconnect (this will gracefully handle the context release) Disconnect(); throw PCSCException.ThrowByResult(result); } // Retrieve our ATR byte[] readerName = new byte[255]; uint readerLen = 255; SCardState state = 0; SCardProtocol cardProtocol = 0; uint atrLen = NativeMethods.SCARD_ATR_LENGTH; byte[] atr = new byte[atrLen]; result = NativeMethods.SCardStatus(myHandle, readerName, ref readerLen, out state, out cardProtocol, atr, ref atrLen); if (result != PCSCResult.None) { // Disconnect from the card Disconnect(); throw PCSCException.ThrowByResult(result); } // // Protocol Enumeration // try { // Add the default 7816 protocol Protocols.Add(new PCSCIso7816Protocol(atr, this)); // Determine whether this card is contactless or not if (SupportsIso14443) { // Replace the 7816 protocol with 14443 Protocols.Clear(); var protocol = new PCSCIso14443AProtocol(atr, this); Protocols.Add(protocol); // Create our OptionalCommands object OptionalCommands = new PCSCOptionalCommands(protocol); // // HACK: Adding a PCSCMifareProtocol to all ISO14443 cards, what // we should be doing is somehow determining if this card // supports Mifare or Mifare emulation // Protocols.Add(new PCSCMifareProtocol(this)); } } catch (Exception) { // Disconnect from the card Disconnect(); throw PCSCException.ThrowUnsupportedProtocol(); } }
public static extern PCSCResult SCardStatus(IntPtr hCard, byte[] readerName, ref uint dwReaderLen, out SCardState state, out SCardProtocol protocol, byte[] atr, ref uint atrLen);
public SCardError Status(out string[] readerName, out SCardState state, out SCardProtocol protocol, out byte[] atr) { throw new NotImplementedException(); }
private void PollingProcedure() { PCSCResult result; SCardState pnpState = SCardState.Unaware; // Set all existing readers to the 'Unaware' state to force a re-detection foreach (var reader in myReaders.Values) { reader.State = SCardState.Unaware; } // Reader detection loop while (true) { // List readers string[] readers = ListReaders(); // Check for added readers foreach (string r in readers) { if (!myReaders.ContainsKey(r)) { lock (myReaders) { myReaders.Add(r, new PCSCReader(r)); } SpawnOnReaderInsertedEvent(r); } } // Check for removed readers List <string> removed = new List <string>(); foreach (string r in myReaders.Keys) { if (!readers.Contains(r)) { removed.Add(r); } } foreach (string r in removed) { SpawnOnReaderRemovedEvent(r); lock (myReaders) { myReaders.Remove(r); } } // Create our reader states, including 1 for the PnP notification reader SCARD_READERSTATE[] readerStates = new SCARD_READERSTATE[myReaders.Count + 1]; readerStates[0].szReader = PnPDetectorReader; readerStates[0].dwCurrentState = pnpState; for (int i = 0; i < myReaders.Count; i++) { PCSCReader r = myReaders.ElementAt(i).Value; readerStates[i + 1].szReader = r.Name; readerStates[i + 1].dwCurrentState = r.State; } // Reader state detection loop while (true) { // Call the suspend wait event. If it is cleared, we will hold here mySuspendEvent.WaitOne(); // First, check for a thread abort request if (myThreadAbortRequested == true) { return; } // Wait for a status change result = NativeMethods.SCardGetStatusChange(myContext, PollingInterval, readerStates, readerStates.Length); // Was it a timeout? If so, just continue to the next iteration of the loop if (PCSCResult.Timeout == result) { continue; } // Was an abort requested? If so return if (PCSCResult.Canceled == result) { return; } // Was there another error? If so restart the loop if (PCSCResult.None != result) { Debug.WriteLine($"PCSC> Error: {result}"); continue; } ; // Loop through each reader (skipping the PnP) for (int i = 1; i < readerStates.Length; i++) { // Mask off any changes SCardState changes = (readerStates[i].dwEventState ^ readerStates[i].dwCurrentState); // Was a card inserted? if ((SCardState.Present & changes & readerStates[i].dwEventState) != 0x00) { // Ignore cards with the MUTE flag set if ((readerStates[i].dwEventState & SCardState.Mute) == 0) { lock (myReaders) { myReaders[readerStates[i].szReader].State |= SCardState.Present; } SpawnOnCardInsertedEvent(myReaders[readerStates[i].szReader]); } } // Was a card removed? if ((SCardState.Present & changes & ~readerStates[i].dwEventState) != 0x00) { lock (myReaders) { myReaders[readerStates[i].szReader].State &= ~SCardState.Present; } SpawnOnCardRemovedEvent(myReaders[readerStates[i].szReader]); } // Reset our reader polling state readerStates[i].dwCurrentState = readerStates[i].dwEventState; } // Has a reader been inserted or removed? If so, break to the reader detection loop pnpState = readerStates[0].dwEventState; if ((readerStates[0].dwEventState & SCardState.Changed) != 0x00) { break; } readerStates[0].dwCurrentState = readerStates[0].dwEventState; // This is where we notify the Start() method that we have run at least once myRunOnceEvent.Set(); } } // reader detection while }