📄 pcsccom.cpp
字号:
//pcsccom.cpp
#include "stdafx.h"
#include "pcsccom.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <direct.h>
#include <windows.h>
#pragma data_seg ("PortData")
PCSCCOM_STRUCT g_STUPortArray[256];
#pragma data_seg ("PortData")
//IC function
BOOL PCSCCOM_API bOpenPort(UINT nPortNum)
{
BOOL bRtn(FALSE);
CFileException ex;
CHAR szPortName[32];
TCHAR szError[1024];
//int Result;
if(g_STUPortArray[nPortNum].bOpen != FALSE)
return FALSE;
sprintf(szPortName,"\\\\.\\COM%d",nPortNum+1);
g_STUPortArray[nPortNum].hPortFile = CreateFile(szPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); //
if(g_STUPortArray[nPortNum].hPortFile == INVALID_HANDLE_VALUE){
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),szError,1024,NULL);
pcscWriteErrorLog(szError,2);
return FALSE;
}
//set comm property
DCB dcb;
bRtn = GetCommState(g_STUPortArray[nPortNum].hPortFile,&dcb);
if(! bRtn){
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),szError,1024,NULL);
pcscWriteErrorLog(szError,2);
return bRtn;
}
dcb.BaudRate = CBR_9600;
//dcb.fParity = TRUE;
dcb.Parity = NOPARITY;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
//dcb.fAbortOnError = FALSE;
bRtn = SetCommState(g_STUPortArray[nPortNum].hPortFile,&dcb);
if(! bRtn){
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),szError,1024,NULL);
pcscWriteErrorLog(szError,2);
return bRtn;
}
// set event mask
bRtn = SetCommMask(g_STUPortArray[nPortNum].hPortFile,EV_RXCHAR|EV_TXEMPTY);
if(! bRtn){
pcscWriteErrorLog("Failed to Set Comm Mask",2);
return bRtn;
}
//set size of input/output buffer
SetupComm( g_STUPortArray[nPortNum].hPortFile, 1024,1024) ;
//clear up input/output buffer
PurgeComm( g_STUPortArray[nPortNum].hPortFile, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
//set comm timeout
COMMTIMEOUTS CommTimeout;
bRtn = GetCommTimeouts(g_STUPortArray[nPortNum].hPortFile,&CommTimeout);
if(! bRtn){
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),szError,1024,NULL);
sprintf(szError,"%s%s","Failed to get timeout configuration of current port:",szError);
pcscWriteErrorLog(szError,2);
return bRtn;
}
CommTimeout.ReadIntervalTimeout = MAXDWORD;
CommTimeout.ReadTotalTimeoutConstant = 0;
CommTimeout.ReadTotalTimeoutMultiplier = 0;
CommTimeout.WriteTotalTimeoutConstant = 0;
CommTimeout.WriteTotalTimeoutMultiplier = 0;
bRtn = SetCommTimeouts(g_STUPortArray[nPortNum].hPortFile,&CommTimeout);
if(! bRtn){
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),szError,1024,NULL);
sprintf(szError,"%s%s","Failed to configure timeout of current port:",szError);
pcscWriteErrorLog(szError,2);
return bRtn;
}/**/
// init ProcessCompletionEvent
g_STUPortArray[nPortNum].ReceiveEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
g_STUPortArray[nPortNum].ROverlapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
g_STUPortArray[nPortNum].hCardChangedMutex = CreateMutex( NULL, FALSE, NULL );
// reset reader
EscapeCommFunction( g_STUPortArray[nPortNum].hPortFile, SETDTR );
EscapeCommFunction( g_STUPortArray[nPortNum].hPortFile, SETRTS );
Sleep( 100 );
//init other variable
g_STUPortArray[nPortNum].bOpen = TRUE;
g_STUPortArray[nPortNum].fReadReady = FALSE;
g_STUPortArray[nPortNum].fAPDUHead = FALSE;
g_STUPortArray[nPortNum].fConnect = FALSE;
g_STUPortArray[nPortNum].nTryConnect = 0;
return TRUE;
}
UINT PCSCCOM_API iConnectCard(UINT nPortNum, UINT nProtocolType, BYTE *pATR, UINT *nATRLen)
{
BYTE lBuf[1024],szBuf[512];
UINT nReadDataLen(0),nPackLen(0);
CHAR szSendData[1024];
UINT iRtn(0);
DWORD length(0);
char szErrorMsg[1024];
BOOL bRtn(FALSE);
g_STUPortArray[nPortNum].nProtocolType = nProtocolType;
if(INVALID_HANDLE_VALUE == g_STUPortArray[nPortNum].hPortFile)
return UINT(FAIL_COMMUNICATE);
if(1 == g_STUPortArray[nPortNum].nProtocolType)
g_STUPortArray[nPortNum].fAPDUHead = FALSE;
//bReadData(nPortNum,lBuf,&nReadDataLen);
iRtn = iDisconnectCard(nPortNum);
if(0x9000 == iRtn){
switch(g_STUPortArray[nPortNum].nProtocolType)
{
case 0://cpu t=0
break;
case 1://cpu t=1
break;
case 2://sle4428 AM8KS
iRtn = bSetMemoryICType(nPortNum, "0102010507", 10);
if(iRtn != 0x9000)
return iRtn;
break;
case 3://sle4442 AM2KS
iRtn = bSetMemoryICType(nPortNum, "0102010604", 10);
if(iRtn != 0x9000)
return iRtn;
break;
case 4://sle4406 ST1305 AM104 GPM103 AT88SC06
iRtn = bSetMemoryICType(nPortNum, "0102010103", 10);
if(iRtn != 0x9000)
return iRtn;
break;
case 5://at24c01-16 ST14C02C ST14C04C AM1KF-4KF GFM1K-8K
iRtn = bSetMemoryICType(nPortNum, "0102010200", 10);
if(iRtn != 0x9000)
return iRtn;
break;
default:
return UINT(WRONG_INS_STRUCT);
}
memcpy(szSendData,"\x02",1);
memcpy(szSendData+1,"01800081",8);
memcpy(szSendData+9,"\x03",1);
bRtn = bWriteData(nPortNum,szSendData,10);
memset(lBuf,0,1024);
memset(szBuf,0,512);
iRtn = bReadData(nPortNum,lBuf,&nReadDataLen);
if(iRtn != TRUE)
{
sprintf(szErrorMsg,"COM%d: iConnectCard failed to read data from port for connecting reader , SW:1111",nPortNum+1);
pcscWriteErrorLog(szErrorMsg,3);
return UINT(FAIL_READ_DATA);
}
nPackHexToByte(lBuf,nReadDataLen,szBuf,&nPackLen);
if(!( (szBuf[0] == 0x01) && (szBuf[1] == 0x90) && (szBuf[2] == 0x00) ) )
{
if((szBuf[0] == 0x01) && (szBuf[1] == 0x60) && (szBuf[2] == 0x02) && (szBuf[3] == 0x00))
{
if(g_STUPortArray[nPortNum].nTryConnect > 10)
{
sprintf(szErrorMsg,"COM%d: iConnectCard returning data is wrong for connecting reader , %s",nPortNum+1,lBuf);
pcscWriteErrorLog(szErrorMsg,3);
g_STUPortArray[nPortNum].nTryConnect = 0;
return UINT(WRONG_RETURN_FORMAT);
}
else
{
return iConnectCard(nPortNum, nProtocolType, pATR, nATRLen);
}
}
else
{
sprintf(szErrorMsg,"COM%d: iConnectCard returning data is wrong for connecting reader ,%s",nPortNum+1,lBuf);
pcscWriteErrorLog(szErrorMsg,3);
return UINT(WRONG_RETURN_FORMAT);
}
}
else{
memcpy(pATR,szBuf+4,szBuf[3]);//-1
*nATRLen = szBuf[3];//-2;
pATR[*nATRLen] = 0;
if(g_STUPortArray[nPortNum].nProtocolType != 5)
{
if(0 == *nATRLen)
{
return UINT(WRONG_READ_LENGTH);
}
}
switch(g_STUPortArray[nPortNum].nProtocolType){
case 1:
memcpy(szSendData,"\x02",1);
memcpy(szSendData+1,"01A10500C101F838A5",18);
memcpy(szSendData+19,"\x03",1);
bRtn = bWriteData(nPortNum,szSendData,20);
memset(lBuf,0,1024);
iRtn = bReadData(nPortNum,lBuf,&nReadDataLen);
if(iRtn != TRUE)
{
sprintf(szErrorMsg,"COM%d: iConnectCard t=1 failed to read data from port, SW:1111",nPortNum+1);
pcscWriteErrorLog(szErrorMsg,3);
return UINT(FAIL_READ_DATA);
}
else
{
lBuf[nReadDataLen] = 0;
if(strcmp((char*)lBuf,(char*)"0190000500E101F81894") != 0)
{
sprintf(szErrorMsg,"COM%d: iConnectCard t=1 reading data is wrong ,not 0190000500E101F81894, %s",nPortNum+1,lBuf);
pcscWriteErrorLog(szErrorMsg,3);
return UINT(FAIL_SET_T1);
}
}
break;
default:
break;
}
}
}
else
{
sprintf(szErrorMsg,"COM%d: iDisconnectCard SW:FFFF",nPortNum+1);
pcscWriteErrorLog(szErrorMsg,3);
return UINT(FAIL_COMMUNICATE);
}
g_STUPortArray[nPortNum].fConnect = TRUE;
return UINT(0x9000);
}
UINT PCSCCOM_API iTransmitAPDU(UINT nPortNum, BYTE *pInData, UINT nInDataLen, BYTE *pOutData, UINT *nOutDataLen)
{
BYTE lBuf[1024],szBuf[512];
UINT nReadDataLen(0),nPackLen(0);
BYTE szSendData[1024];
UINT iRtn(0),nRtnValue(0xFFFF);
CHAR Buf[5];
BOOL bRtn(FALSE);
UINT nLc = 0;
if(INVALID_HANDLE_VALUE == g_STUPortArray[nPortNum].hPortFile)
return UINT(FAIL_COMMUNICATE);
if(! g_STUPortArray[nPortNum].fConnect)
return UINT(FAIL_COMMUNICATE);
if(nInDataLen%2)
return nInDataLen;
memset(szSendData,0,576);
memcpy(szSendData,"\x02",1);
switch(g_STUPortArray[nPortNum].nProtocolType){
case 0:
memcpy(szSendData+1,"01A0",4);
sprintf(Buf,"%02X",nInDataLen/2);
memcpy(szSendData+5,Buf,2);
memcpy(szSendData+7,pInData,nInDataLen);
nPackHexToByte(szSendData+1,nInDataLen+6,szBuf,&nPackLen);
sprintf(Buf,"%02X",cSumParityByte(szBuf,nPackLen));
memcpy(szSendData+7+nInDataLen,Buf,2);
memcpy(szSendData+9+nInDataLen,"\x03",1);
memcpy(szSendData+10+nInDataLen, "\x00", 1);
break;
case 1:
g_STUPortArray[nPortNum].fAPDUHead = !g_STUPortArray[nPortNum].fAPDUHead;
memcpy(szSendData+1,"01A1",4);
sprintf(Buf,"%02X",nInDataLen/2+4);
memcpy(szSendData+5,Buf,2);
if(g_STUPortArray[nPortNum].fAPDUHead)
memcpy(szSendData+7,"0000",4);
else
memcpy(szSendData+7,"0040",4);
sprintf(Buf,"%02X",nInDataLen/2);
memcpy(szSendData+11,Buf,2);
memcpy(szSendData+13,pInData,nInDataLen);
nPackHexToByte(szSendData+9,nInDataLen+4,szBuf,&nPackLen);
sprintf(Buf,"%02X",cSumParityByte(szBuf,nPackLen));
memcpy(szSendData+13+nInDataLen,Buf,2);
nPackHexToByte(szSendData+1,nInDataLen+14,szBuf,&nPackLen);
sprintf(Buf,"%02X",cSumParityByte(szBuf,nPackLen));
memcpy(szSendData+15+nInDataLen,Buf,2);
memcpy(szSendData+17+nInDataLen,"\x03",1);
memcpy(szSendData+18+nInDataLen, "\x00", 1);
break;
default :
memcpy(szSendData+1, pInData, 4);//copy INS
switch(pInData[3])
{
case '0':
//read data from IC
memcpy(szSendData+5, "030000", 6);
memcpy(szSendData+11, pInData+10, 2);//copy Le
nPackHexToByte(szSendData+1, 12, szBuf, &nPackLen);
sprintf(Buf,"%02X",cSumParityByte(szBuf,nPackLen));
memcpy(szSendData+13, Buf, 2);
memcpy(szSendData+15,"\x03",1);
memcpy(szSendData+16, "\x00", 1);
break;
case '1':
//write data to IC
nPackHexToByte(pInData+8, 2, szBuf, &nPackLen);
nLc = szBuf[0];
sprintf(Buf, "%02X", nLc+2);
memcpy(szSendData+5, Buf, 2);
memcpy(szSendData+7, "0000", 4);
memcpy(szSendData+11, pInData+10, 2*nLc);
nPackHexToByte(szSendData+1, 10+2*nLc, szBuf, &nPackLen);
sprintf(Buf,"%02X",cSumParityByte(szBuf,nPackLen));
memcpy(szSendData+11+2*nLc, Buf, 2);
memcpy(szSendData+13+2*nLc, "\x03", 1);
memcpy(szSendData+14+2*nLc, "\x00", 1);
break;
case '2':
nPackHexToByte(pInData+8, 2, szBuf, &nPackLen);
nLc = szBuf[0];
memcpy(szSendData+5, pInData+8, 2*(nLc+1));
nPackHexToByte(szSendData+1, 6+2*nLc, szBuf, &nPackLen);
sprintf(Buf,"%02X",cSumParityByte(szBuf,nPackLen));
memcpy(szSendData+7+2*nLc, Buf, 2);
memcpy(szSendData+9+2*nLc, "\x03", 1);
memcpy(szSendData+10+2*nLc, "\x00", 1);
break;
default:
return UINT(WRONG_INS_STRUCT);
break;
}
break;
}
/////////execute apdu and read data
bRtn = bWriteData(nPortNum, (CHAR*)szSendData, strlen((CHAR*)szSendData));
//read data for last apdu
iRtn = bReadData(nPortNum,lBuf,&nReadDataLen);
if(iRtn != TRUE)
return UINT(FAIL_READ_DATA);
//parse reading data
nPackHexToByte(lBuf,nReadDataLen,szBuf,&nPackLen);
if(4 == nReadDataLen)
return UINT(256*szBuf[0]+szBuf[1]);
if(!( (szBuf[0] == 0x01) && (szBuf[1] == 0x90) && (szBuf[2] == 0x00) ))
return UINT(WRONG_RETURN_FORMAT);//fromat of returning data is wrong
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -