#include "StdAfx.h"
#include "PCSC.h"
CPCSC::CPCSC()
{
m_hContext = 0;
m_hCard = 0;
m_mszReader = NULL;
m_IsConnect = false;
m_IsReset = false;
memset(m_strReaderName, 0, 256);
}
CPCSC::~CPCSC()
{
DisConnectCard();
}
bool CPCSC::ConnectCard(IN char* pcReaderName)
{
//建立读卡器上下文
if(m_IsConnect)
DisConnectCard();
if (SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &m_hContext) != SCARD_S_SUCCESS)
{
m_IsConnect = false;
return FALSE;
}
//连接读卡器
DWORD dwRes = 0;
dwRes = SCardConnect(m_hContext, (LPCSTR)pcReaderName, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, &m_hCard, &m_DWAP);
if((dwRes != SCARD_S_SUCCESS) && (dwRes !=SCARD_W_REMOVED_CARD))
{
m_IsConnect = false;
return FALSE;
}
m_IsConnect = true;
return TRUE;
}
bool CPCSC::GetReadList(IN char * sReader,OUT vector<string> &vReaderList)
{
SCARDCONTEXT hContext = NULL;
vReaderList.clear();
char *szReaderName = NULL;
DWORD dwcReaders = SCARD_AUTOALLOCATE;
//建立读卡器上下文
if (SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext) != SCARD_S_SUCCESS)
{
return FALSE;
}
//列表读卡器
if(SCardListReaders(hContext, (LPCSTR)sReader, (LPSTR)&szReaderName, &dwcReaders) != SCARD_S_SUCCESS)
{
return FALSE;
}
//分拆读卡器名称
int iCount = 0;
//读卡器列表中最近一次0x00字符的位置
int iZeroMark = -1;
while (iCount <= dwcReaders)
{
if (0x00 == szReaderName[iCount])
{
//string strTemp(szReaderName + iZeroMark + 1, szReaderName + iCount);
string strTemp;
vReaderList.push_back(strTemp);
vReaderList[vReaderList.size() - 1] = szReaderName + iZeroMark + 1;
iZeroMark = iCount;
}
iCount++;
}
if(szReaderName)
SCardFreeMemory(hContext, szReaderName);
if(hContext)
SCardReleaseContext(hContext);
return TRUE;
}
void CPCSC::DisConnectCard()
{
m_IsConnect = false;
m_IsReset = false;
if(m_hCard)
{
::SCardDisconnect(m_hCard,SCARD_EJECT_CARD);
m_hCard = 0;
}
if(m_hContext)
{
::SCardReleaseContext(m_hContext);
m_hContext = 0;
}
}
//bool CPCSC::SELECT(IN WORD wFileID, OUT BYTE& byResLen)
bool CPCSC::SendCmd(IN BYTE ucCmd[], IN DWORD CmdLen, OUT BYTE* Response, OUT DWORD& ResponseLen,OUT WORD& WSW)
{
//组织Select命令的APDU指令
BYTE ucRes[1024]={0};
DWORD dwlen = 1024;
LONG lReturn = 0;
lReturn = ::SCardBeginTransaction(m_hCard);
if(lReturn != SCARD_S_SUCCESS)
return false;
//发送APDU指令
if(!RunAPDU(ucCmd,CmdLen,ucRes,dwlen))
{
return false;
}
BYTE sw1 = ucRes[dwlen-2];
BYTE sw2 = ucRes[dwlen-1];
if(sw1 != 0x61 && sw1 != 0x90 && sw1 != 0x6c)
{
WSW = MAKEWORD(ucRes[dwlen-1],ucRes[dwlen-2]);
return true;
}
if((2 == dwlen && sw1 == 0x61))
{
memcpy(ucCmd,"\x00\xc0\x00\x00",4);
ucCmd[4]=sw2;
CmdLen = 5;
dwlen = 1024;
DWORD dwRet = ::SCardTransmit(m_hCard,SCARD_PCI_T0, ucCmd, CmdLen, NULL,ucRes, (DWORD*)&dwlen);
if(dwRet != SCARD_S_SUCCESS)
{
return false;
}
}
if((2 == dwlen) && (sw1 == 0x6c))
{
ucCmd[4] = sw2;
CmdLen = 5;
dwlen = 1024;
DWORD dwRet = ::SCardTransmit(m_hCard,
SCARD_PCI_T0, ucCmd, CmdLen,
NULL,ucRes, (DWORD*)&dwlen);
if(dwRet != SCARD_S_SUCCESS)
{
return false;
}
}
WSW = MAKEWORD(ucRes[dwlen-1],ucRes[dwlen-2]);
memcpy(Response,ucRes,dwlen-2);
ResponseLen = dwlen-2;
lReturn = ::SCardEndTransaction(m_hCard,SCARD_LEAVE_CARD);
if(lReturn != SCARD_S_SUCCESS)
return false;
return true;
}
bool CPCSC::STATUS()
{
//组织Status命令的APDU指令
long lReturn = 0;
DWORD dwATRLength = 40;
BYTE pbyATR[256];
DWORD dwCardState = 0;
// lReturn = SCardReconnect(m_hCard,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1,SCARD_RESET_CARD,&m_DWAP);
// if((lReturn != SCARD_S_SUCCESS) && (lReturn !=SCARD_W_REMOVED_CARD))
// {
// return FALSE;
// }
lReturn = SCardStatus(m_hCard, NULL, NULL, &dwCardState, NULL, pbyATR,&dwATRLength);
if(lReturn != SCARD_S_SUCCESS)
{
return false;
}
lReturn = SCardStatus(m_hCard, NULL, NULL, &dwCardState, NULL, pbyATR,&dwATRLength);
if(lReturn != SCARD_S_SUCCESS)
{
return false;
}
return true;
}
bool CPCSC::RESETCARD(OUT BYTE* pbATR, OUT DWORD* dwATRLen)
{
//连接读卡器
DWORD dwRes = 0;
dwRes = SCardReconnect(m_hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &m_DWAP);
if((dwRes != SCARD_S_SUCCESS) && (dwRes !=SCARD_W_REMOVED_CARD))
{
m_IsReset = false;
return FALSE;
}
DWORD dwState = 0;
//检查卡片状态,获取复位信息
BYTE pbATRTemp[256] = {0};
DWORD dwAtrLenTemp = 0;
dwRes = SCardStatus(m_hCard, NULL, NULL, &dwState, NULL, pbATRTemp, &dwAtrLenTemp);
if(dwRes != SCARD_S_SUCCESS)
{
m_IsReset = false;
return FALSE;
}
dwRes = SCardStatus(m_hCard, NULL, NULL, &dwState, NULL, pbATRTemp, &dwAtrLenTemp);
if(dwRes != SCARD_S_SUCCESS)
{
m_IsReset = false;
return FALSE;
}
memcpy(pbATR, pbATRTemp, dwAtrLenTemp);
*dwATRLen = dwAtrLenTemp;
m_IsReset = true;
return TRUE;
}
bool CPCSC::RunAPDU(IN BYTE* ucCmd, IN DWORD nCmdLen, OUT BYTE* ucRes, IN OUT DWORD& nResLen)
{
//判断读卡器是否连接
if(!m_hCard)
{
return false;
}
//发送数据请求
SCARD_IO_REQUEST sendPci;
sendPci.dwProtocol = m_DWAP;
sendPci.cbPciLength = sizeof(sendPci);
if(::SCardTransmit(m_hCard,&sendPci,ucCmd,nCmdLen,NULL,ucRes,(DWORD*)&nResLen) != SCARD_S_SUCCESS)
{
return false;
}
return true;
}
PCSC标准读卡器接口
需积分: 30 36 浏览量
2018-04-08
19:06:28
上传
评论
收藏 4KB ZIP 举报
you74092078
- 粉丝: 2
- 资源: 3
最新资源
- 原生微信小程序源码 - -仿豆瓣图书
- 原生微信小程序源码 - -滴滴公交-查公交
- 人工智能实验四 感知器算法的设计实现
- java小项目多线程多线程 复制文件 冒泡排序 群聊
- 四数之和(java代码).docx
- 701837906919458TapScanner v3.0.10 (Pro).apk
- 青岛大学人工智能实验二 利用α-β搜索的博弈树算法编写一字棋游戏
- ### 1、项目介绍 本项目Scrapy进行数据爬取,并使用Django框架+PyEcharts实现可视化大屏 效果如下:
- # 微信小程序-健康菜谱 基于微信小程序的一个查找检索菜谱的应用 ### 效果 !动态图(./res/gif/demo
- zabbix-get命令包资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