WinScard SCardConnect返回SCARD_E_NOT_READY

时间:2014-12-09 17:19:12

标签: smartcard winscard

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

我的问题是我尝试使用WinSCard库在Qt框架C ++程序中实现相同的功能。如果我在读卡器插入USB后10秒内运行程序,一切运行良好,但之后读卡器进入我认为是省电状态的状态,几秒钟后它就会击落USB管道。当我尝试连接它时,java程序自动“唤醒”读者,但我写的C ++没有,我不知道我做错了什么。

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

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

winAPI描述没有提示在这种情况下该怎么做,我找不到任何做什么的痕迹。如果有人知道这方面的解决方案,请分享!

2 个答案:

答案 0 :(得分:4)

苦难得到解决:未记录的windows api或windows api bug或者糟糕的智能卡读卡器驱动程序实现。

SCardConnect()窗口api声明:

dwShareMode [in] 一个标志,指示其他应用程序是否可以与卡形成连接。

SCARD_SHARE_SHARED: 此应用程序愿意与其他应用程序共享该卡。 SCARD_SHARE_EXCLUSIVE: 此应用程序不愿意与其他应用程序共享该卡。 SCARD_SHARE_DIRECT: 此应用程序将读取器分配给其私人使用,并将直接控制它。没有其他应用程序可以访问它。

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

答案 1 :(得分:1)

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

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;
}