如何在没有卡的情况下控制智能卡读卡器? [英] How to control smart card readers without card on them?
问题描述
这些天我试图设计一个使用智能卡读卡器的软件,我使用的是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屋!