ISO7816-4 APDU コマンドのビルド
サービス プロバイダーに機能を追加するには、ベース サービス プロバイダー DLL 内に ISO7816-4 アプリケーション プロトコル データ ユニット (APDU) がどのように構築されているかを把握する必要があります。 次の手順では、ビルド プロセスの概要を示します。
Note
ここに含まれる例は必ずしも完全ではありません。詳細については、サンプル アプリケーションと DLL を参照してください。
ISO7816-4 APDU コマンドをビルドするには
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 つのには、コマンドの実行後にカードによって返された応答情報が含まれます。
これらのオブジェクトを使用して、次のように有効な 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;
ビルドされた 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);
}
}