Ejemplo n.º 1
0
        public byte[] GetAttribute(uint attribId)
        {
            if (_hContext == IntPtr.Zero)
            {
                throw new SCardException("No card reader context established.  Must call SCard.EstablishContext() first.");
            }
            if (_hCard == IntPtr.Zero)
            {
                throw new SCardException("Not connected to card. Must call SCard.Connect() method first.");
            }

            byte[] attr    = null;
            UInt32 attrLen = 0;

            // call get attrib to locate the attribute and receive the size of
            // the buffer that needs to be allocated
            int rtn = SCardDll.SCardGetAttrib(_hCard, attribId, attr, ref attrLen);

            EvalReturnCode(rtn);

            if (attrLen != 0)
            {
                // allocate the buffer based on size returned by previous call
                attr = new byte[attrLen];
                // call again to get the actual data this time copied into our buffer
                int rtn2 = SCardDll.SCardGetAttrib(_hCard, attribId, attr, ref attrLen);
                EvalReturnCode(rtn2);
            }

            return(attr);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Terminates a connection previously opened between the calling application and a smart card in the target reader.
 /// </summary>
 /// <param name="disposition">Action to take on the card in the connected reader on close.</param>
 public void Disconnect(DispositionOptions disposition)
 {
     if (_hCard != IntPtr.Zero)
     {
         int rtn = SCardDll.SCardDisconnect(_hCard, (UInt32)disposition);
         EvalReturnCode(rtn);
         _hCard = IntPtr.Zero;
     }
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Closes an established resource manager context, freeing any resources allocated under that context.
 /// </summary>
 public void ReleaseContext()
 {
     if (_hContext != IntPtr.Zero)
     {
         int rtn = SCardDll.SCardReleaseContext(_hContext);
         EvalReturnCode(rtn);
         _hContext = IntPtr.Zero;
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Establishes the resource manager context (the scope) within which database operations are performed.
        /// </summary>
        /// <param name="Scope">Scope of the resource manager context.</param>
        public void EstablishContext(ScopeOptions Scope)
        {
            if (_hContext != IntPtr.Zero)
            {
                throw new SCardException("Context already established.  Must call SCard.ReleaseContext() first.");
            }
            IntPtr hContext = IntPtr.Zero;
            int    rtn      = SCardDll.SCardEstablishContext((UInt32)Scope, IntPtr.Zero, IntPtr.Zero, ref hContext);

            EvalReturnCode(rtn);
            _hContext = hContext;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Completes a previously declared transaction, allowing other applications to resume interactions with the card.
        /// </summary>
        /// <param name="disposition">Action to take on the card in the connected reader on close.</param>
        public void EndTransaction(DispositionOptions disposition)
        {
            if (_hContext == IntPtr.Zero)
            {
                throw new SCardException("No card reader context established.  Must call SCard.EstablishContext() first.");
            }
            if (_hCard == IntPtr.Zero)
            {
                throw new SCardException("Not connected to card. Must call SCard.Connect() method first.");
            }
            int rtn = SCardDll.SCardEndTransaction(_hCard, (UInt32)disposition);

            EvalReturnCode(rtn);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Establishes a connection (using a specific resource manager context) between the calling application and a smart card contained by a specific reader. If no card exists in the specified reader, an error is returned.
        /// </summary>
        /// <param name="readerName">The name of the reader that contains the target card.</param>
        /// <param name="shareMode">A flag that indicates whether other applications may form connections to the card.</param>
        /// <param name="preferredProtocols">A bitmask of acceptable protocols for the connection. Possible values may be combined with the OR operation.</param>
        public void Connect(string readerName, ShareModeOptions shareMode, ProtocolOptions preferredProtocols)
        {
            if (_hContext == IntPtr.Zero)
            {
                throw new SCardException("No card reader context established.  Must call SCard.EstablishContext() first.");
            }
            if (_hCard != IntPtr.Zero)
            {
                throw new SCardException("Already connected to card.  Must call SCard.Disconnect() first.");
            }
            IntPtr hCard = IntPtr.Zero;
            int    rtn   = SCardDll.SCardConnectA(_hContext, readerName, (UInt32)shareMode, (UInt32)preferredProtocols, ref hCard, ref _protocol);

            EvalReturnCode(rtn);
            _hCard = hCard;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Sends a service request to the smart card and expects to receive data back from the card.
        /// </summary>
        /// <param name="apdu">The SmartCard ADPU command and response object.</param>
        /// <returns>adpu</returns>
        public SCardAdpu Transmit(SCardAdpu apdu)
        {
            if (_hContext == IntPtr.Zero)
            {
                throw new SCardException("No card reader context established.  Must call SCard.EstablishContext() first.");
            }
            if (_hCard == IntPtr.Zero)
            {
                throw new SCardException("Not connected to card. Must call SCard.Connect() method first.");
            }

            byte[] send    = apdu.GetSendBuffer();
            byte[] recv    = new byte[apdu.GetReceiveBufferSize()];
            int    recvLen = recv.Length; // this is an in/out value

            SCARD_IO_REQUEST ioRequest = new SCARD_IO_REQUEST();

            ioRequest.dwProtocol  = (uint)_protocol;
            ioRequest.cbPciLength = 8;
            IntPtr pioRecvPci = IntPtr.Zero;

            Debug.WriteLine("SCardTransmit-ADPU-send: " + ArrayUtils.HexEncode(send));

            int rtn = SCardDll.SCardTransmit(_hCard, ref ioRequest, ref send[0], send.Length, pioRecvPci, ref recv[0], ref recvLen);

            EvalReturnCode(rtn);

            // resize the array if the bytes received are less than the buffer size
            if (recvLen < recv.Length)
            {
                Array.Resize <byte>(ref recv, (int)recvLen);
            }

            Debug.WriteLine("SCardTransmit-ADPU-recv: " + ArrayUtils.HexEncode(recv));

            // update the apdu object with the receive data
            apdu.SetReceiveData(recv);

            return(apdu);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Provides the list of named smart cards previously introduced to the system by the user.
        /// </summary>
        /// <remarks>SmartCards may not be available by Windows when accessing the machine via terminal services.</remarks>
        /// <returns>An array of strings contains the name of each SmartCard.</returns>
        public string[] ListCards()
        {
            if (_hContext == IntPtr.Zero)
            {
                throw new SCardException("No card reader context established.  Must call SCard.EstablishContext() first.");
            }

            // make the first call to get the size of the string we need to allocate and use in the second call
            UInt32 pchCards = 0;
            int    rtn1     = SCardDll.SCardListCardsA(_hContext, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref pchCards);

            EvalReturnCode(rtn1);

            IntPtr        szListCards = IntPtr.Zero;
            StringBuilder b           = new StringBuilder();

            try
            {
                // allocate an unmanaged string
                szListCards = Marshal.AllocHGlobal((int)pchCards);
                int rtn2 = SCardDll.SCardListCardsA(_hContext, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, szListCards, ref pchCards);
                EvalReturnCode(rtn2);

                for (int i = 0; i < pchCards; i++)
                {
                    b.Append((char)Marshal.ReadByte(szListCards, i));
                }
            }
            finally
            {
                if (szListCards != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(szListCards);
                }
            }

            return(b.ToString().Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries));
        }