我正在尝试将APDU命令发送到读卡器本身,而不是智能卡。我使用的测试命令打开和关闭射频场
如果我第一次连接到智能卡,此命令将通过SCardTransmit发送。但一旦射频场关闭,卡就会断开,我无法发送另一个APDU来打开场。
基本上有没有任何方法可以在没有卡的情况下通过pc/sc发送APDU。我想在读卡之前配置读卡器的某些部分。
提前谢谢。
-----编辑-----
正如FPGA Warrior所提到的,我需要使用SCardControl向读卡器发送APDU命令。
到目前为止,我已经采取了以下步骤:
使用SCARD_SHARE_DIRECT和SCARD_PROTOCOL_UNDEFINED连接到"卡"。这将作为成功返回,并为您提供卡句柄。
_lastError = SCardConnect(_hContext, _cardReaderName, dwShareMode, dwPreferredProtocols, ref phCard, ref _activeProtocol);
返回:0和看起来有效的_hCard句柄。
然后我打电话给SCardControl
_lastError = SCardControl(phCard, CTL_code(3500), txBytes, (uint)txByte.Length, out rxBytes, (uint)rxAttr.Length, out rxLen);
我现在得到错误error_INVALID_HANDLE(0x6)。因此,我的SCardConnect似乎没有返回有效的句柄,即使你也没有返回错误。
在设备上使用PC_to_RDR_Escape模式时,如果您安装的驱动程序不允许,您可能需要编辑注册表以打开它。https://msdn.microsoft.com/en-us/library/windows/hardware/dn653571%28v=vs.85%29.aspx
我不知道为什么要通过向卡发送APDU来配置读卡器。不应该是那样。SCardTransmit用于向卡发送命令,如果没有卡,它将不起作用(除非你破解驱动程序,让它谎称实际上插入了卡)。
您可能正在寻找以下API之一:https://msdn.microsoft.com/en-us/library/windows/desktop/aa375369(v=vs.85).aspx它可以更直接地访问您的读卡器/卡。
指定要在读卡器上设置的配置可能会增加更改,以获得有助于您的答案。
我能够使用带有以下参数的perl绑定来做到这一点:
#connect witouth card in
$hCard = new Chipcard::PCSC::Card($hContext, $ReadersList[0], $Chipcard::PCSC::SCARD_SHARE_DIRECT, $Chipcard::PCSC::SCARD_PROTOCOL_RAW);
#send any adpu
$cmd = Chipcard::PCSC::ascii_to_array("FF 00 40 F0 04 05 05 03 03");
$hCard->Transmit($cmd);
我在SCardConnect之后调用SCardTransmit时也有类似的经历(从SCardTransmission接收ERROR_INVALID_HANDLE<0x6>)。
作为一个实验,在SCardTransmit之后放置Thread.Sleep(100)似乎会在Sleep语句之后将错误代码从0x6更改为SUCCESS(在调试器中查看)。这不是一个解决方案,而是一个正确方向的提示。在SCardControl之后编写线程安全代码来处理语句将是一种更好的方法。
以下链接是一个很好的参考:
https://www.csharpstar.com/csharp-race-conditions-in-threading/
只打开/关闭智能卡读卡器的简单方法是调用SCardEstablishContext连接到读卡器。注意:这不会连接到智能卡:
/// <summary>
/// Native SCardEstablishContext function from winscard.dll
/// </summary>
/// <param name="dwScope"></param>
/// <param name="pvReserved1"></param>
/// <param name="pvReserved2"></param>
/// <param name="phContext"></param>
/// <returns></returns>
[DllImport("winscard.dll", SetLastError=true)]
internal static extern int SCardEstablishContext(UInt32 dwScope,
IntPtr pvReserved1,
IntPtr pvReserved2,
IntPtr phContext);
释放读卡器:这将关闭当前进程中的读卡器句柄。注意:与智能卡没有任何关系。
/// <summary>
/// Native SCardReleaseContext function from winscard.dll
/// </summary>
/// <param name="hContext"></param>
/// <returns></returns>
[DllImport("winscard.dll", SetLastError=true)]
internal static extern int SCardReleaseContext(UInt32 hContext);