我正在使用Microsoft SmartCard APIs开发SCM非接触式RFID读卡器。
我所理解的通常使用智能卡的过程是:
1.使用SCardEstablishContext()建立上下文
2.使用SCardListReaders()列出连接到系统的所有阅读器
3.选择一个阅读器,然后等待插入卡中
4.一旦检测到卡,SCardGetStatusChange()函数返回
5.使用SCardConnect()
通过所选阅读器连接到卡
6.使用SCardTransmit()
直到5的所有步骤都正常工作,这意味着我得到了正确的卡片手柄。可以通过发出SCardStatus()函数进一步验证卡,该函数返回协商的协议和卡的ATR,这也是正确的。但是当我尝试使用SCardTransmit()发送任何APDU命令时,它返回一个错误(错误代码14,我猜是SCARD_E_CANT_DISPOSE)。
我不知道出了什么问题或者缺少什么。我尝试了不同的APDU,例如通过发出{0xFF,0xCA,0x00,0x00,0x00}来读取卡UID的非常基本的APDU。我使用SCM TestResMan调试工具验证了这个APDU,它返回了卡的正确UID。我使用的是MiFARE 1k卡和SCM非接触式SCL011读卡器。
请在下面找到SCardTransmit()代码段(所有以前的功能都返回成功)。
SCARD_IO_REQUEST sioreq;
sioreq.dwProtocol = 2; // SCARD_PROTOCOL_T1
sioreq.cbPciLength = 8;
SCARD_IO_REQUEST rioreq;
rioreq.dwProtocol = 2; // SCARD_PROTOCOL_T1
rioreq.cbPciLength = 8;
byte sendbuffer[256], receivebuffer[256];
ULONG sendbufferLen, receivebufferLen, sizeofUID;
sendbuffer[0] = 0xFF; // CLA - Instruction Class
sendbuffer[1] = 0xCA; // Instruction code
sendbuffer[2] = 0x00; // P1 - 1st parameter
sendbuffer[3] = 0x00; // P2 - 2nd parameter
sendbuffer[4] = 0x00;
sendbufferLen = 0x05;
retval = objScWrapper->SCardTransmit(hCardHandle, &sioreq, sendbuffer,
sendbufferLen, NULL, receivebuffer,
&receivebufferLen);
如果有人有任何线索或指示,请告诉我。
TIA !!
答案 0 :(得分:4)
您的接收缓冲区大小为256字节,但您要求256字节(Le = 00h),接收缓冲区也需要状态字(由两个字节SW1和SW2组成)。
所以我认为你的14个错误代码是接收缓冲区的通用OUT_OF_MEMORY。
您的命令缓冲区也太小,无法容纳5个字节的标头+最多255个字节的命令数据。当然,两者肯定都太小而无法处理扩展长度的ADPU。
Windows目前对于兼容PCSC的读卡器的智能卡读卡器缓冲区大小非常挑剔。命令缓冲区至少使用5 + 255 = 260字节,接收缓冲区使用256 + 2字节。重复使用缓冲区或安全处理它们,否则会发生内存泄漏。
答案 1 :(得分:0)
在大多数情况下从这里看起来很好...你可以回答几个问题,看看我们是否可以到达任何地方......
1)当您使用SCardConnect连接时,您是通过独占,共享还是直接访问进行连接? 2)你确定当你连接到卡时,卡所连接的协议是T1吗? 3)SCARD_IO_REQUEST rioreq的目的是什么;样本中的这个对象似乎没有被使用? 4)我看到你正在通过一个包装来进行API调用。你能在包装器中共享内部的SCardTrasmit实现吗?
我会根据您更新的问题编辑此答案。