如何在没有卡的情况下控制智能卡读卡器? [英] How to control smart card readers without card on them?

查看:103
本文介绍了如何在没有卡的情况下控制智能卡读卡器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些天我试图设计一个使用智能卡读卡器的软件,我使用的是ACR1252u,我发现如果读卡器上有标签或卡片,我的智能卡读卡器会如何嗡嗡声。但仍然想知道如果没有读卡器上的卡,我怎么能这样做呢。卡片在读卡器上时的代码如下:



 retCode = Card.SCardConnect(hContext,readername,Card .SCARD_SHARE_SHARED,Card.SCARD_PROTOCOL_T0 | Card.SCARD_PROTOCOL_T1, ref  hCard, ref 协议); 

字节 [] setBuzzerOff = new 字节 [ 6 ];
setBuzzerOff [ 0 ] = 0xE0;
setBuzzerOff [ 1 ] = 0x00;
setBuzzerOff [ 2 ] = 0x00;
setBuzzerOff [ 3 ] = 0x28;
setBuzzerOff [ 4 ] = 0x01;
setBuzzerOff [ 5 ] = 0x00;
UInt32 controlcode = 3500 ;
int pcBytesReturned = 0 ;
字节 [] RecieveBuff = new 字节 [ 1 ];
int status = Card.SCardControl(hCard,controlcode, ref setBuzzerOff [ 0 ], 6 ref RecieveBuff [ 0 ],RecieveBuff.Length, ref pcBytesReturned);
MessageBox.Show(status.ToString());



问题是当读卡器上的hcard状态是错误显示6.这意味着错误处理!但是,如果卡片在阅读器上方,为什么嗡嗡作响的读者呢?无论如何要转过来?因为此后我想打开LED,而卡片没有超过读卡器 - 如果有人解决了这个问题,请告诉我们。



我是什么尝试过:



我已经浏览了http://the--semicolon.blogspot.it/p/this-is-simple-way -to-restart-your.html



这里也说过可以使用SCardControl访问没有卡的读卡器。



http://pvbookmarks.readthedocs.io/en/latest/devel/drivers/usb/classes/ccid/pc_sc/pcsc_tools/proprietary/commands.html

解决方案

我在c ++代码中找到了解决方案:

仅在链接器中我们需要添加winscard.h



  #include   < ;   iostream  >  
#include < iomanip >
#include < vector >
#include < 字符串 >
#include < cstdint >
#include < cstring >
#include < winscard.h >

std :: wstring s2ws( const std :: string&或多个);

int main( int argc, char * argv []){
SCARDCONTEXT context = 0 ;
LONG ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, nullptr nullptr ,& context);

if (ret!= SCARD_S_SUCCESS){
std :: cout<< SCardEstablishContext:<< RET<<的std :: ENDL;
}
else {
LPTSTR allReaderNames = nullptr ;
DWORD readerCount = SCARD_AUTOALLOCATE;

ret = SCardListReaders(context, nullptr ,reinterpret_cast< LPTSTR>(& allReaderNames),& readerCount);

if (ret!= SCARD_S_SUCCESS){
std :: cout<< SCardListReaders:<< ret<<的std :: ENDL;
}
else {
std :: string readerName( ACS ACR1252 1S CL Reader PICC 0);
std :: wstring stemp = s2ws(readerName);
LPCWSTR result = stemp.c_str();
DWORD activeProtocol = 0 ;
SCARDHANDLE卡= 0 ;

ret = SCardConnect(上下文,结果,SCARD_SHARE_DIRECT, 0 ,& card,& activeProtocol);

if (ret!= SCARD_S_SUCCESS){
std :: cout<< SCardConnect:<< ret<<的std :: ENDL;
}
else {
std :: vector< std :: uint8_t> outputBuffer {0xE0,0x0,0x0,0x21,0x01,0x71};
std :: vector< std :: uint8_t> inputBuffer( 64 0 );
DWORD bytesReturned = 0 ;

DWORD controlcode = SCARD_CTL_CODE( 3500 );
ret = SCardControl(card,controlcode,outputBuffer.data(),outputBuffer.size(),inputBuffer.data(),inputBuffer.size(),& bytesReturned);

if (ret!= SCARD_S_SUCCESS){
std :: cout<< SCardControl:<< ret<<的std :: ENDL;
}
else {
std :: cout<< 响应:<< std :: hex<< std :: setfill(' 0');
for (std :: size_t i = 0 ; i< bytesReturned; ++ i){
std :: cout<< std :: setw( 2 )<< static_cast< std :: uint32_t>(inputBuffer [i])<< ;
}
std :: cout<< std :: dec<<的std :: ENDL;

SCardDisconnect(card,SCARD_LEAVE_CARD);
}
}

// 释放SCardListReaders分配的内存对我们来说
SCardFreeMemory(context,allReaderNames);
}

ret = SCardReleaseContext(context);

if (ret!= SCARD_S_SUCCESS){
std :: cout<< SCardReleaseContext:<< ret<<的std :: ENDL;
}
std :: getchar();
}

