public void ReadCard(object ob) { string selectedReader = ob as string; ASN1 daTa = null; List<String[]> la = new List<string[]>(); List<byte[]> pseIdentifiers = new List<byte[]>(); List<byte[]> applicationIdentifiers = new List<byte[]>(); ASCIIEncoding encoding = new ASCIIEncoding(); APDUCmd apdu = null; APDURes response = null; bool pseFound = false; pseIdentifiers.Add(encoding.GetBytes("1PAY.SYS.DDF01")); pseIdentifiers.Add(encoding.GetBytes("2PAY.SYS.DDF01")); try { // Now lets process all Payment System Environments if (pseIdentifiers.Count > 0) { cardReaderList.Connect(selectedReader); foreach (byte[] pse in pseIdentifiers) { apdu = new APDUCmd(0x00, 0xA4, 0x04, 0x00, pse, (byte)pse.Length); response = cardReaderList.Transmit(apdu); // Get response nescesary if (response.SW1 == 0x61) { apdu = new APDUCmd(0x00, 0xC0, 0x00, 0x00, null, response.SW2); response = cardReaderList.Transmit(apdu); } // PSE application read found ok if (response.SW1 == 0x90) { pseFound = true; daTa = new ASN1(response.Data); byte sfi = new ASN1(response.Data).Find(0x88).Value[0]; byte recordNumber = 0x01; byte p2 = (byte)((sfi << 3) | 4); while (response.SW1 != 0x6A && response.SW2 != 0x83) { apdu = new APDUCmd(0x00, 0xB2, recordNumber, p2, null, 0x00); response = cardReaderList.Transmit(apdu); // Retry with correct length if (response.SW1 == 0x6C) { apdu = new APDUCmd(0x00, 0xB2, recordNumber, p2, null, response.SW2); response = cardReaderList.Transmit(apdu); } if (response.SW1 == 0x61) { apdu = new APDUCmd(0x00, 0xC0, 0x00, 0x00, null, response.SW2); response = cardReaderList.Transmit(apdu); } if (response.Data != null) { ASN1 aefVal = new ASN1(response.Data); foreach (ASN1 appTemplate in aefVal) { // Check we really have an Application Template if (appTemplate.Tag[0] == 0x61) { applicationIdentifiers.Add(appTemplate.Find(0x4f).Value); } } } recordNumber++; } } if (pseFound) break; } cardReaderList.Disconnect(); } if (applicationIdentifiers.Count > 0) { foreach (byte[] AID in applicationIdentifiers) { List<AppliFileLoc> applicationFileLocators = new List<AppliFileLoc>(); StringBuilder sb = new StringBuilder(); cardReaderList.Connect(selectedReader); // Select AID apdu = new APDUCmd(0x00, 0xA4, 0x04, 0x00, AID, (byte)AID.Length); response = cardReaderList.Transmit(apdu); // Get response nescesary if (response.SW1 == 0x61) { apdu = new APDUCmd(0x00, 0xC0, 0x00, 0x00, null, response.SW2); response = cardReaderList.Transmit(apdu); } // Application not found if (response.SW1 == 0x6A && response.SW2 == 0x82) continue; if (response.SW1 == 0x90) { foreach (byte b in AID) { sb.AppendFormat("{0:X2}", b); } daTa = new ASN1(response.Data); // Get processing options (with empty PDOL) apdu = new APDUCmd(0x80, 0xA8, 0x00, 0x00, new byte[] { 0x83, 0x00 }, 0x02); response = cardReaderList.Transmit(apdu); // Get response nescesary if (response.SW1 == 0x61) { apdu = new APDUCmd(0x00, 0xC0, 0x00, 0x00, null, response.SW2); response = cardReaderList.Transmit(apdu); } if (response.SW1 == 0x90) { ASN1 template = new ASN1(response.Data); ASN1 aipVal = null; ASN1 aflVal = null; // Primative response (Template Format 1) if (template.Tag[0] == 0x80) { byte[] tempAIP = new byte[2]; Buffer.BlockCopy(template.Value, 0, tempAIP, 0, 2); aipVal = new ASN1(0x82, tempAIP); byte[] tempAFL = new byte[template.Length - 2]; Buffer.BlockCopy(template.Value, 2, tempAFL, 0, template.Length - 2); aflVal = new ASN1(0x94, tempAFL); } // constructed data object response (Template Format 2) if (template.Tag[0] == 0x77) { aipVal = template.Find(0x82); aflVal = template.Find(0x94); } // Chop up AFL's for (int i = 0; i < aflVal.Length; i += 4) { byte[] AFL = new byte[4]; Buffer.BlockCopy(aflVal.Value, i, AFL, 0, 4); AppliFileLoc fileLocator = new AppliFileLoc(AFL); applicationFileLocators.Add(fileLocator); } ASN1 aipafl = new ASN1(response.Data); foreach (AppliFileLoc file in applicationFileLocators) { int rec = file.FirstRecord;// read SDA records int lrec = file.LastRecord; byte p2 = (byte)((file.SFI << 3) | 4); while (rec <= lrec) { apdu = new APDUCmd(0x00, 0xB2, (byte)rec, p2, null, 0x00); response = cardReaderList.Transmit(apdu); // Retry with correct length if (response.SW1 == 0x6C) { apdu = new APDUCmd(0x00, 0xB2, (byte)rec, p2, null, response.SW2); response = cardReaderList.Transmit(apdu); } ASN1 record = new ASN1(response.Data); s_Card(record); getVal(record); rec++; } } } else { UpdateStatusLabel(String.Format("Record not found.")); } } else { UpdateStatusLabel(String.Format("File not selected.")); } cardReaderList.Disconnect(); UpdateStatusLabel(String.Format("Process Complete.")); } } } catch (CardDExcep ex) { UpdateStatusLabel(ex.Message); return; } }
public APDURes Transmit(APDUCmd apdu) { byte[] recvBuffer = new byte[256]; int recvLength = recvBuffer.Length; IntPtr sendPci = IntPtr.Zero; switch ((WinConCard.Protocol)activeProtocol) { case WinConCard.Protocol.SCARD_PROTOCOL_T0: sendPci = WinConCard.SCARD_PCI_T0; break; case WinConCard.Protocol.SCARD_PROTOCOL_T1: sendPci = WinConCard.SCARD_PCI_T1; break; } #region Debug output #if DEBUG if (outputDebugString) { StringBuilder sb = new StringBuilder(); foreach (byte b in apdu.ToArray()) { sb.AppendFormat("{0:X2}", b); } Debug.WriteLine(sb.ToString()); } #endif #endregion int result = WinConCard.SCardTransmit(card, sendPci, apdu.ToArray(), apdu.ToArray().Length, IntPtr.Zero, recvBuffer, ref recvLength); if (result != WinConCard.SCARD_S_SUCCESS) { throw new CardDExcep(result); } #region Debug output #if DEBUG if (outputDebugString) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < recvLength; i++) { sb.AppendFormat("{0:X2}", recvBuffer[i]); } Debug.WriteLine(sb.ToString()); } #endif #endregion byte[] response = new byte[recvLength]; Buffer.BlockCopy(recvBuffer, 0, response, 0, recvLength); return(new APDURes(response)); }