次の方法で共有


ISO7816-4 APDU コマンドのビルド

サービス プロバイダーに機能を追加するには、ベース サービス プロバイダー DLL 内に ISO7816-4 アプリケーション プロトコル データ ユニット (APDU) がどのように構築されているかを把握する必要があります。 次の手順では、ビルド プロセスの概要を示します。

Note

ここに含まれる例は必ずしも完全ではありません。詳細については、サンプル アプリケーションと DLL を参照してください。

 

ISO7816-4 APDU コマンドをビルドするには

  1. ISCardCmd オブジェクトと ISCardISO7816 オブジェクトを作成します。

    //  Create an ISCardCmd object.
    HRESULT hresult = CoCreateInstance(CLSID_CSCardCmd,
                               NULL,
                               CLSCTX_ALL,
                               IID_ISCardCmd,
                               (LPVOID*) &g_pISCardCmd);
    //  Create an ISCardISO7816 object.
    HRESULT hresult = CoCreateInstance(CLSID_CSCardISO7816,
                               NULL,
                               CLSCTX_ALL,
                               IID_ISCardISO7816,
                               (LPVOID*) &g_pISCardISO7816);
    

    ISCardCmd インターフェイスには、2 つの IByteBuffer バッファーが含まれています。 1 つのバッファーには、実際の APDU コマンド文字列 (およびコマンドで送信するデータ) が含まれています。 もう 1 つのには、コマンドの実行後にカードによって返された応答情報が含まれます。

  2. これらのオブジェクトを使用して、次のように有効な ISO7816-4 コマンドを作成します。

    //  Do challenge.
    HRESULT hresult = g_pISCardISO7816->GetChallenge(dwLengthOfChallenge,
                                             &g_pISCardCmd);
    

    GetChallenge メソッドで使用されるコードを次に示します。

    #include <windows.h>
    
    STDMETHODIMP CSCardISO7816::GetChallenge(IN DWORD dwBytesExpected /*= 0*/,
                                IN OUT LPSCARDCMD *ppCmd)
    {
        //  Locals.
        HRESULT hr = S_OK;
    
        try
        {
            //  Is the ISCardCmd object okay?
            hr = IsSCardCmdValid(ppCmd);
            if (FAILED(hr))
                throw (hr);
    
            //  Do it.
            hr = (*ppCmd)->BuildCmd(m_byClassId,
                                    (BYTE) INS_GET_CHALLENGE,
                                    (BYTE) INS_NULL,  // P1 = 0x00
                                    (BYTE) INS_NULL,  // P2 = 0x00
                                    NULL,
                                    &dwBytesExpected);
            if (FAILED(hr))
                throw (hr);
        }
    }
    

    ISCardISO7816::GetChallenge メソッドは、ISCardCmd::BuildCmd メソッドを使用して、要求された APDU をビルドします。 これは、次のステートメントで ISCardCmd APDU バッファーに適切な情報を書き込むことで行われます。

    hr = (*ppCmd)->BuildCmd;
    
  3. ビルドされた ISCardCmd オブジェクトを使用して、カードを使用してトランザクションを実行し、結果を解釈して続行します。

ISO7816-4 以降の拡張

上記のサービス プロバイダーのビルド/実行プロセスを拡張するには、新しい COM オブジェクトを作成することをお勧めします。 この COM オブジェクトは、ISO7816-4 以外のコマンドを作成できる新しいインターフェイスをサポートし、 ISCardISO7816 インターフェイスを集計する必要があります。

ISO7816-4 APDU コマンドの作成例

次の例は、上記の手順で使用したコードを示しています。

//  Create an ISCardCmd object.
hresult = CoCreateInstance(CLSID_CSCardCmd,
                           NULL,
                           CLSCTX_ALL,
                           IID_ISCardCmd,
                           (LPVOID*) &g_pISCardCmd);
//  Create an ISCardISO7816 object.
hresult = CoCreateInstance(CLSID_CSCardISO7816,
                           NULL,
                           CLSCTX_ALL,
                           IID_ISCardISO7816,
                           (LPVOID*) &g_pISCardISO7816);
//  Do challenge.
hresult = g_pISCardISO7816->GetChallenge(dwLengthOfChallenge,
                                         &g_pISCardCmd);

STDMETHODIMP
CSCardISO7816::GetChallenge(IN DWORD dwBytesExpected /*= 0*/,
                            IN OUT LPSCARDCMD *ppCmd)
{
    //  Locals.
    HRESULT hr = S_OK;
    
    try
    {
        //  Is the ISCardCmd object okay?
        hr = IsSCardCmdValid(ppCmd);
        if (FAILED(hr))
            throw (hr);

        //  Do it.
        hr = (*ppCmd)->BuildCmd(m_byClassId,
                                (BYTE) INS_GET_CHALLENGE,
                                (BYTE) INS_NULL,  // P1 = 0x00
                                (BYTE) INS_NULL,  // P2 = 0x00
                                NULL,
                                &dwBytesExpected);
        if (FAILED(hr))
            throw (hr);
    }
}