Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #4
0
        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;
        }
Exemple #6
0
        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();
            }
        }
Exemple #7
0
 public static extern PCSCResult SCardStatus(IntPtr hCard, byte[] readerName, ref uint dwReaderLen, out SCardState state, out SCardProtocol protocol, byte[] atr, ref uint atrLen);
Exemple #8
0
 public SCardError Status(out string[] readerName, out SCardState state, out SCardProtocol protocol, out byte[] atr)
 {
     throw new NotImplementedException();
 }
Exemple #9
0
        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
        }