/// <summary>
        /// The SCardTransmit function sends a service request to the smart card and expects to receive data back from the card.
        /// </summary>
        /// <param name="sendBuffer">
        /// The actual data to be written to the card.
        /// </param>
        /// <param name="sendLength">
        /// The length, in bytes, of the sendBuffer parameter.
        /// </param>
        /// <param name="responseBuffer">
        /// Returned data from the card.
        /// </param>
        /// <param name="responseLength">
        /// Supplies the length, in bytes, of the responseBuffer parameter and receives the actual
        /// number of bytes received from the smart card.
        /// </param>
        public void Transmit(byte[] sendBuffer, int sendLength, byte[] responseBuffer, ref int responseLength)
        {
            SCARD_IO_REQUEST SCARD_PCI;

            SCARD_PCI.dwProtocol  = (uint)activeSCardProtocol;
            SCARD_PCI.cbPciLength = 8;

            Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump("--> C-APDU: 0x", sendBuffer, sendLength, 16, ValueFormat.HexASCII));

            int ret = WinSCardAPIWrapper.SCardTransmit(phCARD, ref SCARD_PCI, sendBuffer,
                                                       sendLength,
                                                       IntPtr.Zero,
                                                       responseBuffer,
                                                       ref responseLength);

            if (ret == 0)
            {
                RespApdu respApdu = new RespApdu(responseBuffer, responseLength);
                Trace.WriteLineIf(scardTrace, respApdu.ToString());
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.Transmit", ret);
            }
        }
        /// <summary>
        /// The WaitForCardRemoval function blocks execution until there is no card in the reader.
        /// </summary>
        /// <param name="szReader">
        /// The name of the reader that contains the target card.
        /// </param>
        public void WaitForCardRemoval(string szReader)
        {
            int ret;

            SCARD_READERSTATE[] readerStates = new SCARD_READERSTATE[1];
            readerStates[0].m_szReader       = szReader;
            readerStates[0].m_dwEventState   = (uint)SCARD_CARD_STATE.UNAWARE;
            readerStates[0].m_dwCurrentState = (uint)SCARD_CARD_STATE.UNAWARE;

            ret = WinSCardAPIWrapper.SCardGetStatusChange(phContext, (uint)10, readerStates, (uint)1);
            if (ret != 0)
            {
                throw new WinSCardException(scardTrace, "SCard.Connect", ret);
            }

            if ((readerStates[0].m_dwEventState & (uint)SCARD_CARD_STATE.EMPTY) == (uint)SCARD_CARD_STATE.EMPTY)
            {
                return;
            }
            Trace.WriteLineIf(this.TraceSCard, "    Wait for card removal...");

            do
            {
                ret = WinSCardAPIWrapper.SCardGetStatusChange(phContext, (uint)10, readerStates, (uint)1);
                if (ret != 0)
                {
                    throw new WinSCardException(scardTrace, "SCard.Connect", ret);
                }
            } while ((readerStates[0].m_dwEventState & (uint)SCARD_CARD_STATE.EMPTY) != (uint)SCARD_CARD_STATE.EMPTY);
        }
