コード例 #1
0
        /// <summary>
        /// Terminates all connections for given card.
        /// </summary>
        /// <remarks>
        /// The card very likely is not attached to the cardreader at the moment of execution,
        /// so SCARD_LEAVE_CARD is used here to avoid error log messages from underlying winscard api.
        /// </remarks>
        private OperationResult DisconnectCardMultiHandlesAware(Card cardForDisconnect)
        {
            var currentHandle = cardForDisconnect.ConnectionHandle;

            // disconnect first (current) handle
            var mainReturnCode       = WinscardWrapper.SCardDisconnect(cardForDisconnect.ConnectionHandle, WinscardWrapper.SCARD_LEAVE_CARD);
            var mainDisconnectResult = ReturnCodeManager.GetErrorMessage(mainReturnCode);

            Logger.TraceEvent(TraceEventType.Verbose, 0, "First handler disconnect result: {0}", mainDisconnectResult.StatusDescription);

            // disconnect the rest handles
            if (mainDisconnectResult.IsSuccessful)
            {
                var restHandlers = _cardConnectionManager.GetConnections(cardForDisconnect.InternalUid);

                Logger.TraceEvent(TraceEventType.Verbose, 0, "Card has {0} handlers", restHandlers.Length);

                foreach (var handleToDisconnect in restHandlers.Where(x => x != currentHandle))
                {
                    var returnCode = WinscardWrapper.SCardDisconnect(handleToDisconnect, WinscardWrapper.SCARD_LEAVE_CARD);
                    var result     = ReturnCodeManager.GetErrorMessage(returnCode);

                    Logger.TraceEvent(TraceEventType.Verbose, 0, "Card handler disconnect result: {0}", result.StatusDescription);
                }

                _cardConnectionManager.CardDisconnected(cardForDisconnect.InternalUid);
            }

            cardForDisconnect.ConnectionHandle = IntPtr.Zero;

            return(mainDisconnectResult);
        }
コード例 #2
0
        /// <summary>
        /// Establish Context of Resource Manager.
        /// </summary>
        public OperationResult EstablishContext()
        {
            lock (_locker)
            {
                if (_contextManager.IsContextExist(Thread.CurrentThread.ManagedThreadId))
                {
                    Logger.TraceEvent(TraceEventType.Verbose, 0, "Context is already established.");
                    Logger.Flush();

                    return(new OperationResult(true, WinscardWrapper.SCARD_S_SUCCESS, null, null));
                }

                IntPtr resourceManagerContext;
                IntPtr notUsed1 = IntPtr.Zero;
                IntPtr notUsed2 = IntPtr.Zero;

                int returnCode = WinscardWrapper.SCardEstablishContext(WinscardWrapper.SCARD_SCOPE_USER,
                                                                       notUsed1,
                                                                       notUsed2,
                                                                       out resourceManagerContext);

                if (returnCode == WinscardWrapper.SCARD_S_SUCCESS)
                {
                    Logger.TraceEvent(TraceEventType.Verbose, 0, "Context established");
                    Logger.Flush();

                    _contextManager.AddContext(Thread.CurrentThread.ManagedThreadId, resourceManagerContext);
                }

                return(ReturnCodeManager.GetErrorMessage(returnCode));
            }
        }
コード例 #3
0
        /// <summary>
        /// Returns a card's UID.
        /// </summary>
        public ReceiveCardIdResult GetCardId(Card cardToRead)
        {
            if (cardToRead == null)
            {
                throw new ArgumentNullException("cardToRead");
            }

            var bytesToSend = new byte[5];

            bytesToSend[0] = 0xFF;             // Class
            bytesToSend[1] = 0xCA;             // INS
            bytesToSend[2] = 0x00;             // P1
            bytesToSend[3] = 0x00;             // P2
            bytesToSend[4] = 0x00;             // LE:Full Length

            ApduResponse response = SendAPDU(cardToRead, bytesToSend, 10);

            const int responseCodeLength = 2;
            var       responseLengthWithoutResponseCodes = response.ResponseLength - responseCodeLength;

            var receiveCardIdResult = new ReceiveCardIdResult(ReturnCodeManager.IsApduSuccessful(response));

            if (receiveCardIdResult.IsCompletelySuccessful)
            {
                //read UID bytes from apdu response
                receiveCardIdResult.Bytes = response.RecvBuff.Take(responseLengthWithoutResponseCodes).ToArray();
            }

            return(receiveCardIdResult);
        }
コード例 #4
0
        /// <summary>
        /// The function provides the current status of a smart card in a reader.
        /// </summary>
        public OperationResult GetCardState(Card cardToRead)
        {
            if (cardToRead == null)
            {
                throw new ArgumentNullException("cardToRead");
            }

            var sizeOfReadersListStructure = 0;
            var cardStateStatus            = 0;
            var dwActProtocol = 0;
            var tmpAtrBytes   = new byte[257];
            var tmpAtrLen     = 32;

            var returnCode = WinscardWrapper.SCardStatus(cardToRead.ConnectionHandle, cardToRead.CardreaderName, ref sizeOfReadersListStructure, ref cardStateStatus, ref dwActProtocol, ref tmpAtrBytes[0], ref tmpAtrLen);

            OperationResult result = ReturnCodeManager.GetErrorMessage(returnCode);

            if (result.IsSuccessful)
            {
                cardToRead.State    = new CardState(cardStateStatus);
                cardToRead.Atr      = tmpAtrBytes.Take(tmpAtrLen).ToArray();
                cardToRead.Protocol = dwActProtocol;
            }

            return(result);
        }
