生成 ISO7816-4 APDU 命令
若要向服务提供商添加功能,需要了解如何在基本服务提供商 DLL 中生成 ISO7816-4 应用程序协议数据单元 (APDU) 。 以下过程简要概述了生成过程。
注意
此处包含的示例不一定完整;有关详细信息,请参阅示例应用程序和 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 接口包含两个 IByteBuffer 缓冲区。 一个缓冲区包含实际的 APDU 命令字符串 (以及要随命令) 发送的任何数据。 另一个包含命令执行后卡返回的任何回复信息。
使用这些对象创建有效的 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);
}
}
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