return 0 ;
}


std :: wstring s2ws( const std :: string& s)
{
int len;
int slength =( int )s.length()+ 1 ;
len = MultiByteToWideChar(CP_ACP, 0 ,s.c_str(),slength, 0 0 );
wchar_t * buf = new wchar_t [长度];
MultiByteToWideChar(CP_ACP, 0 ,s.c_str(),slength,buf,len);
std :: wstring r(buf);
delete [] buf;
return r;
}





和c#代码将是这样的



 retCode = Card.SCardEstablishContext(Card.SCARD_SCOPE_SYSTEM, 0  0  ref  hContext); 
if (retCode!= Card.SCARD_S_SUCCESS)
{
MessageBox.Show( 检查您的设备,请重新启动 Reader not connected,MessageBoxButtons.OK,MessageBoxIcon.Warning);
connActive = false ;
return ;
}
retCode = Card.SCardConnect(hContext,readername, 3 0 ref hCard, ref 协议);
if (retCode!= Card.SCARD_S_SUCCESS)
{
MessageBox.Show( 错误: + retCode.ToString());
}
字节 [] setRFOff = new 字节 [ 6 ];
setRFOff [ 0 ] = 0xE0;
setRFOff [ 1 ] = 0x00;
setRFOff [ 2 ] = 0x00;
setRFOff [ 3 ] = 0x21;
setRFOff [ 4 ] = 0x01;
setRFOff [ 5 ] = 0x71;
uint pcBytesReturned = 0 ;
字节 [] RecieveBuff = new 字节 [ 64 ];
uint controlcode = 3225264 ;
uint pCard = hCard;
int status = Card.SCardControl(hCard,controlcode, ref setRFOff [ 0 ], 6 ref RecieveBuff [ 0 ],RecieveBuff.Length, ref pcBytesReturned);
if (status!= Card.SCARD_S_SUCCESS)
{
MessageBox.Show( 错误: + status.ToString());
}
status = Card.SCardDisconnect(pCard,Card.SCARD_RESET_CARD);
if (status!= Card.SCARD_S_SUCCESS)
{
MessageBox.Show( 错误: + status.ToString());
}
rtbStatus.Text = success;


Well these days Im trying to design a software which use smart card readers, I am using ACR1252u and I have discovered how to buzz my smart card reader if a tag or card is on the reader. but still wondering how can I do this without the card on the reader. the code which works for when the card is on the reader is below:

retCode = Card.SCardConnect(hContext, readername, Card.SCARD_SHARE_SHARED, Card.SCARD_PROTOCOL_T0 | Card.SCARD_PROTOCOL_T1, ref hCard, ref Protocol);

           Byte[] setBuzzerOff = new Byte[6];
           setBuzzerOff[0] = 0xE0;
           setBuzzerOff[1] = 0x00;
           setBuzzerOff[2] = 0x00;
           setBuzzerOff[3] = 0x28;
           setBuzzerOff[4] = 0x01;
           setBuzzerOff[5] = 0x00;
           UInt32 controlcode = 3500;
           int pcBytesReturned = 0;
           Byte[] RecieveBuff = new Byte[1];
           int status=Card.SCardControl(hCard, controlcode,ref setBuzzerOff[0],6,ref RecieveBuff[0], RecieveBuff.Length,ref pcBytesReturned);
           MessageBox.Show(status.ToString());


The problem is when hcard is on the reader the status which is the error shows 6. which means wrong handle!. But why buzzing a reader is connected to if the card is over the reader? is there anyway to turn this over? cause after this I want to turn on LEDs while the card is not over the reader- Guys plz if anyone have solved this problem tell us.

What I have tried:

I have gone through the http://the--semicolon.blogspot.it/p/this-is-simple-way-to-restart-your.html

and also its been said here that it is possible to use SCardControl for accessing reader without card available.

http://pvbookmarks.readthedocs.io/en/latest/devel/drivers/usb/classes/ccid/pc_sc/pcsc_tools/proprietary/commands.html

解决方案

