使用winscard.dll(PC / SC)发送APDU而未连接智能卡

时间:2015-02-16 10:53:31

标签: apdu smartcard-reader pcsc

我正在尝试将APDU命令发送到读卡器本身而不是智能卡。我正在使用的测试命令打开和关闭RF场。

如果我第一次连接到智能卡,此命令将通过SCardTransmit发送。但是一旦RF场关闭,卡就会断开连接,我无法发送另一个APDU来打开该字段。

基本上没有任何方法可以在没有卡存在的情况下通过pc / sc发送APDU。我想在读卡之前配置读卡器的某些部分。

提前致谢。

- - - - - - - - 编辑

正如FPGA Warrior所提到的,我需要使用SCardControl将APDU命令发送给读卡器。

到目前为止我已经采取的步骤:

使用SCARD_SHARE_DIRECT和SCARD_PROTOCOL_UNDEFINED连接到带有SCardConnect的'card'。这将成功返回,并为您提供卡片处理。

_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

4 个答案:

答案 0 :(得分:0)

我不确定为什么通过将APDU发送到卡来配置读卡器。不应该那样。 SCardTransmit用于向卡发送命令,如果没有卡,它将无法工作(除非您破解驱动程序,因此实际上插入了卡)。

您可能正在寻找其中一种API: https://msdn.microsoft.com/en-us/library/windows/desktop/aa375369(v=vs.85).aspx 它可以更直接地访问您的读卡器/卡。

指定您希望在阅读器上设置的配置可能会增加更改以获得有助于您的答案。

答案 1 :(得分:0)

我可以使用带有这些参数的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);

答案 2 :(得分:0)

我在SCardConnect之后调用SCardTransmit也有类似的经历(从SCardTransmit接收ERROR_INVALID_HANDLE <0x6>)。

作为实验,在sleep语句之后,将Thread.Sleep(100)放在SCardTransmit之后似乎会将错误代码从0x6更改为SUCCESS(如在调试器中查看)。这不是解决方案,而是朝着正确方向的提示。最好在SCardControl之后编写线程安全代码来处理语句。

以下链接是一个很好的参考:

https://www.csharpstar.com/csharp-race-conditions-in-threading/

答案 3 :(得分:-1)

简单的方法是只打开/关闭智能卡读卡器是调用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);

要释放Reader:这将关闭/释放当前进程的阅读器句柄。 注意:与智能卡没有任何关系。

    /// <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);