コード例 #5
0
        public OperationResult WaitForChanges(ref CardreaderStatus[] statuses)
        {
            var resourceManagerContext = EstablishContextIfNotEstablished();

            var scardStatuses = new WinscardWrapper.SCARD_READERSTATE[statuses.Length];

            for (var i = 0; i < statuses.Length; i++)
            {
                scardStatuses[i] = statuses[i].ToScardStatus();
            }

            Logger.TraceEvent(TraceEventType.Verbose, 0, "SCardGetStatusChange started");
            Logger.Flush();

            var returnCode = WinscardWrapper.SCardGetStatusChange(
                resourceManagerContext,
                WinscardWrapper.INFINITE,
                scardStatuses,
                scardStatuses.Length);

            Logger.TraceEvent(TraceEventType.Verbose, 0, "SCardGetStatusChange ended");
            Logger.Flush();

            var operationResult = ReturnCodeManager.GetErrorMessage(returnCode);

            if (operationResult.IsSuccessful)
            {
                for (var i = 0; i < statuses.Length; i++)
                {
                    statuses[i].NewStatusFlags = scardStatuses[i].dwEventState;
                }
            }

            return(operationResult);
        }
コード例 #6
0
        private OperationResult ReleaseContext(IntPtr context)
        {
            int returnCode = WinscardWrapper.SCardReleaseContext(context);

            var operationResult = ReturnCodeManager.GetErrorMessage(returnCode);

            return(operationResult);
        }
コード例 #7
0
        public ApduOperationResult SetBuzzerOutputForCardDetection(Card card, bool shouldBuzzWhenCardDetected)
        {
            var bytesToSend = new byte[5];

            bytesToSend[0] = 0xFF;
            bytesToSend[1] = 0x00;
            bytesToSend[2] = 0x52;
            bytesToSend[3] = shouldBuzzWhenCardDetected ? (byte)0xFF : (byte)0x00;
            bytesToSend[4] = 0x00;

            const int responseCodeLength = 2;

            ApduResponse response = SendAPDU(card, bytesToSend, responseCodeLength);

            return(ReturnCodeManager.IsApduSuccessful(response));
        }
コード例 #8
0
        public ApduOperationResult UpdateLedAndBuzzer(Card card, byte ledState, byte t1, byte t2, byte repetitionNumber, byte buzzer)
        {
            var bytesToSend = new byte[9];

            bytesToSend[0] = 0xFF;
            bytesToSend[1] = 0x00;
            bytesToSend[2] = 0x40;
            bytesToSend[3] = ledState;
            bytesToSend[4] = 0x04;
            bytesToSend[5] = t1;
            bytesToSend[6] = t2;
            bytesToSend[7] = repetitionNumber;
            bytesToSend[8] = buzzer;

            const int responseCodeLength = 2;

            ApduResponse response = SendAPDU(card, bytesToSend, responseCodeLength);

            return(ReturnCodeManager.IsApduSuccessful(response));
        }
コード例 #9
0
        /// <summary>
        /// Return card readers list.
        /// </summary>
        public OperationResult GetCardReadersList(out string[] readersList)
        {
            var resourceManagerContext = EstablishContextIfNotEstablished();

            readersList = new string[0];

            OperationResult result;
            int             sizeOfReadersListStructure = 0;

            int returnCode = WinscardWrapper.SCardListReaders(resourceManagerContext, null, null, ref sizeOfReadersListStructure);

            if (returnCode != WinscardWrapper.SCARD_S_SUCCESS)
            {
                result = ReturnCodeManager.GetErrorMessage(returnCode);
            }
            else
            {
                // Fill reader list
                var cardReadersList = new byte[sizeOfReadersListStructure];
                returnCode = WinscardWrapper.SCardListReaders(resourceManagerContext, null, cardReadersList, ref sizeOfReadersListStructure);

                if (returnCode != WinscardWrapper.SCARD_S_SUCCESS)
                {
                    result = ReturnCodeManager.GetErrorMessage(returnCode);
                }
                else
                {
                    // Convert to strings
                    readersList = ConvertReadersBuffer(cardReadersList);

                    result = ReturnCodeManager.GetErrorMessage(returnCode);
                }
            }

            return(result);
        }
コード例 #10
0
        /// <summary>
        /// Establishing a connection to smart card contained by a specific reader.
        /// <param name="cardreaderName">Card reader name to connection.</param>
        /// </summary>
        public ConnectResult Connect(string cardreaderName, Guid?idOverride = null)
        {
            var resourceManagerContext = EstablishContextIfNotEstablished();

            IntPtr cardConnectionHandle;
            int    connectionProtocolType;

            int returnCode = WinscardWrapper.SCardConnect(
                resourceManagerContext,
                cardreaderName,
                WinscardWrapper.SCARD_SHARE_SHARED,
                WinscardWrapper.SCARD_PROTOCOL_T0 | WinscardWrapper.SCARD_PROTOCOL_T1,
                out cardConnectionHandle,
                out connectionProtocolType);

            var operationResult = ReturnCodeManager.GetErrorMessage(returnCode);
            var connectResult   = new ConnectResult(operationResult);

            if (operationResult.IsSuccessful)
            {
                var newCard = new Card(
                    Thread.CurrentThread.ManagedThreadId,
                    cardConnectionHandle,
                    cardreaderName,
                    connectionProtocolType);

                _cardConnectionManager.AddConnection(
                    idOverride ?? newCard.InternalUid,
                    Thread.CurrentThread.ManagedThreadId,
                    cardConnectionHandle);

                connectResult.ConnectedCard = newCard;
            }

            return(connectResult);
        }