Error in ScardTransmit () when returning SW1 = 69. SW2 = 00

4

I develop a Pc / Sc application, I set the context, the connection and I get the ATR perfectly, but when I start the transmission instead of returning (SW1 = 90 SW2 = 00) it returns me (SW1 = 69 SW2 = 00) CodigoSnipe

     class MaxSmartCard 
{
    private UInt32 LONGITUD = 0xFF;
    private const UInt32 T0 = 0x01; private const UInt32 T1 = 0x02 ; 
    private const UInt32 EXCLUSIVE = 0x01; private const UInt32 SHARED = 0x02; 
    private SCARD_IO_REQUEST request = new SCARD_IO_REQUEST();

    [DllImport("Winscard.dll")]
    private extern static int SCardTransmit(
      [In] IntPtr cardHandle, 
      IntPtr sendPci,
      Byte [] sendBuffer,
      UInt32 sbLength,
      [In, Out]  SCARD_IO_REQUEST recvPci, 
      [In, Out] Byte[] recvBuffer,
      [In, Out] UInt32 rbLength);

    [DllImport("kernel32.dll", SetLastError = true)]
    private extern static IntPtr LoadLibrary(string lpFileName);

    [DllImport("kernel32.dll")]
    private extern static void FreeLibrary(IntPtr handle);

    [DllImport("kernel32.dll")]
    private extern static IntPtr GetProcAddress(IntPtr handle, string procName);

    [StructLayout(LayoutKind.Sequential)]
     public struct SCARD_IO_REQUEST
     {
        public UInt32 pciProt; public UInt32 pciLen;
        public SCARD_IO_REQUEST (UInt32 a, UInt32 b)
        { this.pciProt = a; this.pciLen = b; }
     }

    public MaxSmartCard() { this.request = new SCARD_IO_REQUEST(0x00,0xFF); }

    public void EstablecerContexto() { this.rContex = SCardEstablishContext(0x00, IntPtr.Zero, IntPtr.Zero, out this.hContext); }

    public void InformacionLectores()
    {
        UInt32 _pcchReaders = 0;
        this.rReader = SCardListReaders(this.hContext, null, null, ref _pcchReaders);
        Byte[] byteLectores = new Byte[_pcchReaders];
        this.rReader2 = SCardListReaders(this.hContext, null, byteLectores, ref _pcchReaders);
        ASCIIEncoding ascii = new ASCIIEncoding();
        this.miLector = ascii.GetString(byteLectores);
    }

    public void EstablecerConexion() { this.rConnect = SCardConnect(this.hContext, miLector, EXCLUSIVE,T1, ref this.hContext, ref ActiveProtocol); }

    public void AtributosCard()
    {
        this.vectorAttr = new Byte[22];
        IntPtr pcbAttrLen = new IntPtr(vectorAttr.Length);
        this.rAtributo = SCardGetAttrib(this.hContext, SCARD_ATTR_ATR_STRING, vectorAttr, ref pcbAttrLen);
    }

    public void Trasmision()
    {
        Byte[] vectorSend = { 0x00, 0xA4, 0x04, 0x00, 0x00};
        UInt32 inT2 = (UInt32)vectorSend.Length; 
        vectorIn = new Byte[2];
        UInt32 inT = (UInt32)vectorIn.Length;
        IntPtr IOPCI = GetPciT1();
        this.rTransmit = SCardTransmit(this.hContext, IOPCI, vectorSend, inT2,  request, vectorIn, inT);

    }
   public IntPtr GetPciT1()
    {
        IntPtr handle = LoadLibrary("Winscard.dll");
        IntPtr pci = GetProcAddress(handle, "g_rgSCardT1Pci");
        FreeLibrary(handle);
        return pci;
    }
}

