Ejemplo n.º 1
0
        public static ApduOperationResult IsApduSuccessful(ApduResponse response)
        {
            var baseOperationResult = GetErrorMessage(response.ReturnCode);
            var apduOperationStatus = Check90_00(response.RecvBuff, response.ResponseLength);

            return new ApduOperationResult(baseOperationResult, apduOperationStatus);
        }
Ejemplo n.º 2
0
        private ApduResponse SendAPDU(Card card, byte[] bytesToSend, int expectedRequestLength)
        {
            Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU started");
            Logger.TraceEvent(TraceEventType.Verbose, 0, "bytesToSend: {0}", BitConverter.ToString(bytesToSend));
            Logger.TraceEvent(TraceEventType.Verbose, 0, "card connection handle: {0}", card.ConnectionHandle);
            Logger.Flush();

            IntPtr cardConnectionHandle = card.ConnectionHandle;

            // establish a new temporary connection in case of context mismatch
            if (card.ThreadId != Thread.CurrentThread.ManagedThreadId)
            {
                Logger.TraceEvent(TraceEventType.Verbose, 0,
                    string.Format("Card context mismatch. Original thread: {0}. Current thread: {1}",
                    card.ThreadId,
                    Thread.CurrentThread.ManagedThreadId));
                Logger.Flush();

                if (!_cardConnectionManager.IsConnectionExist(card.InternalUid, Thread.CurrentThread.ManagedThreadId))
                {
                    // establish a new connection
                    var connectionResult = Connect(card.CardreaderName, card.InternalUid);
                    if (!connectionResult.IsSuccessful)
                    {
                        return new ApduResponse
                                    {
                                        ReturnCode = connectionResult.StatusCode,
                                        RecvBuff = new byte[0],
                                        ResponseLength = 0
                                    };
                    }

                    // use a handle of a new connection
                    cardConnectionHandle = connectionResult.ConnectedCard.ConnectionHandle;

                    Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU: new connection established. Handle: "
                                                                    + cardConnectionHandle);
                }
                else
                {
                    cardConnectionHandle = _cardConnectionManager
                        .GetConnection(card.InternalUid, Thread.CurrentThread.ManagedThreadId);

                    Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU: existed card context found. Handle: "
                                                                    + cardConnectionHandle);
                }
            }

            var recvBuff = new byte[500];

            WinscardWrapper.SCARD_IO_REQUEST pioSendRequest;
            pioSendRequest.dwProtocol = card.Protocol;
            pioSendRequest.cbPciLength = PciLength;

            int returnCode = WinscardWrapper.SCardTransmit(
                cardConnectionHandle, ref pioSendRequest,
                ref bytesToSend[0], bytesToSend.Length,
                ref pioSendRequest, ref recvBuff[0],
                ref expectedRequestLength);

            Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU ended. Return code: " + returnCode);
            Logger.Flush();

            //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379804(v=vs.85).aspx
            //The pcbRecvLength should be at least n+2 and will be set to n+2 upon return.

            var result = new ApduResponse
            {
                RecvBuff = recvBuff,
                ResponseLength = expectedRequestLength,
                ReturnCode = returnCode
            };

            return result;
        }