/// <summary>
        /// Wraps the PCSC function
        /// LONG SCardReleaseContext(
        ///		IN SCARDCONTEXT hContext
        ///	);
        /// </summary>
        public void ReleaseContext()
        {
            if (PCSC.SCardIsValidContext(context) == PCSC.SCARD_S_SUCCESS)
            {
                lastError = PCSC.SCardReleaseContext(context);
                ThrowSmartcardException("SCardReleaseContext", lastError);

                context = IntPtr.Zero;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Wraps the PCSC function
        /// LONG SCardReleaseContext(
        ///		IN SCARDCONTEXT hContext
        ///	);
        /// </summary>
        private static void ReleaseContext(IntPtr hContext)
        {
            if (PCSC.SCardIsValidContext(hContext) == PCSC.SCARD_S_SUCCESS)
            {
                int lastError = PCSC.SCardReleaseContext(hContext);
                ThrowSmartcardException("SCardReleaseContext", lastError);

                //Marshal.FreeHGlobal(hContext);
                hContext = IntPtr.Zero;
            }
        }
        /// <summary>
        /// This function must implement a card detection mechanism.
        ///
        /// When card insertion is detected, it must call the method CardInserted()
        /// When card removal is detected, it must call the method CardRemoved()
        ///
        /// </summary>
        protected override void RunCardDetection(string reader)
        {
            bool   bFirstLoop = true;
            IntPtr hContext   = IntPtr.Zero;  // Local context
            IntPtr phContext;

            phContext = Marshal.AllocHGlobal(Marshal.SizeOf(hContext));

            if (PCSC.SCardEstablishContext((uint)SCOPE.User, IntPtr.Zero, IntPtr.Zero, phContext) == 0)
            {
                hContext = Marshal.ReadIntPtr(phContext);
                Marshal.FreeHGlobal(phContext);

                UInt32 nbReaders = 1;
                PCSC.SCard_ReaderState[] readerState = new PCSC.SCard_ReaderState[nbReaders];

                readerState[0].CurrentState = (UInt32)PCSC.CARD_STATE.UNAWARE;
                readerState[0].Reader       = reader;

                UInt32 eventState;
                UInt32 currentState = readerState[0].CurrentState;

                // Card detection loop
                do
                {
                    if (PCSC.SCardGetStatusChange(hContext, WAIT_TIME
                                                  , readerState, nbReaders) == 0)
                    {
                        eventState   = readerState[0].EventState;
                        currentState = readerState[0].CurrentState;

                        if (bFirstLoop)
                        {
                            // Check if a card is already inserted
                            if ((eventState & (uint)PCSC.CARD_STATE.PRESENT) == (uint)PCSC.CARD_STATE.PRESENT)
                            {
                                CardInserted(reader);
                            }
                        }
                        else if (((eventState & (uint)PCSC.CARD_STATE.CHANGED) == (uint)PCSC.CARD_STATE.CHANGED) && !bFirstLoop)
                        {
                            // State has changed
                            if ((eventState & (uint)PCSC.CARD_STATE.EMPTY) == (uint)PCSC.CARD_STATE.EMPTY)
                            {
                                // There is no card, card has been removed -> Fire CardRemoved event
                                CardRemoved((string)reader);
                            }

                            if (((eventState & (uint)PCSC.CARD_STATE.PRESENT) == (uint)PCSC.CARD_STATE.PRESENT) &&
                                ((eventState & (uint)PCSC.CARD_STATE.PRESENT) != (currentState & (uint)PCSC.CARD_STATE.PRESENT)))
                            {
                                // There is a card in the reader -> Fire CardInserted event
                                CardInserted(reader);
                            }

                            if ((eventState & (uint)PCSC.CARD_STATE.ATRMATCH) == (uint)PCSC.CARD_STATE.ATRMATCH)
                            {
                                // There is a card in the reader and it matches the ATR we were expecting-> Fire CardInserted event
                                CardInserted(reader);
                            }
                        }

                        // The current stateis now the event state
                        readerState[0].CurrentState = eventState;

                        bFirstLoop = false;
                    }

                    Thread.SpinWait(50000);

                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }
                }while (true);    // Exit on request
            }
            else
            {
                Marshal.FreeHGlobal(phContext);
                throw new Exception("PC/SC error");
            }

            PCSC.SCardReleaseContext(hContext);
            cancellationToken.ThrowIfCancellationRequested();
        }