Windows系统提供了大量的API来方便的进行智能卡应用程序的开发,通过它们我们可以直接控制智能卡读卡器对智能卡进行操作,也可以与智能卡建立直接的虚拟连接而不用考虑智能卡读卡器。
智能卡应用程序开发的一般流程是:
1)建立连接(使用函数SCardEstablishContext和SCardConnect,SCardReconnect);
2)开始事务处理(使用函数SCardBeginTransaction);
3)进行事务处理(使用函数SCardTransmit);
4)结束事务处理(使用函数SCardEndTransaction);
5)断开连接(使用函数SCardDisconnect和SCardReleaseContext)。
下面就具体看看各个函数的功能和用法吧!
1)SCardEstablishContext函数用于建立进行设备数据库操作的资源管理器上下文:
LONG WINAPI SCardEstablishContext(
__in DWORD dwScope, //资源管理器上下文的范围,取值如下:
//SCARD_SCOPE_USER---数据库操作在用户域中
//SCARD_SCOPE_SYSTEM---数据库操作在系统域中,调用的应用程序
//必须具有对任何数据库操作的权限
__in LPCVOID pvReserved1, //保留值,必须设为NULL
__in LPCVOID pvReserved2, //保留值,必须设为NULL
__out LPSCARDCONTEXT phContext //建立的资源管理器上下文句柄
);
返回值:成功时返回SCARD_S_SUCCESS;失败时返回智能卡特定错误码。
函数返回的资源管理器上下文句柄可以被对设备数据库进行查询和管理的函数使用。如果一个客户试图在远程会话中实现智能卡操作,例如运行在终端服务器上的客户会话,而且客户会话所在的操作系统不支持智能卡重定向,则函数SCardEstablishContext返回ERROR_BROKEN_PIPE。
下面的代码是建立资源管理器上下文的例子:
SCARDCONTEXT hSC;
LONG lReturn;
//Establish the context
lReturn = SCardEstablishContext(SCARD_SCOPE_USER,
NULL, NULL, &hSC);
if(SCARD_S_SUCCESS != lReturn)
printf("Failed SCardEstablishContext/n");
else
{
//Use the context as needed, when done,
//free the context by calling SCardReleaseContext
}
2)SCardConnect函数利用特定资源管理器上下文,在应用程序与包含在特定读卡器中的智能卡之间建立一条连接:
LONG WINAPI SCardConnect(
__in SCARDCONTEXT hContext, //资源管理器上下文句柄
__in LPCTSTR szReader, //包含目标智能卡的读写器名字
__in DWORD dwShareMode, //标志其他应用程序是否可以与该智能卡建立连接,取值如下:
//SCARD_SHARE_SHARED---与其他应用程序共享该智能卡
//SCARD_SHARE_EXCLUSIVE---独占该智能卡
//SCARD_SHARE_DIRECT---本应用程序将读写器作为私有使用,并且直接
//控制它,其他应用程序没有权限使用该读写器
__in DWORD dwPreferredProtocols, //可接受协议的位掩码,可是如下的组合:
//SCARD_PROTOCOL_T0--- T=0是可接受协议
//SCARD_PROTOCOL_T1--- T=0是可接受协议
//0--- 该参数只有当dwShareMode是SCARD_SHARE_DIRECT时才能为0;
//这种情况下,驱动程序不会处理任何协议协商,直到将控制指令
//IOCTL_SMARTCARD_SET_PROTOCOL发送给SCardControl
__out LPSCARDHANDLE phCard, //标识与特定读卡器中智能卡连接的句柄
__out LPDWORD pdwActiveProtocol //返回已建立的活动协议,取值如下:
//SCARD_PROTOCOL_T0--- T=0是活动协议;
//SCARD_PROTOCOL_T1--- T=1是活动协议;
//SCARD_PROTOCOL_UNDEFINED---SCARD_SHARE_DIRECT标志被
//被设置,因此没有任何协议协商发生;这时读卡器中可能没有智能卡
);
返回值:成功时返回SCARD_S_SUCCESS;失败时返回智能卡错误码。
函数SCardConnect是智能卡和读卡器访问函数,下面的代码创建和读卡器的连接,代码中假定hContext是由函数SCardEstablishContext返回的有效的资源上下文句柄:
SCARDHANDLE hCardHandle;
LONG lReturn;
DWORD dwAP;
lReturn = SCardConnect(hContext, (LPCTSTR)"Rainbow Technologies SCR3531 0",
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
&hCardHandle, &dwAP);
if(SCARD_S_SUCCESS != lReturn)
{
printf("Failed SCardConnect/n");
return;
}
//Use the connection. Display the active protocol
switch(dwAP)
{
case SCARD_PROTOCOL_T0:
printf("Active protocol T0/n");
break;
case SCARD_PROTOCOL_T1:
printf("Active protocol T1/n");
break;
case SCARD_PROTOCOL_UNDEFINED:
default:
printf("Active protocol unnegotiated or unknown/n");
break;
}
//Remember to disconnect(by calling SCardDisconnect)
3)SCardBeginTransaction函数在开始执行前,先等待其他所有事务完成。当该事务开始后,其他应用程序不允许在事务期间访问智能卡:
LONG WINAPI SCardBeginTransaction(
__in SCARDHANDLE hCard //调用SCardConnect所获得的连接句柄
);
返回值:成功时返回SCARD_S_SUCCESS;失败时返回智能卡错误代码。
注意:即使另一个进程或线程重置了智能卡,本函数仍然返回SCARD_S_SUCCESS,要确定智能卡是否被重置,可以在该函数调用后立即调用SCardStatus函数。
SCardBeginTransaction函数同样是智能卡和读卡器访问函数。下面的代码片段展示了开始智能卡事务:
lReturn = SCardBeginTransaction( hCard );
if ( SCARD_S_SUCCESS != lReturn )
printf("Failed SCardBeginTransaction/n");
4)SCardTransmit函数用来发送服务请求给智能卡,并接收从智能卡返回的数据:
LONG WINAPI SCardTransmit(
__in SCARDHANDLE hCard, //由函数SCardConnect返回的连接句柄
__in LPCSCARD_IO_REQUEST pioSendPci, //指向指令的协议头结构的指针
//一般使用系统定义的结构:
// SCARD_PCI_T0(T=0协议);
// SCARD_PCI_T1(T=1协议);
// SCARD_PCI_RAW(原始协议)
__in LPCBYTE pbSendBuffer, //要发送到智能卡的数据的指针
__in DWORD cbSendLength, //pbSendBuffer的字节长度
__inout_opt LPSCARD_IO_REQUEST pioRecvPci, //指向指令的协议头结构的指针,该参数当没有
//协议控制信息PCI返回时可设为NULL
__out LPBYTE pbRecvBuffer, //从智能卡返回的数据的指针
__inout LPDWORD pcbRecvLength //pbRecvBuffer的字节长度
);
返回值:成功时返回SCARD_S_SUCCESS;失败时返回智能卡错误代码。
SCARD_IO_REQUEST结构开启一个协议控制信息结构,任何特定协议信息立即跟在这个结构之后。该结构的总长度必须根据底层硬件结构字节长度进行对齐。例如,在Win32中,任何PCI(Protocol Control Information)信息的长度一定是4字节的整数倍,即对齐到32位边界。结构定义如下:
typedef struct {
DWORD dwProtocol; //使用的协议
DWORD cbPciLength; //本结构的字节长度(加上任何跟随的特定PCI信息长度)
} SCARD_IO_REQUEST;
使用函数SCardTransmit的代码片段:
// Transmit the request.
// lReturn is of type LONG.
// hCardHandle was set by a previous call to SCardConnect.
// pbSend points to the buffer of bytes to send.
// dwSend is the DWORD value for the number of bytes to send.
// pbRecv points to the buffer for returned bytes.
// dwRecv is the DWORD value for the number of returned bytes.
lReturn = SCardTransmit(hCardHandle,
SCARD_PCI_T0,
pbSend,
dwSend,
NULL,
pbRecv,
&dwRecv );
if ( SCARD_S_SUCCESS != lReturn )
{
printf("Failed SCardTransmit/n");
exit(1); // or other appropriate error action
}
5)SCardEndTransaction函数完成先前声明的一个事务,并允许其他应用程序恢复与智能卡的交互:
LONG WINAPI SCardEndTransaction(
__in SCARDHANDLE hCard, //由函数SCardConnect返回的连接句柄
__in DWORD dwDisposition //断开连接时对智能卡的操作,取值如下:
//SCARD_EJECT_CARD---弹出智能卡;
//SCARD_LEAVE_CARD---不做任何操作
//SCARD_RESET_CARD---复位智能卡
//SCARD_UNPOWER_CARD---给智能卡掉电
);
返回值:成功时返回SCARD_S_SUCCESS;失败时返回智能卡错误代码,例如:
SCARD_W_RESET_CARD---事务被释放,但是将来任何和智能卡的通信都需要调用SCardReconnect函数。但是对于以下操作系统:Windows Server 2008,WindowsVista,Windows Server 2003,Windows XP和Windows 2000而言,事务并没有释放掉,应用程序必须马上调用函数SCardDisconnect、SCardReconnect或SCardReleaseContext来避免该事务阻塞其他线程或进程与智能卡的交互。
函数使用的代码片段如下:
lReturn = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
if ( SCARD_S_SUCCESS != lReturn )
printf("Failed SCardEndTransaction/n");
6)SCardDisconnect函数用来断开先前在应用程序和智能卡之间建立的连接:
LONG WINAPI SCardDisconnect(
__in SCARDHANDLE hCard, //由函数SCardConnect返回的连接句柄
__in DWORD dwDisposition //断开连接时对智能卡的操作,取值如下:
//SCARD_EJECT_CARD---弹出智能卡;
//SCARD_LEAVE_CARD---不做任何操作
//SCARD_RESET_CARD---复位智能卡
//SCARD_UNPOWER_CARD---给智能卡掉电
);
返回值:成功时是SCARD_S_SUCCESS;失败时是智能卡错误代码。
如果一个先前建立连接的应用程序退出前没有调用SCardDisconnect函数,则智能卡会自动重置。函数使用的代码片段如下:
lReturn = SCardDisconnect(hCardHandle,
SCARD_LEAVE_CARD);
if ( SCARD_S_SUCCESS != lReturn )
{
printf("Failed SCardDisconnect/n");
exit(1); // Or other appropriate action.
}
7)SCardReconnect函数用来重新建立应用程序与智能卡直接已存在的连接。该函数可以使智能卡句柄从直接访问变为普通访问,或者确认并清除阻止对智能卡进行访问的错误状态:
LONG WINAPI SCardReconnect(
__in SCARDHANDLE hCard, //由SCardConnect返回的连接句柄
__in DWORD dwShareMode, //标志其他应用程序能否建立与该智能卡的连接,取值如下:
//SCARD_SHARE_SHARED---可以共享;
//SCARD_SHARE_EXCLUSIVE---独占使用
__in DWORD dwPreferredProtocols, //该连接允许接受的协议,组合如下:
//SCARD_PROTOCOL_T0--- T=0是可接受的协议;
//SCARD_PROTOCOL_T1--- T=1是可接受的协议
__in DWORD dwInitialization, //初始化类型:
//SCARD_LEAVE_CARD---不做任何操作
//SCARD_RESET_CARD---重置智能卡(热重置)
//SCARD_UNPOWER_CARD---将智能卡掉电后再重置(冷重置)
__out_opt LPDWORD pdwActiveProtocol //已建立的活动协议:
//SCARD_PROTOCOL_T0--- T=0是活动协议
//SCARD_PROTOCOL_T1--- T=1是活动协议
);
返回值:成功时是SCARD_S_SUCCESS;失败时是智能卡错误代码。
函数使用的代码片段如下:
DWORD dwAP;
LONG lReturn;
// Reconnect.
// hCardHandle was set by a previous call to SCardConnect.
lReturn = SCardReconnect(hCardHandle,
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
SCARD_LEAVE_CARD,
&dwAP );
if ( SCARD_S_SUCCESS != lReturn )
printf("Failed SCardReconnect/n");
8)SCardReleaseContext函数关闭建立的资源管理器上下文,并释放分配给该上下文的资源:
LONG WINAPI SCardReleaseContext(
__in SCARDCONTEXT hContext
);
返回值:成功时是SCARD_S_SUCCESS;失败时是智能卡错误代码。
函数使用的代码片段如下:
// Free the context.
// lReturn is of type LONG.
// hSC was set by an earlier call to SCardEstablishContext.
lReturn = SCardReleaseContext(hSC);
if ( SCARD_S_SUCCESS != lReturn )
printf("Failed SCardReleaseContext/n");
分享到:
相关推荐
asce1885-blogasce1885的博客
ASCE(American Society of ...通过研究这个项目,开发者可以学习到如何利用MFC高效地构建用户界面,尤其是如何利用List控件来展示和管理数据,这对于任何需要处理大量信息的Windows应用程序开发都具有很高的参考价值。
PHASE II OF THE ASCE BENCHMARK STUDY ON SHM
ASCE为全球最大的土木工程信息知识的出版机构,每年出版超过5万页的出版物,包括专业和技术期刊、专业会议录、图书、实践手册、标准专论等。 ASCE期刊是土木工程学科的主要核心期刊,包括30种专业技术期刊,由专业...
此为ASCE的第三代基准模型代码,可供土木工程领域学者使用。
ASCE LaTeX 指南主要介绍了土木工程学会(American Society of Civil Engineers,简称ASCE)期刊的LaTeX投稿流程和注意事项。由于ASCE期刊接受LaTeX格式的投稿,因此作者需要按照特定的模板和格式要求提交论文。本文...
### ASCE7-10《建筑物和其他结构最小设计荷载》关键知识点解析 #### 一、规范内容简介 美国土木工程师学会(American Society of Civil Engineers, ASCE)发布的ASCE7-10标准《建筑物和其他结构最小设计荷载》,...
EndNote软件提供了各种预设的样式模板,用户可以根据需要选择对应的期刊格式,如ASCE Journals或APA,将引用的文献信息导入后,EndNote会自动按照选定的样式格式化引用。用户还可以自定义样式,以满足特定期刊的特殊...
ASCE全文数据库是一个由iGroup公司提供的专业资源,主要聚焦于土木工程领域的知识与研究。这个数据库由美国土木工程师协会(American Society of Civil Engineers)出版,该协会成立于1852年,是全球最大的土木工程...
根据给定文件信息,本篇文档是关于Android研发工程师高级进阶技能的介绍,涉及了函数响应式编程、Android Support Annotations、RxJava、Android应用性能优化、Fragment使用、依赖注入、ASCE1885动态启发技术等技术...
ASCE-7-2005美国荷载规范中文版知识点总结 ASCE-7-2005美国荷载规范中文版是美国 土木工程师协会(ASCE)发布的一份最小设计荷载规范。该规范涵盖了建筑和其他结构的设计荷载要求,旨在确保建筑和结构的安全和可靠...
在选择InChorus应用前端交换机时,需要考虑多种因素,包括设备的性能、可扩展性、安全性、易用性等。InChorus应用前端交换机的核心是虚拟服务器的概念,它提供了智能内容交换、应用加速、数据压缩、TCP offload、SSL...
ASCE 7-10美国建筑荷载规范(中文版) ASCE 7-10《建筑物和其他结构最小设计荷载》(Minimum Design Loads for Buildings and Other Structures)是由美国土木工程学会(ASCE)发布的一份重要的建筑荷载规范。该...
ANSI ASCE CI 71-21 Identifying, Quantifying, and Proving Loss of Productivity.pdf
6. **ASEE AC 2012-4751.pdf** - 这可能是一篇学术论文或会议报告,详细描述了VUKinect项目在2012年美国土木工程师学会(ASCE)活动中的应用或成果。 7. **license.txt** - 包含项目的许可信息,规定了使用、修改和...
IES VisualFoundation是结构工程师和专业人员分析和设计复杂的席式基础和组合基础的强大应用程序。它是一个全面的套件,提供了各种先进和强大的工具,用于分析复杂的结构组件。这是一个有效的应用程序,为结构工程师...
结构安全和结构动力学有许多领域,通常需要计算随机变量函数的前几个统计矩。 通常的近似是泰勒展开法。 这种方法需要计算导数。 为了避免导数的计算,已经提出了概率矩的点估计。 然而,准确度非常低,并且有时,...
eclipse 配置AmaterasUML时需要的3个jar 包,以及配置文档 http://blog.csdn.net/asce1885/article/details/40744163