建置 ISO7816-4 APDU 命令
若要將功能新增至服務提供者,您必須知道 ISO7816-4 應用程式通訊協定資料單位 (APDU) 建置在基底服務提供者 DLL 內的方式。 下列程式提供建置程式的簡短概觀。
注意
此處包含的範例不一定完整;如需詳細資訊,請參閱範例應用程式和 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);
}
}