【问题标题】:WinScard SCardConnect returns SCARD_E_NOT_READYWinScard SCardConnect 返回 SCARD_E_NOT_READY
【发布时间】:2014-12-09 17:19:12
【问题描述】:

我有一个 Java 程序,它使用 javax.smartcardio.* 成功地与带有智能卡读卡器的 Java 智能卡通信。通过 API 监视器,我发现运行它的 java.exe 女巫实际上是在使用 WinSCard winAPI(它在我开始通信的那一刻加载了 winscard.dll。我还没有设法找到我们的实际调用)

我的问题是我尝试使用 WinSCard 库在 Qt 框架 C++ 程序中实现相同的东西。如果我在阅读器插入 USB 后 10 秒内运行程序,一切正常,但在那之后阅读器进入我认为是某种节电状态的状态,然后几秒钟后它击落了 USB 管道。 java程序在我尝试连接时会自动“唤醒”阅读器,但是我写的C++没有,我也不知道自己做错了什么。

首先我用SCardEstablishContext()调用建立一个上下文,然后我用SCardListReaders()列出读者,这实际上列出了读者是问题,最后我调用SCardConnect()进行连接,如果智能卡返回SCARD_E_NOT_READY阅读器处于这种“睡眠”状态。

请注意,如果智能卡读卡器不是这种“睡眠”模式,我可以用相同的代码与卡通信,没有问题。

winAPI 描述没有提示在这种情况下应该做什么,而且我找不到任何关于该做什么的踪迹。如果有人知道这个问题的解决方案,请分享!

【问题讨论】:

    标签: smartcard winscard apimonitor


    【解决方案1】:

    问题解决了。:未记录的 windows api 或 windows api 错误或坏的智能卡读卡器驱动程序实现。

    SCardConnect() windows api 声明:

    dwShareMode [输入] 指示其他应用程序是否可以与卡建立连接的标志。

    SCARD_SHARE_SHARED: 此应用程序愿意与其他应用程序共享该卡。 SCARD_SHARE_EXCLUSIVE: 此应用程序不愿意与其他应用程序共享卡。 SCARD_SHARE_DIRECT: 此应用程序正在分配阅读器供其私人使用,并将直接控制它。不允许其他应用程序访问它。

    在 SCARD_SHARE_DIRECT 的情况下,它也不允许访问任何旨在唤醒睡眠阅读器的内容。在 SCARD_SHARE_EXCLUSIVE 或 SCARD_SHARE_SHARED 的情况下,它的作用就像一个魅力:阅读器在 SCardConnect() 上自动“唤醒”。

    【讨论】:

    • 我最初将您的开场白误读为“谜团已解开”。我相信“苦难”确实更贴切。
    【解决方案2】:

    我这样做了,使用以下代码,它似乎工作正常。 (虽然它现在已经很老了。)这就是我所做的:

    int connectDevice(bool cardNeeded){
        dwAP = 0;
    
        log("\nEstablishing a connection to the device\n");
    
        if (deviceConnected) {
            log("Already connected.\n");
            return 1;
        }   
    
        hCard  = NULL;
        if (cardNeeded) {
            lReturn = SCardConnect(hContext, (LPCTSTR)currentReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, &hCard, &dwAP );
            if(SCARD_S_SUCCESS != lReturn){
                logBytes("  SCardConnect failed with error: ", (byte *)&lReturn, sizeof(LONG));
                return 0;
            }
        }
        else {
            lReturn = SCardConnect(hContext, (LPCTSTR)currentReader, SCARD_SHARE_DIRECT, 0, &hCard, &dwAP );
            if(SCARD_S_SUCCESS != lReturn){
                logBytes("  SCardConnect failed with error: ", (byte *)&lReturn, sizeof(LONG));
                return 0;
            }
        }
        deviceConnected = true;
        logBytes("  SCardConnect succeeded, handle : ", (byte *)&hCard, sizeof(SCARDHANDLE));
        log("  Successful\n");
        return 1;
    }
    

    【讨论】:

    • 与我使用的代码几乎相同。唯一的区别在于 SCARD_SHARE_SHARED 参数。我的问题是,当 SCardConnect() 返回 lReturn 时,如果设备处于“睡眠模式”,它是错误代码 SCARD_E_NOT_READY,我不知道如何摆脱它。即使我在 10 毫秒睡眠的循环中多次调用 SCardConnect(),我也会得到相同的结果。我可以看到阅读器从其上的 LED 进入此“睡眠模式”。它开始闪烁然后关闭。
    • 好的,对不起,伙计。以为你可能会在那里看到一些东西。我会删除答案...
    • 我找到了我的问题的答案,请看一下,这可能会影响您的解决方案! (可能想使用 SCARD_SHARE_EXCLUSIVE 而不是 SCARD_SHARE_DIRECT)
    猜你喜欢
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多