qt5 win7下调用 pcsc smartcard winscard库 (记录)

qt5 win7下调用 pcsc smartcard winscard库

简单的参考代码:(需要有智能卡读卡器设备)
https://download.csdn.net/download/wowocpp/14920759
在这里插入图片描述

在这里插入图片描述

win32: LIBS += -lWinSCard

xxx.pro文件

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        PCSC.cpp \
        main.cpp
DEFINES += _UNICODE

win32: LIBS += -lWinSCard
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

HEADERS += \
    PCSC.h

main.cpp

#include <QCoreApplication>

#include "winscard.h"
#include <conio.h>
#include <iostream>
#include "PCSC.h"
#include <QDebug>

int main(int argc, char *argv[])
{
//    SCARDCONTEXT _context;

//    LONG lRetValue = SCardEstablishContext(SCARD_SCOPE_USER, nullptr, nullptr, &_context);

//    if ( SCARD_S_SUCCESS != lRetValue ){

//        std::cout << "Failed SCardEstablishContext\n";

//    }else{

//        std::cout << "Success SCardEstablishContext\n";
//    }

    CPCSC smartCardReader ;

    smartCardReader.ListCardReader();


    printf("Hello World AAAA\n");
    //std::cout << lRetValue;

    std::cout <<"Hello" ;

    std::cout <<SCARD_S_SUCCESS ;

    _getch();

    QCoreApplication a(argc, argv);

    qDebug()<< QString::fromStdWString(smartCardReader.ppReadersName[2]);
    smartCardReader.ConnectCard(smartCardReader.ppReadersName[2]);

#define HEX_BUF_LEN 100
    BYTE HexDataBuf[HEX_BUF_LEN] = {0x00,0x84,0x00,0x00,0x04};
    UINT i ;
    int iHexBufCnt =5 ;
    BYTE RecvData[HEX_BUF_LEN];
    DWORD dwRecvDataLen =HEX_BUF_LEN;
    BOOL bRet ;

    bRet = smartCardReader.TransimitCard(HexDataBuf,iHexBufCnt,RecvData,&dwRecvDataLen);

    if(bRet == TRUE){

        printf("\nRecv Data :\n");
        for(i=0;i < dwRecvDataLen;i++){

            printf("%.2x\n",RecvData[i]);
        }

    }

    return a.exec();
}

pcsc.cpp

#include <conio.h>
#include <iostream>
#include <string>
#include "PCSC.h"



#define log  printf

#define log_t printf


//用到的接口包括
//1.和卡建立连接 OpenCard
//2.关闭和卡的连接 CloseCard
//3.查询当前的PCSC读卡器都有哪些
//4.选择一个读卡器进行连接
//5.APDU发送数据到卡,并且将卡返回的数据原路返回给上层buffer
//6.最后加上接口,读读卡器列表
//7.自己维护一个读卡器列表
//8.需要单独的建立环境的函数

CPCSC::CPCSC(void)
{
	m_hContext	=	NULL;
	m_hCard		=	NULL;
	unReadersNum = 0 ;
	bIsConnected = FALSE ;
}



CPCSC::~CPCSC(void)
{
	DisConnectCard();
}



BOOL CPCSC::EstablishContext(void)
{
	LONG res; 

	if(m_hContext != NULL){
	
		return  TRUE;
	}

	res = ::SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&m_hContext);

	if(res != SCARD_S_SUCCESS){
	
		m_hContext = NULL ;

		return FALSE;
	}	

	log("Establish Context Success %d\n",2);

	return TRUE ;
}



BOOL CPCSC::ReleaseContext(void)
{
	LONG ret ;

	if(m_hContext != NULL){
		
		ret = ::SCardReleaseContext(m_hContext);

		if(SCARD_S_SUCCESS != ret){
		
			return FALSE ;
		}
	}

	return TRUE;
}




/*
 将当前系统中的,所有的PCSC读卡器名称列出来
 ppArrowReaders --- 二维数组
 ArrowRow	   --- 二维数组的列
 ArrowLine     --- 二位数组的行
*/

BOOL CPCSC::ListCardReader(void)
{
	LONG res ; // return value 

	LONG res2;

	BOOL ret = TRUE ; 
	
	DWORD   cch = SCARD_AUTOALLOCATE ;
	LPTSTR  pmszReaders = NULL ;
	LPTSTR  pReader = NULL;

	UINT len = 0 ;
	
	unReadersNum = 0 ;
	EstablishContext();

	res = SCardListReaders(m_hContext,
						   NULL,
						   (LPTSTR)&pmszReaders,
							&cch);

	switch(res){
	
	case SCARD_E_NO_READERS_AVAILABLE:
		//Reader is not in groups .
		unReadersNum = 0 ;
		ret  = FALSE ;
		break;

	case SCARD_S_SUCCESS:
		
		pReader = pmszReaders;

		while( '\0' != *pReader){

            printf("Reader: %S\n", pReader );
			if(unReadersNum >= CARD_READERS_NUM){
				unReadersNum = 0 ;
				ret = FALSE ;
				break ;
			}

            len = wcslen(pReader);
			 
			if(len >= CARD_READERS_NAME_LEN){
				unReadersNum = 0 ;
				ret = FALSE ;
				break ;
			}

            wcscpy(ppReadersName[unReadersNum],pReader);

            //wsprintf("pReader = %s\n",pmszReaders);
            //std::cout << pReader ;
            //wprintf("_tcslen(pReader = %d\n"),_tcslen(pReader));

			unReadersNum++ ;		
            pReader = pReader + wcslen(pReader)+1 ;

		}

        res2 = SCardFreeMemory( m_hContext,
                                   pmszReaders );

		if ( SCARD_S_SUCCESS != res2 ){
		
			ret = FALSE ;
			unReadersNum = 0 ;
		}

		break ;

	}

	return ret;
}
/*
打开指定名称的读卡器
*/

BOOL CPCSC::ConnectCard(LPCTSTR lpReader)
{
	LONG res ;
	BOOL ret ;

	
	if(bIsConnected == TRUE){
	
		return TRUE;
	}

	ret = EstablishContext();

	if(!ret){
	
		return FALSE ;
	}

    printf("lpReader = %ws\n",lpReader);


	res = SCardConnect(m_hContext,
						lpReader,
						SCARD_SHARE_EXCLUSIVE,
						SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1,
						&m_hCard,
						&m_dwActiveProtocol
						);



	if(SCARD_S_SUCCESS != res){
	
		m_hCard = NULL ;
		DisConnectCard();

		return FALSE ;
	}

	log("ScardConnect Success\n");

	bIsConnected = TRUE ;

	return TRUE;
}



void CPCSC::DisConnectCard(void)
{
	if(m_hCard)
	{
		::SCardDisconnect(m_hCard,SCARD_EJECT_CARD);
		m_hCard		=	0;
	}
	if(m_hContext)
	{
		::SCardReleaseContext(m_hContext);
		m_hContext	=	0;
	}

	bIsConnected = FALSE ;
}


/*
Get Response:0x00,0xC0 ,0x00,0x00,0x0F
不是线程安全的
这个先不考虑
*/

BOOL CPCSC::TransimitCard(LPCBYTE pbSendBuffer,DWORD cbSendLength,LPBYTE pbRecvBuffer,LPDWORD pcbRecvLength)
{
	LONG res ;

	LPCSCARD_IO_REQUEST  ioRequest ;

	if(bIsConnected == FALSE){
	
		return FALSE;
	}

	DWORD RecvLen = *pcbRecvLength ;

	switch(m_dwActiveProtocol){
			
	case SCARD_PROTOCOL_T0:
		ioRequest = SCARD_PCI_T0;
		break ;

	case SCARD_PROTOCOL_T1:
		ioRequest = SCARD_PCI_T1;
		break ;

	default :
		ioRequest = SCARD_PCI_T0 ;
		break ;
	}

	res = SCardTransmit(m_hCard,
				  ioRequest ,
				  pbSendBuffer,
				  cbSendLength,
				  NULL,
				  pbRecvBuffer,
				  pcbRecvLength
				);


	if(SCARD_S_SUCCESS != res){
	
		return FALSE ;
	}

	BYTE SW1,SW2;

	SW1 = pbRecvBuffer[*pcbRecvLength -2];
	SW2 = pbRecvBuffer[*pcbRecvLength -1];

	log("SW1=%.2x\n",SW1);
	log("SW2=%.2x\n",SW2);


	if(SW1 == 0x61){
	
		BYTE ucSendBuf[5] = {0x00,0xC0,0x00,0x00};
		ucSendBuf[4] = SW2;

		/*SCardTransmit 会修改pcbRecvLength的值*/

		*pcbRecvLength = RecvLen ;

		res = SCardTransmit(m_hCard,
					  ioRequest ,
					  ucSendBuf,
					  5,
					  NULL,
					  pbRecvBuffer,
					  pcbRecvLength
					);

		if(res != SCARD_S_SUCCESS){
			log("Fail\n");
			return FALSE ;
		}
		log("success\n");
	}

	return TRUE ;

}


	

在这里插入图片描述
按下回车,或者是随便一个按键
在这里插入图片描述

(仅供参考)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值