and from this button I invoke the methods of the class

  private void button9_Click(object sender, EventArgs e)
    {
        Byte[] v; Int64 Exito = 0X00;
        textBox1.Text = "";
        Metodo.EstablecerContexto(); if (Metodo.RContext() != Exito) { MessageBox.Show("CONTEXTO NO ESTABLECIDO, ERROR " + Metodo.RContext().ToString("X2"), "INFORMACION DEL SISTEMA", MessageBoxButtons.OK, MessageBoxIcon.Error); }
        Metodo.InformacionLectores();
        if (Metodo.RReader() != Exito) { MessageBox.Show("1era LLAMADA AL LECTOR FALLIDA", "INFORMACION DEL SISTEMA", MessageBoxButtons.OK, MessageBoxIcon.Error); }
        if (Metodo.RReader2() != Exito) { MessageBox.Show("2da LLAMADA AL LECTOR FALLIDA", "INFORMACION DEL SISTEMA", MessageBoxButtons.OK, MessageBoxIcon.Error); }
        textBox1.Text = "NOMBRE DEL LECTOR  " + Metodo.MiLector();
        Metodo.EstablecerConexion(); if (Metodo.RConnect() != Exito) { MessageBox.Show("CONEXION NO ESTABLECIDA, ERROR " + Metodo.RConnect().ToString("X2"), "INFORMACION DEL SISTEMA", MessageBoxButtons.OK, MessageBoxIcon.Error); }
        Metodo.AtributosCard(); if (Metodo.RAtributo() != Exito) { MessageBox.Show("OBTENCION DE ATRIBUTO FALLIDA, ERROR " + Metodo.RAtributo().ToString("X2"), "INFORMACION DEL SISTEMA", MessageBoxButtons.OK, MessageBoxIcon.Error); }
        v = Metodo.VectorAtributo();
        textBox1.Text = textBox1.Text + Environment.NewLine + "ATR   ";
        for (int i = 0; i <= v.Length - 1; i++) { textBox1.Text = textBox1.Text + v[i].ToString("X2") + " "; }
        textBox1.Text = textBox1.Text + Environment.NewLine + "MODELO TARJETA   " + Metodo.CadenaHexArray(v, false);
        Metodo.Trasmision(); if (Metodo.RTransmit() != Exito) { MessageBox.Show("TRASMISION FALLIDA, ERROR " + Metodo.RTransmit().ToString("X2"), "INFORMACION DEL SISTEMA", MessageBoxButtons.OK, MessageBoxIcon.Error); }
        v = Metodo.VectorSalida();
        textBox1.Text = textBox1.Text + Environment.NewLine + "SW1=" + v[0].ToString("X2") + "  " + "SW2=" + v[1].ToString("X2");
        Metodo.Desconectar();
    }

    
asked by Efrain Mejias C 16.05.2016 в 15:00
source

1 answer

1

To send n bytes of data to the card, where n > 0, the sending and receiving buffers must be formatted:

  • First four bytes of pbSendBuffer contain the values CLA, INS, P1, and P2 for the T = 0 operation.

  • The fifth byte must be set to n (size, in bytes, of the data to be transferred to the card). The following n bytes must contain the data that will be sent to the card.

cbSendLength must be adjusted to the header information size T = 0 (CLA, INS, P1 and P2) plus one byte that contains the length of the data to be transferred (n), plus the size of the the data to be issued. In this example, this is n + 5 .

pbRecvBuffer receives status codes SW1 and SW2 of the operation.

pcbRecvLength must be at least two and will be set to two at

LONG WINAPI SCardTransmit(
    _In_        SCARDHANDLE         hCard,
      _In_        LPCSCARD_IO_REQUEST pioSendPci,
      _In_        LPCBYTE             pbSendBuffer,
      _In_        DWORD               cbSendLength,
      _Inout_opt_ LPSCARD_IO_REQUEST  pioRecvPci,
      _Out_       LPBYTE              pbRecvBuffer,
      _Inout_     LPDWORD             pcbRecvLength
);

The call would be:

lReturn = SCardTransmit(hCardHandle,
    SCARD_PCI_T0,
    pbSend,
    dwSend,
    NULL,
    pbRecv,
    &dwRecv );

if ( SCARD_S_SUCCESS != lReturn )
{
       // Fallo
}

Also here you have a complete example of using a similar class for Smart Card .

The reader if it is from SCM Microsystems will belong (I can not assure you 100%) to Identive ID that if it has tools for developers, it is also a point of reference for PS / SC: SDKs for PC / SC here .

References of possible error codes.

    
answered by 30.06.2017 в 11:06