示例#3
0
        // blocks until someone scans their card
        public void WaitForCardPresent(string szReader)
        {
            int ret;

            SCARD_READERSTATE[] readerStates = new SCARD_READERSTATE[1];
            readerStates[0].m_szReader       = szReader;
            readerStates[0].m_dwEventState   = (uint)SCARD_CARD_STATE.UNAWARE;
            readerStates[0].m_dwCurrentState = (uint)SCARD_CARD_STATE.UNAWARE;

            ret = WinSCardAPIWrapper.SCardGetStatusChange(phContext, (uint)10, readerStates, (uint)1);
            if (ret != 0)
            {
                throw new WinSCardException(scardTrace, "SCard.Connect", ret);
            }

            if ((readerStates[0].m_dwEventState & (uint)SCARD_CARD_STATE.PRESENT) == (uint)SCARD_CARD_STATE.PRESENT)
            {
                return;
            }
            Trace.WriteLineIf(this.TraceSCard, "    Wait for card present...");

            do
            {
                ret = WinSCardAPIWrapper.SCardGetStatusChange(phContext, (uint)10, readerStates, (uint)1);

                if (ret != 0)
                {
                    throw new WinSCardException(scardTrace, "SCard.Connect", ret);
                }

                //this is our event loop to simulate what would be an action listener
            } while ((readerStates[0].m_dwEventState & (uint)SCARD_CARD_STATE.PRESENT) != (uint)SCARD_CARD_STATE.PRESENT);
        }
        /// <summary>
        /// The EstablishContext function establishes the smart card resourete manager context.
        /// </summary>
        /// <param name="dwScope">
        /// Scope of the resource manager context.
        /// </param>
        public void EstablishContext(SCARD_SCOPE dwScope)
        {
            int ret = WinSCardAPIWrapper.SCardEstablishContext((uint)dwScope, IntPtr.Zero, IntPtr.Zero, out phContext);

            if (ret == 0)
            {
                Trace.WriteLineIf(scardTrace, string.Format("    SCard.EstablishContext({0})", (SCARD_SCOPE)dwScope));
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.EstablishContext", ret);
            }
        }
        /// <summary>
        /// The SCardGetAttrib function gets the current reader attributes.
        /// It does not affect the state of the reader, driver, or card.
        /// </summary>
        /// <param name="attrId">
        /// Identifier for the attribute to get.
        /// </param>
        /// <param name="responseBuffer">
        /// The response buffer.
        /// </param>
        /// <param name="responseLength">
        /// Supplies the length of the responseBuffer in bytes, and receives the actual length
        /// of the received attribute.
        /// </param>
        public void GetAttrib(uint attrId, byte[] responseBuffer, ref int responseLength)
        {
            Trace.WriteLineIf(this.scardTrace, string.Format("    SCard.SCardGetAttrib(AttrId: {0})", (SCARD_ATTR)attrId));

            int ret = WinSCardAPIWrapper.SCardGetAttrib(phCARD, (uint)attrId, responseBuffer, ref responseLength);

            if (ret == 0)
            {
                Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump("        Attr. Value: 0x", responseBuffer, responseLength, 16, ValueFormat.HexASCII));
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.Control", ret);
            }
        }
        /// <summary>
        /// The SCardReconnect function reestablishes an existing connection between the calling application and
        /// a smart card. This function moves a card handle from direct access to general access, or acknowledges
        /// and clears an error condition that is preventing further access to the card.
        /// </summary>
        /// <param name="dwShareMode">
        /// A flag that indicates whether other applications may form connections to the card.
        /// </param>
        /// <param name="dwPrefProtocol">
        /// A bitmask of acceptable protocols for the connection. Possible values may be combined with the OR operation.
        /// </param>
        /// <param name="disconnectAction">
        /// Action to take on the card in the connected reader on close.
        /// </param>
        /// <returns>
        /// If the function succeeds, the function returns SCARD_S_SUCCESS.
        /// If the function fails, it returns an error code.
        /// </returns>
        public void Reconnect(SCARD_SHARE_MODE dwShareMode, SCARD_PROTOCOL dwPrefProtocol, SCARD_DISCONNECT disconnectAction)
        {
            int ret = WinSCardAPIWrapper.SCardReconnect(phCARD, (uint)dwShareMode, (uint)dwPrefProtocol,
                                                        (uint)disconnectAction, out activeSCardProtocol);

            if (ret == 0)
            {
                Trace.WriteLineIf(scardTrace, String.Format("    SCard.Reconnect(SHARE_MODE.{0}, SCARD_PROTOCOL.{1}, SCARD_DISCONNECT.{2} )",
                                                            dwShareMode, (SCARD_PROTOCOL)dwPrefProtocol, (SCARD_DISCONNECT)disconnectAction));
                Trace.WriteLineIf(scardTrace, String.Format("        Active Protocol: SCARD_PROTOCOL.{0} ", (SCARD_PROTOCOL)activeSCardProtocol));
                Trace.WriteLineIf(this.TraceSCard, HexFormatting.Dump("        ATR: 0x", this.Atr, this.Atr.Length, 24));
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.Reconnect", ret);
            }
        }
        /// <summary>
        /// The SCardConnect function 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="szReader">
        /// The name of the reader that contains the target card.
        /// </param>
        /// <param name="dwShareMode">
        /// A flag that indicates whether other applications may form connections to the card.
        /// </param>
        /// <param name="dwPrefProtocol">
        /// A bitmask of acceptable protocols for the connection. Possible values may be combined with the OR operation.
        /// </param>
        public void Connect(string szReader, SCARD_SHARE_MODE dwShareMode, SCARD_PROTOCOL dwPrefProtocol)
        {
            int ret = WinSCardAPIWrapper.SCardConnect(phContext, szReader, (uint)dwShareMode, (uint)dwPrefProtocol, out phCARD, out activeSCardProtocol);

            if (ret == 0)
            {
                connectedReaderName = szReader;
                Trace.WriteLineIf(scardTrace, String.Format("    SCard.Connect({0}, SHARE_MODE.{1}, SCARD_PROTOCOL.{2})",
                                                            szReader, dwShareMode, (SCARD_PROTOCOL)dwPrefProtocol));
                Trace.WriteLineIf(scardTrace, String.Format("        Active Protocol: SCARD_PROTOCOL.{0} ", (SCARD_PROTOCOL)activeSCardProtocol));
                Trace.WriteLineIf(this.TraceSCard, HexFormatting.Dump("        ATR: 0x", this.Atr, this.Atr.Length, 24));
            }
            else
            {
                connectedReaderName = null;
                throw new WinSCardException(scardTrace, "SCard.Connect", ret);
                //Trace.WriteLineIf(pcscTrace, String.Format("    Error: SCardConnect failed with 0x{0:X8}.", ret));
            }
        }
        /// <summary>
        /// The SCardListReaders function provides the list of readers.
        /// </summary>
        /// <returns>
        /// The names of available readers.
        /// </returns>
        public string[] ListReaders()
        {
            try
            {
                int pcchReaders = 0;
                readerStrings = null;

                // Get first the mszReaders buffer length
                int ret = WinSCardAPIWrapper.SCardListReaders(phContext, null, null, ref pcchReaders);

                if (ret == 0)
                {
                    byte[] mszReaders = new byte[pcchReaders];

                    // Get list of readers
                    ret = WinSCardAPIWrapper.SCardListReaders(phContext, null, mszReaders, ref pcchReaders);

                    if (ret == 0)
                    {
                        Trace.WriteLineIf(scardTrace, "    SCard.ListReaders...");

                        if (pcchReaders > 2)
                        {
                            readerStrings = System.Text.Encoding.ASCII.GetString(mszReaders).Substring(0, pcchReaders - 2).Split('\0');

                            for (int i = 0; i < readerStrings.Length; i++)
                            {
                                Trace.WriteLineIf(scardTrace, string.Format("        Reader {0:#0}: {1}", i, readerStrings[i]));
                            }
                        }
                    }
                    return(readerStrings);
                }
                else
                {
                    throw new WinSCardException(scardTrace, "SCard.ListReaders", ret);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// The SCardReleaseContext function closes an established resource manager context,
        /// freeing any resources allocated under that context.
        /// </summary>
        /// <returns>
        /// If the function succeeds, the function returns SCARD_S_SUCCESS.
        /// If the function fails, it returns an error code.
        /// </returns>
        public void ReleaseContext()
        {
            connectedReaderName = null;


            if (this.phContext != (IntPtr)0)
            {
                int ret = WinSCardAPIWrapper.SCardReleaseContext(phContext);
                this.phContext = (IntPtr)0;

                if (ret == 0)
                {
                    Trace.WriteLineIf(scardTrace, "    SCard.ReleaseContext...");
                }
                else
                {
                    throw new WinSCardException(scardTrace, "SCard.ReleaseContext", ret);
                }
            }
        }
示例#10
0
        /// <summary>
        /// The SCardDisconnect function 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>
        /// <returns>
        /// If the function succeeds, the function returns SCARD_S_SUCCESS.
        /// If the function fails, it returns an error code.
        /// </returns>
        public void Disconnect(SCARD_DISCONNECT disposition)
        {
            connectedReaderName = null;

            if (this.phCARD != (IntPtr)0)
            {
                int ret = WinSCardAPIWrapper.SCardDisconnect(phCARD, (uint)disposition);
                this.phCARD = (IntPtr)0;

                this.readerStrings = null;
                if (ret == 0)
                {
                    Trace.WriteLineIf(scardTrace, String.Format("    SCard.Disconnect(SCARD_DISCONNECT.{0})...", disposition));
                }
                else
                {
                    throw new WinSCardException(scardTrace, "SCard.Disconnect", ret);
                }
            }
        }
示例#11
0
        /// <summary>
        /// The SCardControl function gives you direct control of the reader.
        /// You can call it any time after a successful call to SCardConnect and before
        /// a successful call to SCardDisconnect. The effect on the state of the reader
        /// depends on the control code.
        /// </summary>
        /// <param name="dwControlCode">
        /// Control code for the operation. This value identifies the specific operation to be performed.
        /// </param>
        /// <param name="inBuffer">
        /// A buffer that contains the data required to perform the operation.
        /// This parameter can be null if the dwControlCode parameter specifies an operation that does
        /// not require input data.
        /// </param>
        /// <param name="inBufferLength">
        /// Length of the input buffer.
        /// </param>
        /// <param name="outBuffer">
        /// The output buffer.
        /// </param>
        /// <param name="outBufferSize">
        /// Size, in bytes, of the output buffer.
        /// </param>
        /// <param name="bytesReturned">
        /// Supplies the length, in bytes, of the outBuffer parameter.
        /// </param>
        public void Control(uint dwControlCode, byte[] inBuffer, int inBufferLength, byte[] outBuffer, int outBufferSize, ref int bytesReturned)
        {
            Trace.WriteLineIf(this.scardTrace, string.Format("    SCard.Control (Cntrl Code: 0x{0:X}", dwControlCode));
            //Trace.WriteLineIf( this.scardTrace, HexFormatting.Dump(string.Format( "--> SCard.Control (Cntrl Code: 0x{0:X} ): 0x",
            //                                                    dwControlCode ), inBuffer, inBufferLength, 16, ValueFormat.HexASCII ) );

            int ret = WinSCardAPIWrapper.SCardControl(phCARD,
                                                      dwControlCode,
                                                      inBuffer,
                                                      inBufferLength,
                                                      outBuffer,
                                                      outBufferSize,
                                                      ref bytesReturned);

            if (ret == 0)
            {
                Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump("        Value: 0x", outBuffer, bytesReturned, 16, ValueFormat.HexASCII));
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.Control", ret);
            }
        }
示例#12
0
        /// <summary>
        /// Gets a value indicating whether smart card is present.
        /// </summary>
        /// <param name="szReader">
        /// The name of the reader that contains the target card.
        /// </param>
        /// <value><c>true</c> if [card activated]; otherwise, <c>false</c>.</value>
        public bool GetCardPresentState(string szReader)
        {
            int ret;

            SCARD_READERSTATE[] readerStates = new SCARD_READERSTATE[1];
            readerStates[0].m_szReader       = szReader;
            readerStates[0].m_dwEventState   = (uint)SCARD_CARD_STATE.UNAWARE;
            readerStates[0].m_dwCurrentState = (uint)SCARD_CARD_STATE.UNAWARE;

            ret = WinSCardAPIWrapper.SCardGetStatusChange(phContext, (uint)100, readerStates, (uint)1);
            if (ret != 0)
            {
                throw new WinSCardException(scardTrace, "SCard.Connect", ret);
            }

            if ((readerStates[0].m_dwEventState & (uint)SCARD_CARD_STATE.PRESENT) == (uint)SCARD_CARD_STATE.PRESENT)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }