向智慧卡傳送指令
函式ScardTransmit()向智慧卡傳送指令,並接受返回的數據。
函式原型:LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_I0_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
各個參數的含義:
(1)hCard:輸入類型;與智慧卡連線的句柄。
(2)pioSendPci:輸入類型;指令的協定頭結構的指針,由SCARD_IO_REQUEST結構定義。後面是使用的協定的協定控制信息。一般使用系統定義的結構,SCARD_PCI_T0(T=0協定)、 SCARD_PCI_T1(T=1協定)、SCARD_PCI_RAW(原始協定)。
(3)pbSendBuffer:輸入類型;要傳送到智慧卡的數據的指針。
(4)cbSendLength:輸入類型;pbSendBuffer的位元組數目。
(5)pioRecvPci:輸入輸出類型;指令協定頭結構的指針,後面是使用的協定的協定控制信息,如果不返回協定控制信息,可以為NULL。
(6)pbRecvBuffer:輸出類型;從智慧卡返回的數據的指針。
(7)pcbRecvLength:輸入輸出類型;pbRecvBuffer的大小和實際大小。
對於T=0協定,收發緩衝的用法如下:
向智慧卡傳送數據
要向智慧卡傳送n>0位元組數據時,pbSendBuffer 前4位元組分別為T=0的CLA、INS、P1、P2,第5位元組是n,隨後是n位元組的數據;cbSendLength值為n+5(4位元組頭+1位元組Lc+n位元組數據)。PbRecvBuffer將接收SW1、SW2狀態碼;pcbRecvLength值在調用時至少為2,返回後為2。
BYTE recvBuffer[260];
int sendSize, recvSize;
BTYE sw1, sw2;
BYTE select_mf[]={0xC0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00};
sendSize=7;
recvSize=sizeof(recvBuffer);
lReturn = SCardTransmit(hCardHandle[0], SCARD_PCI_T0, select_mf, sendSize,
NULL, recvBuffer, &recvSize);
if ( lReturn != SCARD_S_SUCCESS )
{
printf("Failed SCardTransmit\n");
exit(1);
}
//返回的數據,recvSize=2
sw1=recvBuffer[recvSize-2];
sw2=recvBuffer[recvSize-1];
從智慧卡接收數據
為從智慧卡接收n>0位元組數據,pbSendBuffer 前4位元組分別為T=0的CLA、INS、P1、P2,第5位元組是n(即Le),如果從智慧卡接收256位元組,則第5位元組為0;cbSendLength值為5(4位元組頭+1位元組Le)。PbRecvBuffer將接收智慧卡返回的n位元組,隨後是SW1、SW2狀態碼;pcbRecvLength的值在調用時至少為 n+2,返回後為n+2。
BYTE get_challenge[]={0x00, 0x84, 0x00, 0x00, 0x08};
sendSize=5;
recvSize=sizeof(recvBuffer);
lReturn = SCardTransmit(hCardHandle[0], SCARD_PCI_T0, get_challenge,
sendSize, NULL, recvBuffer, &recvSize);
if ( lReturn != SCARD_S_SUCCESS )
{
printf("Failed SCardTransmit\n");
exit(1);
}
//返回的數據, recvSize=10
sw1=recvBuffer[recvSize-2];
sw2=recvBuffer[recvSize-1];
//data=recvBuffer[0]----recvBuffer[7]
數據交換
向智慧卡傳送沒有數據交換的命令
應用程式既不向智慧卡傳送數據,也不從智慧卡接收數據,pbSendBuffer 前4位元組分別為T=0的CLA、INS、P1、P2,不傳送P3;cbSendLength 值必須為4。PbRecvBuffer從智慧卡接收SW1、SW2狀態碼;pcbRecvLength值在調用時至少為2,返回後為2。
BYTE set_flag[]={0x80, 0xFE, 0x00, 0x00};
sendSize=4;
recvSize=sizeof(recvBuffer);
lReturn = SCardTransmit(hCardHandle[0], SCARD_PCI_T0, set_flag, sendSize,
NULL, recvBuffer, &recvSize);
if ( lReturn != SCARD_S_SUCCESS )
{
printf("Failed SCardTransmit\n");
exit(1);
}
//返回的數據,recvSize=2
sw1=recvBuffer[recvSize-2];
sw2=recvBuffer[recvSize-1];
向智慧卡傳送具有雙向數據交換的命令
T=0協定中,應用程式不能同時向智慧卡傳送數據,並從智慧卡接收數據,即傳送到智慧卡的指令中,不能同時有Lc和Le。這只能分兩步實現:向智慧卡傳送數據,接收智慧卡返回的狀態碼,其中,SW2是智慧卡將要返回的數據位元組數目;從智慧卡接收數據(指令為0x00、0xC0、0x00、0x00、Le)。
BYTE get_response={0x00, 0xc0, 0x00, 0x00, 0x00};
BYTE internal_auth[]={0x00, 0x88, 0x00, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
sendSize=13;
recvSize=sizeof(recvBuffer);
lReturn = SCardTransmit(hCardHandle[0], SCARD_PCI_T0, internal_auth,
sendSize, NULL, recvBuffer, &recvSize);
if ( lReturn != SCARD_S_SUCCESS )
{
printf("Failed SCardTransmit\n");
exit(1);
}
//返回的數據,recvSize=2
sw1=recvBuffer[recvSize-2];
sw2=recvBuffer[recvSize-1];
if ( sw1!=0x61 )
{
printf("Failed Command\n");
exit(1);
}
get_response[4]=sw2;
sendSize=5;
recvSize=sizeof(recvBuffer);
lReturn = SCardTransmit(hCardHandle[0], SCARD_PCI_T0, get_response,
sendSize, NULL, recvBuffer, &recvSize);
if ( lReturn != SCARD_S_SUCCESS )
{
printf("Failed SCardTransmit\n");
exit(1);
}
//返回的數據,recvSize=10
sw1=recvBuffer[recvSize-2];
sw2=recvBuffer[recvSize-1];
//data=recvBuffer[0]----recvBuffer[7]