Advertisement
Guest User

CardNative.cs

a guest
Aug 22nd, 2010
971
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 19.53 KB | None | 0 0
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Text;
  4. using System.Threading;
  5.  
  6. namespace GemCard
  7. {
  8.     /// <summary>
  9.     /// CARD_STATE enumeration, used by the PC/SC function SCardGetStatusChanged
  10.     /// </summary>
  11.     enum CARD_STATE
  12.     {
  13.         UNAWARE = 0x00000000,
  14.         IGNORE = 0x00000001,
  15.         CHANGED = 0x00000002,
  16.         UNKNOWN = 0x00000004,
  17.         UNAVAILABLE = 0x00000008,
  18.         EMPTY = 0x00000010,
  19.         PRESENT = 0x00000020,
  20.         ATRMATCH = 0x00000040,
  21.         EXCLUSIVE = 0x00000080,
  22.         INUSE = 0x00000100,
  23.         MUTE = 0x00000200,
  24.         UNPOWERED = 0x00000400
  25.     }
  26.  
  27.     /// <summary>
  28.     /// Wraps the SCARD_IO_STRUCTURE
  29.     ///  
  30.     /// </summary>
  31.     [StructLayout(LayoutKind.Sequential)]
  32.     public struct   SCard_IO_Request
  33.     {
  34.         public UInt32   m_dwProtocol;
  35.         public UInt32   m_cbPciLength;
  36.     }
  37.  
  38.  
  39.     /// <summary>
  40.     /// Wraps theSCARD_READERSTATE structure of PC/SC
  41.     /// </summary>
  42.     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  43.     public struct SCard_ReaderState
  44.     {
  45.         public string m_szReader;
  46.         public IntPtr m_pvUserData;
  47.         public UInt32 m_dwCurrentState;
  48.         public UInt32 m_dwEventState;
  49.         public UInt32 m_cbAtr;
  50.         [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
  51.         public byte[] m_rgbAtr;
  52.     }
  53.    
  54.     /// <summary>
  55.     /// Implementation of ICard using native (P/Invoke) interoperability for PC/SC
  56.     /// </summary>
  57.     public class CardNative : CardBase
  58.     {
  59.         private IntPtr m_hContext = IntPtr.Zero;
  60.         private IntPtr m_hCard = IntPtr.Zero;
  61.         private UInt32  m_nProtocol = (uint) PROTOCOL.T0;
  62.         private int m_nLastError = 0;
  63.         const int SCARD_S_SUCCESS = 0;
  64.  
  65.         #region PCSC_FUNCTIONS
  66.         /// <summary>
  67.         /// Native SCardGetStatusChanged from winscard.dll
  68.         /// </summary>
  69.         /// <param name="hContext"></param>
  70.         /// <param name="dwTimeout"></param>
  71.         /// <param name="rgReaderStates"></param>
  72.         /// <param name="cReaders"></param>
  73.         /// <returns></returns>
  74.         [DllImport("winscard.dll", SetLastError = true)]
  75.         internal static extern int SCardGetStatusChange(IntPtr hContext,
  76.             UInt32 dwTimeout,
  77.             [In,Out] SCard_ReaderState[] rgReaderStates,
  78.             UInt32 cReaders);
  79.  
  80.         /// <summary>
  81.         /// Native SCardListReaders function from winscard.dll
  82.         /// </summary>
  83.         /// <param name="hContext"></param>
  84.         /// <param name="mszGroups"></param>
  85.         /// <param name="mszReaders"></param>
  86.         /// <param name="pcchReaders"></param>
  87.         /// <returns></returns>
  88.         [DllImport("winscard.dll", SetLastError=true)]
  89.         internal static extern int SCardListReaders(IntPtr hContext,
  90.             [MarshalAs(UnmanagedType.LPTStr)] string mszGroups,
  91.             IntPtr mszReaders,
  92.             out UInt32 pcchReaders);
  93.  
  94.         /// <summary>
  95.         /// Native SCardEstablishContext function from winscard.dll
  96.         /// </summary>
  97.         /// <param name="dwScope"></param>
  98.         /// <param name="pvReserved1"></param>
  99.         /// <param name="pvReserved2"></param>
  100.         /// <param name="phContext"></param>
  101.         /// <returns></returns>
  102.         [DllImport("winscard.dll", SetLastError=true)]
  103.         internal    static  extern  int SCardEstablishContext(UInt32 dwScope,
  104.             IntPtr pvReserved1,
  105.             IntPtr pvReserved2,
  106.             IntPtr phContext);
  107.  
  108.         /// <summary>
  109.         /// Native SCardReleaseContext function from winscard.dll
  110.         /// </summary>
  111.         /// <param name="hContext"></param>
  112.         /// <returns></returns>
  113.         [DllImport("winscard.dll", SetLastError=true)]
  114.         internal static extern int SCardReleaseContext(IntPtr hContext);
  115.  
  116.         /// <summary>
  117.         /// Native SCardIsValidContext function from winscard.dll
  118.         /// </summary>
  119.         /// <param name="hContext"></param>
  120.         /// <returns></returns>
  121.         [DllImport("winscard.dll", SetLastError = true)]
  122.         internal static extern int SCardIsValidContext(IntPtr hContext);
  123.  
  124.         /// <summary>
  125.         /// Native SCardConnect function from winscard.dll
  126.         /// </summary>
  127.         /// <param name="hContext"></param>
  128.         /// <param name="szReader"></param>
  129.         /// <param name="dwShareMode"></param>
  130.         /// <param name="dwPreferredProtocols"></param>
  131.         /// <param name="phCard"></param>
  132.         /// <param name="pdwActiveProtocol"></param>
  133.         /// <returns></returns>
  134.         [DllImport("winscard.dll", SetLastError=true, CharSet=CharSet.Auto)]
  135.         internal static extern int SCardConnect(IntPtr hContext,
  136.             [MarshalAs(UnmanagedType.LPTStr)] string szReader,
  137.             UInt32  dwShareMode,
  138.             UInt32  dwPreferredProtocols,
  139.             IntPtr  phCard,
  140.             IntPtr  pdwActiveProtocol);
  141.  
  142.         /// <summary>
  143.         /// Native SCardDisconnect function from winscard.dll
  144.         /// </summary>
  145.         /// <param name="hCard"></param>
  146.         /// <param name="dwDisposition"></param>
  147.         /// <returns></returns>
  148.         [DllImport("winscard.dll", SetLastError=true)]
  149.         internal static extern int SCardDisconnect(IntPtr hCard,
  150.             UInt32 dwDisposition);
  151.  
  152.         /// <summary>
  153.         /// Native SCardTransmit function from winscard.dll
  154.         /// </summary>
  155.         /// <param name="hCard"></param>
  156.         /// <param name="pioSendPci"></param>
  157.         /// <param name="pbSendBuffer"></param>
  158.         /// <param name="cbSendLength"></param>
  159.         /// <param name="pioRecvPci"></param>
  160.         /// <param name="pbRecvBuffer"></param>
  161.         /// <param name="pcbRecvLength"></param>
  162.         /// <returns></returns>
  163.         [DllImport("winscard.dll", SetLastError=true)]
  164.         internal static extern int SCardTransmit(IntPtr hCard,
  165.             [In] ref SCard_IO_Request pioSendPci,
  166.             byte[] pbSendBuffer,
  167.             UInt32 cbSendLength,
  168.             IntPtr pioRecvPci,
  169.             [Out] byte[] pbRecvBuffer,
  170.             out UInt32 pcbRecvLength
  171.             );
  172.  
  173.         /// <summary>
  174.         /// Native SCardBeginTransaction function of winscard.dll
  175.         /// </summary>
  176.         /// <param name="hContext"></param>
  177.         /// <returns></returns>
  178.         [DllImport("winscard.dll", SetLastError = true)]
  179.         internal static extern int SCardBeginTransaction(IntPtr hContext);
  180.  
  181.         /// <summary>
  182.         /// Native SCardEndTransaction function of winscard.dll
  183.         /// </summary>
  184.         /// <param name="hContext"></param>
  185.         /// <returns></returns>
  186.         [DllImport("winscard.dll", SetLastError = true)]
  187.         internal static extern int SCardEndTransaction(IntPtr hContext, UInt32 dwDisposition);
  188.  
  189.         [DllImport("winscard.dll", SetLastError = true)]
  190.         internal static extern int SCardGetAttrib(IntPtr hCard,
  191.             UInt32 dwAttribId,
  192.             [Out] byte[] pbAttr,
  193.             out UInt32 pcbAttrLen);
  194.  
  195.         #endregion WINSCARD_FUNCTIONS
  196.  
  197.         /// <summary>
  198.         /// Default constructor
  199.         /// </summary>
  200.         public CardNative()
  201.         {
  202.         }
  203.  
  204.         /// <summary>
  205.         /// Object destruction
  206.         /// </summary>
  207.         ~CardNative()
  208.         {
  209.             Disconnect(DISCONNECT.Unpower);
  210.  
  211.             ReleaseContext();
  212.         }
  213.  
  214.         #region ICard Members
  215.  
  216.         /// <summary>
  217.         /// Wraps the PCSC function
  218.         /// LONG SCardListReaders(SCARDCONTEXT hContext,
  219.         ///     LPCTSTR mszGroups,
  220.         ///     LPTSTR mszReaders,
  221.         ///     LPDWORD pcchReaders
  222.         /// );
  223.         /// </summary>
  224.         /// <returns>A string array of the readers</returns>
  225.         public  override string[]   ListReaders()
  226.         {
  227.             EstablishContext(SCOPE.User);
  228.  
  229.             string[]    sListReaders = null;
  230.             UInt32 pchReaders = 0;
  231.             IntPtr  szListReaders = IntPtr.Zero;
  232.  
  233.             m_nLastError = SCardListReaders(m_hContext, null, szListReaders, out pchReaders);
  234.             if (m_nLastError == 0)
  235.             {
  236.                 szListReaders = Marshal.AllocHGlobal((int) pchReaders);
  237.                 m_nLastError = SCardListReaders(m_hContext, null, szListReaders, out pchReaders);
  238.                 if (m_nLastError == 0)
  239.                 {
  240.                     char[] caReadersData = new char[pchReaders];
  241.                     int nbReaders = 0;
  242.                     for (int nI = 0; nI < pchReaders; nI++)
  243.                     {
  244.                         caReadersData[nI] = (char) Marshal.ReadByte(szListReaders, nI);
  245.  
  246.                         if (caReadersData[nI] == 0)
  247.                             nbReaders++;
  248.                     }
  249.  
  250.                     // Remove last 0
  251.                     --nbReaders;
  252.  
  253.                     if (nbReaders != 0)
  254.                     {
  255.                         sListReaders = new string[nbReaders];
  256.                         char[] caReader = new char[pchReaders];
  257.                         int nIdx = 0;
  258.                         int nIdy = 0;
  259.                         int nIdz = 0;
  260.                         // Get the nJ string from the multi-string
  261.  
  262.                         while(nIdx < pchReaders - 1)
  263.                         {
  264.                             caReader[nIdy] = caReadersData[nIdx];
  265.                             if (caReader[nIdy] == 0)
  266.                             {
  267.                                 sListReaders[nIdz] = new string(caReader, 0, nIdy);
  268.                                 ++nIdz;
  269.                                 nIdy = 0;
  270.                                 caReader = new char[pchReaders];
  271.                             }
  272.                             else
  273.                                 ++nIdy;
  274.  
  275.                             ++nIdx;
  276.                         }
  277.                     }
  278.  
  279.                 }
  280.  
  281.                 Marshal.FreeHGlobal(szListReaders);
  282.             }
  283.  
  284.             ReleaseContext();
  285.  
  286.             return sListReaders;
  287.         }
  288.  
  289.         /// <summary>
  290.         /// Wraps the PCSC function
  291.         /// LONG SCardEstablishContext(
  292.         ///     IN DWORD dwScope,
  293.         ///     IN LPCVOID pvReserved1,
  294.         ///     IN LPCVOID pvReserved2,
  295.         ///     OUT LPSCARDCONTEXT phContext
  296.         /// );
  297.         /// </summary>
  298.         /// <param name="Scope"></param>
  299.         public void EstablishContext(SCOPE Scope)
  300.         {
  301.             IntPtr hContext = Marshal.AllocHGlobal(Marshal.SizeOf(m_hContext));
  302.  
  303.             m_nLastError = SCardEstablishContext((uint) Scope, IntPtr.Zero, IntPtr.Zero, hContext);
  304.             if (m_nLastError != 0)
  305.             {
  306.                 string msg = "SCardEstablishContext error: " + m_nLastError;
  307.  
  308.                 Marshal.FreeHGlobal(hContext);
  309.                 throw new Exception(msg);
  310.             }
  311.  
  312.             m_hContext = Marshal.ReadIntPtr(hContext);
  313.  
  314.             Marshal.FreeHGlobal(hContext);
  315.         }
  316.  
  317.  
  318.         /// <summary>
  319.         /// Wraps the PCSC function
  320.         /// LONG SCardReleaseContext(
  321.         ///     IN SCARDCONTEXT hContext
  322.         /// );
  323.         /// </summary>
  324.         public void ReleaseContext()
  325.         {
  326.             if (SCardIsValidContext(m_hContext) == SCARD_S_SUCCESS)
  327.             {
  328.                 m_nLastError = SCardReleaseContext(m_hContext);
  329.  
  330.                 if (m_nLastError != 0)
  331.                 {
  332.                     string  msg = "SCardReleaseContext error: " + m_nLastError;
  333.                     throw new Exception(msg);
  334.                 }
  335.  
  336.                 m_hContext = IntPtr.Zero;
  337.             }
  338.         }
  339.  
  340.         /// <summary>
  341.         ///  Wraps the PCSC function
  342.         ///  LONG SCardConnect(
  343.         ///     IN SCARDCONTEXT hContext,
  344.         ///     IN LPCTSTR szReader,
  345.         ///     IN DWORD dwShareMode,
  346.         ///     IN DWORD dwPreferredProtocols,
  347.         ///     OUT LPSCARDHANDLE phCard,
  348.         ///     OUT LPDWORD pdwActiveProtocol
  349.         /// );
  350.         /// </summary>
  351.         /// <param name="Reader"></param>
  352.         /// <param name="ShareMode"></param>
  353.         /// <param name="PreferredProtocols"></param>
  354.         public override void Connect(string Reader, SHARE ShareMode, PROTOCOL PreferredProtocols)
  355.         {
  356.             EstablishContext(SCOPE.User);
  357.  
  358.             IntPtr  hCard = Marshal.AllocHGlobal(Marshal.SizeOf(m_hCard));
  359.             IntPtr  pProtocol = Marshal.AllocHGlobal(Marshal.SizeOf(m_nProtocol));
  360.  
  361.             m_nLastError = SCardConnect(m_hContext,
  362.                 Reader,
  363.                 (uint) ShareMode,
  364.                 (uint) PreferredProtocols,
  365.                 hCard,
  366.                 pProtocol);
  367.  
  368.             if (m_nLastError != 0)
  369.             {
  370.                 string msg = "SCardConnect error: " + m_nLastError;
  371.  
  372.                 Marshal.FreeHGlobal(hCard);
  373.                 Marshal.FreeHGlobal(pProtocol);
  374.                 throw new Exception(msg);
  375.             }
  376.  
  377.             m_hCard = Marshal.ReadIntPtr(hCard);
  378.             m_nProtocol = (uint) Marshal.ReadInt32(pProtocol);
  379.  
  380.             Marshal.FreeHGlobal(hCard);
  381.             Marshal.FreeHGlobal(pProtocol);
  382.         }
  383.  
  384.         /// <summary>
  385.         /// Wraps the PCSC function
  386.         /// LONG SCardDisconnect(
  387.         ///     IN SCARDHANDLE hCard,
  388.         ///     IN DWORD dwDisposition
  389.         /// );
  390.         /// </summary>
  391.         /// <param name="Disposition"></param>
  392.         public override void Disconnect(DISCONNECT Disposition)
  393.         {
  394.             if (SCardIsValidContext(m_hContext) == SCARD_S_SUCCESS)
  395.             {
  396.                 m_nLastError = SCardDisconnect(m_hCard, (uint) Disposition);
  397.                 m_hCard = IntPtr.Zero;
  398.  
  399.                 if (m_nLastError != 0)
  400.                 {
  401.                     string msg = "SCardDisconnect error: " + m_nLastError;
  402.                     throw new Exception(msg);
  403.                 }
  404.  
  405.                 ReleaseContext();
  406.             }
  407.         }
  408.  
  409.         /// <summary>
  410.         /// Wraps the PCSC function
  411.         /// LONG SCardTransmit(
  412.         ///     SCARDHANDLE hCard,
  413.         ///     LPCSCARD_I0_REQUEST pioSendPci,
  414.         ///     LPCBYTE pbSendBuffer,
  415.         ///     DWORD cbSendLength,
  416.         ///     LPSCARD_IO_REQUEST pioRecvPci,
  417.         ///     LPBYTE pbRecvBuffer,
  418.         ///     LPDWORD pcbRecvLength
  419.         /// );
  420.         /// </summary>
  421.         /// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param>
  422.         /// <returns>An APDUResponse object with the response from the card</returns>
  423.         public override APDUResponse Transmit(APDUCommand ApduCmd)
  424.         {
  425.             uint    RecvLength = (uint) (ApduCmd.Le + APDUResponse.SW_LENGTH);
  426.             byte[]  ApduBuffer = null;
  427.             byte[]  ApduResponse = new byte[ApduCmd.Le + APDUResponse.SW_LENGTH];
  428.             SCard_IO_Request    ioRequest = new SCard_IO_Request();
  429.             ioRequest.m_dwProtocol = m_nProtocol;
  430.             ioRequest.m_cbPciLength = 8;
  431.  
  432.             // Build the command APDU
  433.             if (ApduCmd.Data == null)
  434.             {
  435.                 ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + ((ApduCmd.Le != 0) ? 1 : 0)];
  436.  
  437.                 if (ApduCmd.Le != 0)
  438.                     ApduBuffer[4] = (byte) ApduCmd.Le;
  439.             }
  440.             else
  441.             {
  442.                 ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length];
  443.  
  444.                 for (int nI = 0; nI < ApduCmd.Data.Length; nI++)
  445.                     ApduBuffer[APDUCommand.APDU_MIN_LENGTH + 1 + nI] = ApduCmd.Data[nI];
  446.  
  447.                 ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte) ApduCmd.Data.Length;
  448.             }
  449.  
  450.             ApduBuffer[0] = ApduCmd.Class;
  451.             ApduBuffer[1] = ApduCmd.Ins;
  452.             ApduBuffer[2] = ApduCmd.P1;
  453.             ApduBuffer[3] = ApduCmd.P2;
  454.  
  455.             m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint) ApduBuffer.Length, IntPtr.Zero, ApduResponse, out RecvLength);
  456.             if (m_nLastError != 0)
  457.             {
  458.                 string msg = "SCardTransmit error: " + m_nLastError;
  459.                 throw new Exception(msg);
  460.             }
  461.            
  462.             byte[] ApduData = new byte[RecvLength];
  463.  
  464.             for (int nI = 0; nI < RecvLength; nI++)
  465.                 ApduData[nI] = ApduResponse[nI];
  466.  
  467.             return new APDUResponse(ApduData);
  468.         }
  469.  
  470.  
  471.         /// <summary>
  472.         /// Wraps the PSCS function
  473.         /// LONG SCardBeginTransaction(
  474.         ///     SCARDHANDLE hCard
  475.         //  );
  476.         /// </summary>
  477.         public override void BeginTransaction()
  478.         {
  479.             if (SCardIsValidContext(m_hContext) == SCARD_S_SUCCESS)
  480.             {
  481.                 m_nLastError = SCardBeginTransaction(m_hCard);
  482.                 if (m_nLastError != 0)
  483.                 {
  484.                     string msg = "SCardBeginTransaction error: " + m_nLastError;
  485.                     throw new Exception(msg);
  486.                 }
  487.             }
  488.         }
  489.  
  490.         /// <summary>
  491.         /// Wraps the PCSC function
  492.         /// LONG SCardEndTransaction(
  493.         ///     SCARDHANDLE hCard,
  494.         ///     DWORD dwDisposition
  495.         /// );
  496.         /// </summary>
  497.         /// <param name="Disposition">A value from DISCONNECT enum</param>
  498.         public override void EndTransaction(DISCONNECT Disposition)
  499.         {
  500.             if (SCardIsValidContext(m_hContext) == SCARD_S_SUCCESS)
  501.             {
  502.                 m_nLastError = SCardEndTransaction(m_hCard, (UInt32)Disposition);
  503.                 if (m_nLastError != 0)
  504.                 {
  505.                     string msg = "SCardEndTransaction error: " + m_nLastError;
  506.                     throw new Exception(msg);
  507.                 }
  508.             }
  509.         }
  510.  
  511.         /// <summary>
  512.         /// Gets the attributes of the card
  513.         /// </summary>
  514.         /// <param name="AttribId">Identifier for the Attribute to get</param>
  515.         /// <returns>Attribute content</returns>
  516.         public override byte[] GetAttribute(UInt32 AttribId)
  517.         {
  518.             byte[] attr = null;
  519.             UInt32 attrLen = 0;
  520.  
  521.             m_nLastError = SCardGetAttrib(m_hCard, AttribId, attr, out attrLen);
  522.             if (m_nLastError == 0)
  523.             {
  524.                 if (attrLen != 0)
  525.                 {
  526.                     attr = new byte[attrLen];
  527.                     m_nLastError = SCardGetAttrib(m_hCard, AttribId, attr, out attrLen);
  528.                     if (m_nLastError != 0)
  529.                     {
  530.                         string msg = "SCardGetAttr error: " + m_nLastError;
  531.                         throw new Exception(msg);
  532.                     }
  533.                 }
  534.             }
  535.             else
  536.             {
  537.                 string msg = "SCardGetAttr error: " + m_nLastError;
  538.                 throw new Exception(msg);
  539.             }
  540.  
  541.             return attr;
  542.         }
  543.         #endregion
  544.  
  545.         /// <summary>
  546.         /// This function must implement a card detection mechanism.
  547.         ///
  548.         /// When card insertion is detected, it must call the method CardInserted()
  549.         /// When card removal is detected, it must call the method CardRemoved()
  550.         ///
  551.         /// </summary>
  552.         protected override void RunCardDetection(object Reader)
  553.         {
  554.             bool bFirstLoop = true;
  555.             IntPtr hContext = IntPtr.Zero;    // Local context
  556.             IntPtr phContext;
  557.  
  558.             phContext = Marshal.AllocHGlobal(Marshal.SizeOf(hContext));
  559.  
  560.             if (SCardEstablishContext((uint) SCOPE.User, IntPtr.Zero, IntPtr.Zero, phContext) == 0)
  561.             {
  562.                 hContext = Marshal.ReadIntPtr(phContext);
  563.                 Marshal.FreeHGlobal(phContext);
  564.  
  565.                 UInt32 nbReaders = 1;
  566.                 SCard_ReaderState[] readerState = new SCard_ReaderState[nbReaders];
  567.  
  568.                 readerState[0].m_dwCurrentState = (UInt32) CARD_STATE.UNAWARE;
  569.                 readerState[0].m_szReader = (string)Reader;
  570.  
  571.                 UInt32 eventState;
  572.                 UInt32 currentState = readerState[0].m_dwCurrentState;
  573.  
  574.                 // Card detection loop
  575.                 do
  576.                 {
  577.                     if (SCardGetStatusChange(hContext, WAIT_TIME
  578.                         , readerState, nbReaders) == 0)
  579.                     {
  580.                         eventState = readerState[0].m_dwEventState;
  581.                         currentState = readerState[0].m_dwCurrentState;
  582.  
  583.                         // Check state
  584.                         if (((eventState & (uint) CARD_STATE.CHANGED) == (uint) CARD_STATE.CHANGED) && !bFirstLoop)    
  585.                         {
  586.                             // State has changed
  587.                             if ((eventState & (uint) CARD_STATE.EMPTY) == (uint) CARD_STATE.EMPTY)
  588.                             {
  589.                                 // There is no card, card has been removed -> Fire CardRemoved event
  590.                                 CardRemoved((string)Reader);
  591.                             }
  592.  
  593.                             if (((eventState & (uint)CARD_STATE.PRESENT) == (uint)CARD_STATE.PRESENT) &&
  594.                                 ((eventState & (uint) CARD_STATE.PRESENT) != (currentState & (uint) CARD_STATE.PRESENT)))
  595.                             {
  596.                                 // There is a card in the reader -> Fire CardInserted event
  597.                                 CardInserted((string)Reader);
  598.                             }
  599.  
  600.                             if ((eventState & (uint) CARD_STATE.ATRMATCH) == (uint) CARD_STATE.ATRMATCH)
  601.                             {
  602.                                 // There is a card in the reader and it matches the ATR we were expecting-> Fire CardInserted event
  603.                                 CardInserted((string)Reader);
  604.                             }
  605.                         }
  606.  
  607.                         // The current stateis now the event state
  608.                         readerState[0].m_dwCurrentState = eventState;
  609.  
  610.                         bFirstLoop = false;
  611.                     }
  612.  
  613.                     Thread.Sleep(100);
  614.  
  615.                     if (m_bRunCardDetection == false)
  616.                         break;
  617.                 }
  618.                 while (true);    // Exit on request
  619.             }
  620.             else
  621.             {
  622.                 Marshal.FreeHGlobal(phContext);
  623.                 throw new Exception("PC/SC error");
  624.             }
  625.  
  626.             SCardReleaseContext(hContext);
  627.         }
  628.     }
  629. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement