1

javax.smartcardio.* を使用して、スマート カード リーダーを備えた Java スマート カードと正常に通信する Java のプログラムがあります。APIモニターを使用すると、java.exeウィッチが実行され、実際にWinSCard winAPIを使用していることがわかりました(通信を開始するとすぐにwinscard.dllがロードされます。実際の呼び出しをまだ見つけることができませんでした)

私の問題は、WinSCard ライブラリを使用して Qt フレームワーク C++ プログラムに同じことを実装しようとしたことです。リーダーが USB に接続されてから 10 秒以内にプログラムを実行すると、すべてがうまく機能しますが、その後、リーダーは省電力状態であると思われる状態になり、数秒後に USB パイプを撃ち落とします。リーダーに接続しようとすると、Java プログラムは自動的にリーダーを「起動」しますが、私が書いた C++ はそうではなく、何が間違っているのかわかりません。

最初にSCardEstablishContext()call でコンテキストを確立し、次にリーダーをSCardListReaders()でリストします。これは実際にリーダーをリストする質問です。最後にSCardConnect()接続するために呼び出しSCARD_E_NOT_READY、スマート カード リーダーがこの「スリープ」状態にある場合はリターンを返します。

スマート カード リーダーがこの「スリープ」モードでない場合、同じコードで問題なくカードと通信できることに注意してください。

winAPI の説明には、この場合に何をすべきかについてのヒントはなく、何をすべきかの痕跡も見つかりませんでした。誰かがこれに対する解決策を知っている場合は、共有してください!

4

2 に答える 2

4

悲惨さは解決されました。: 文書化されていない Windows API または Windows API のバグ、または不適切なスマート カード リーダー ドライバーの実装。

SCardConnect() Windows API には、次のように記載されています。

dwShareMode [in] 他のアプリケーションがカードへの接続を形成できるかどうかを示すフラグ。

SCARD_SHARE_SHARED: このアプリケーションは、カードを他のアプリケーションと共有しようとしています。SCARD_SHARE_EXCLUSIVE: このアプリケーションは、カードを他のアプリケーションと共有するつもりはありません。SCARD_SHARE_DIRECT: このアプリケーションはリーダーを私的使用のために割り当てており、直接制御します。他のアプリケーションはアクセスできません。

SCARD_SHARE_DIRECT の場合、スリープ状態のリーダーを起動するためのものへのアクセスも許可しないようです。SCARD_SHARE_EXCLUSIVE または SCARD_SHARE_SHARED の場合、それは魔法のように機能します: リーダーは SCardConnect() で自動的に「起動」します。

于 2014-12-13T13:29:17.033 に答える
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;
}
于 2014-12-09T17:36:41.773 に答える