I have found the solution in a c++ code:
only in the linker we need to add winscard.h

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <cstdint>
#include <cstring>
#include <winscard.h>

std::wstring s2ws(const std::string& s);

int main(int argc, char* argv[]) {
	SCARDCONTEXT context = 0;
	LONG ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, nullptr, nullptr, &context);

	if (ret != SCARD_S_SUCCESS) {
		std::cout << "SCardEstablishContext: " << ret<< std::endl;
	}
	else {
		LPTSTR allReaderNames = nullptr;
		DWORD readerCount = SCARD_AUTOALLOCATE;

		ret = SCardListReaders(context, nullptr, reinterpret_cast<LPTSTR>(&allReaderNames), &readerCount);

		if (ret != SCARD_S_SUCCESS) {
			std::cout << "SCardListReaders: " << ret << std::endl;
		}
		else {
			std::string readerName("ACS ACR1252 1S CL Reader PICC 0");
			std::wstring stemp = s2ws(readerName);
			LPCWSTR result = stemp.c_str();
			DWORD activeProtocol = 0;
			SCARDHANDLE card = 0;

			ret = SCardConnect(context, result, SCARD_SHARE_DIRECT, 0, &card, &activeProtocol);

			if (ret != SCARD_S_SUCCESS) {
				std::cout << "SCardConnect: " << ret << std::endl;
			}
			else {
				std::vector<std::uint8_t> outputBuffer{ 0xE0, 0x0, 0x0, 0x21, 0x01, 0x71 };
				std::vector<std::uint8_t> inputBuffer(64, 0);
				DWORD bytesReturned = 0;

				DWORD controlcode = SCARD_CTL_CODE(3500);
				ret = SCardControl(card, controlcode, outputBuffer.data(), outputBuffer.size(), inputBuffer.data(), inputBuffer.size(), &bytesReturned);

				if (ret != SCARD_S_SUCCESS) {
					std::cout << "SCardControl: " << ret << std::endl;
				}
				else {
					std::cout << "Response: " << std::hex << std::setfill('0');
					for (std::size_t i = 0; i < bytesReturned; ++i) {
						std::cout << std::setw(2) << static_cast<std::uint32_t>(inputBuffer[i]) << " ";
					}
					std::cout << std::dec << std::endl;

					SCardDisconnect(card, SCARD_LEAVE_CARD);
				}
			}

			// Release the memory that SCardListReaders allocated for us
			SCardFreeMemory(context, allReaderNames);
		}

		ret = SCardReleaseContext(context);

		if (ret != SCARD_S_SUCCESS) {
			std::cout << "SCardReleaseContext: " << ret << std::endl;
		}
		std::getchar();
	}

	return 0;
}


std::wstring s2ws(const std::string& s)
{
	int len;
	int slength = (int)s.length() + 1;
	len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
	wchar_t* buf = new wchar_t[len];
	MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
	std::wstring r(buf);
	delete[] buf;
	return r;
}



and the c# code will be like this

retCode = Card.SCardEstablishContext(Card.SCARD_SCOPE_SYSTEM, 0, 0, ref hContext);
            if (retCode != Card.SCARD_S_SUCCESS)
            {
                MessageBox.Show("Check your device and please restart again", "Reader not connected", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                connActive = false;
                return;
            }
            retCode = Card.SCardConnect(hContext, readername, 3, 0, ref hCard, ref Protocol);
            if (retCode != Card.SCARD_S_SUCCESS)
            {
                MessageBox.Show("Error: " + retCode.ToString());
            }
            Byte[] setRFOff = new Byte[6];
            setRFOff[0] = 0xE0;
            setRFOff[1] = 0x00;
            setRFOff[2] = 0x00;
            setRFOff[3] = 0x21;
            setRFOff[4] = 0x01;
            setRFOff[5] = 0x71;
            uint pcBytesReturned = 0;
            Byte[] RecieveBuff = new Byte[64];
            uint controlcode = 3225264;
            uint pCard = hCard;
            int status = Card.SCardControl(hCard, controlcode, ref setRFOff[0], 6, ref RecieveBuff[0], RecieveBuff.Length, ref pcBytesReturned);
            if (status != Card.SCARD_S_SUCCESS)
            {
                MessageBox.Show("Error: " + status.ToString());
            }
            status = Card.SCardDisconnect(pCard, Card.SCARD_RESET_CARD);
            if (status != Card.SCARD_S_SUCCESS)
            {
                MessageBox.Show("Error: " + status.ToString());
            }
            rtbStatus.Text = "success";


这篇关于如何在没有卡的情况下控制智能卡读卡器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