⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcscreader.cpp

📁 开发源代码的CPU卡的COS源程序。
💻 CPP
字号:
/* ============================================================================   Project Name : jayaCard   Module Name  : inkit - PCSCReader.cpp   Version      : $Id: PCSCReader.cpp,v 1.9 2003/11/13 18:11:32 pfremy Exp $	Description:    The Original Code is inKit code, the contactless library of the jayacard    project (http://www.jayacard.org).    The contents of this file are subject to the Mozilla Public License Version    1.1 (the "License"); you may not use this file except in compliance with    the License. You may obtain a copy of the License at    http://www.mozilla.org/MPL/    Software distributed under the License is distributed on an "AS IS" basis,    WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License    for the specific language governing rights and limitations under the    License.    The Initial Developer of the Original Code is inSeal SAS and the authors    Gilles Dumortier and Philippe Fremy.    Portions created by the Initial Developer are Copyright (C) 1996-2003 the    Initial Developer. All Rights Reserved.    Alternatively, the contents of this file may be used under the terms of    either the GNU General Public License Version 2 or later (the "GPL"), or    the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),    in which case the provisions of the GPL or the LGPL are applicable instead    of those above. If you wish to allow use of your version of this file only    under the terms of either the GPL or the LGPL, and not to allow others to    use your version of this file under the terms of the MPL, indicate your    decision by deleting the provisions above and replace them with the notice    and other provisions required by the GPL or the LGPL. If you do not delete    the provisions above, a recipient may use your version of this file under    the terms of any one of the MPL, the GPL or the LGPL.    inKit is also available under commercial license. For pricing and ordering    information, send an email to sales@inseal.com   History Rev	Description   060803  phf	wrote it from scratch   ============================================================================*//* ========================================================================= */#include <string>#include <sstream>#include "inkit/jaya_reader/PCSCReader/PCSCReader.h"#include <winscard.h>#ifndef WIN32#include <pcsclite.h>#endifnamespace Jayacard {void * PCSCReader::operator new( size_t tSize ){	return malloc( tSize );}void PCSCReader::operator delete( void *p ){	free(p);}/* =========================================================================	PCSCReader - constructor	On construction, the class connects to the reader and retrieves the     serial number, to validate the reader's presence.   ========================================================================= */PCSCReader::PCSCReader( string type, string configString, jresult * result )     : JayaReader( type, configString, result ){    LONG rv;    // *** need to handle / parse configString    // establish a connection context to the PC/SC ressource manager    rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM, NULL, NULL, &_hContext );    if ( rv != SCARD_S_SUCCESS )     {        *result = convertPCSCError( rv );         jlog( "PCSCReader", "Error when establishing PC/SC context" );        return;     }    // test the availability of the reader    SCARD_READERSTATE rgReaderState;    rgReaderState.szReader = (LPCSTR)strdup( _type.c_str() );    rgReaderState.dwCurrentState = SCARD_STATE_UNAWARE;     rv = SCardGetStatusChange( _hContext, 0, &rgReaderState, 1 );    if ( rv != SCARD_S_SUCCESS )     {        *result = convertPCSCError( rv );         jlog( "PCSCReader",               "Error when checking for status of reader '%s'", _type.c_str() );    }    else if ( rgReaderState.dwEventState & SCARD_STATE_IGNORE              || rgReaderState.dwEventState & SCARD_STATE_UNKNOWN              || rgReaderState.dwEventState & SCARD_STATE_UNAVAILABLE )     {        *result = convertPCSCError( rv );         jlog( "PCSCReader", "Error - reader '%s' is unavailable", _type.c_str() );    }    // various initializations    _hCard = NULL;    _dwActiveProtocol = SCARD_PROTOCOL_UNDEFINED;}/* =========================================================================	~PCSCReader - destructor   ========================================================================= */PCSCReader::~PCSCReader(){    LONG rv;    // release the connection context    rv = SCardReleaseContext( _hContext );    if ( rv != SCARD_S_SUCCESS )        jlog( "PCSCReader", "Error when releasing PC/SC context" );}/* =========================================================================	powerOn	Powers on the card. Most readers automatically power on the card but     some do not [powerOn should always succeed (when a card is in)].    ========================================================================= */jresult PCSCReader::powerOn( Apdu & atr ){    LONG rv;    _lastResult = JY_OK;        if ( _isPowered == false )    {        // connect to the reader (and power up the card)          // *** pass the reader name elsewhere than in _type?         rv = SCardConnect( _hContext, (LPCSTR)_type.c_str(),                            SCARD_SHARE_EXCLUSIVE,                            SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,                            &_hCard, &_dwActiveProtocol );        if ( rv != SCARD_S_SUCCESS )        {            _isPowered = false;            _lastResult = convertPCSCError( rv );             jlog( "PCSCReader",                   "Error when connecting to the reader '%s'", _type.c_str() );            return _lastResult;        }        // the card is now powered on        _isPowered = true;    }    else    {        // card already connected, we do a warm reset        rv = SCardReconnect( _hCard, SCARD_SHARE_EXCLUSIVE,                              SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,                              SCARD_RESET_CARD, &_dwActiveProtocol ); // *** or cold reset        if ( rv != SCARD_S_SUCCESS )        {            _isPowered = false;            _lastResult = convertPCSCError( rv );             jlog( "PCSCReader",                   "Error when reconnecting the reader '%s'", _type.c_str() );             return _lastResult;        }    }      // get the ATR of the card    DWORD dwReaderLen;     DWORD dwState;    DWORD dwProtocol;     BYTE pbAtr[33]; // *** check if size is ok    DWORD dwAtrLen;        rv = SCardStatus( _hCard, NULL, &dwReaderLen,                       &dwState, &dwProtocol, pbAtr, &dwAtrLen );     if ( rv != SCARD_S_SUCCESS )     {        _isPowered = false;         _lastResult = convertPCSCError( rv );         jlog( "PCSCReader", "Error when retrieving the card ATR" );    }    else if ( dwState == SCARD_ABSENT              || dwState == SCARD_SWALLOWED              || dwState == SCARD_POWERED ) // see winsmcrd.h, not OR'ed values    {        _isPowered = false;        _lastResult = JY_NOT_POWERED;        jlog( "PCSCReader", "Error when retrieving the card ATR" );    }    atr.set( (jbyte*)pbAtr, dwAtrLen ); // *** efficient enough?	return _lastResult;}/* =========================================================================	powerOff	Powers off the card.    ========================================================================= */jresult PCSCReader::_powerOff(){    LONG rv;    _lastResult = JY_OK;	if (_hCard != NULL) {		// disconnect from the reader		rv = SCardDisconnect( _hCard, SCARD_UNPOWER_CARD );  // *** or eject?		if ( rv != SCARD_S_SUCCESS )		{			_lastResult = convertPCSCError( rv ); 			jlog( "PCSCReader", 				  "Error when disconnecting from the reader '%s'", _type.c_str() );		}	}    _hCard = NULL;    _isPowered = false;	return _lastResult;}/* =========================================================================	isCardPresent	Test if card is present.    ========================================================================= */jresult	PCSCReader::isCardPresent( bool & cardPresent ){    LONG rv;    cardPresent = false;	_lastResult = JY_OK;    // test if the card is present in the reader    SCARD_READERSTATE rgReaderState;    rgReaderState.szReader = (LPCSTR)strdup( _type.c_str() );    rgReaderState.dwCurrentState = SCARD_STATE_UNAWARE;     rv = SCardGetStatusChange( _hContext, 0, &rgReaderState, 1 );    if ( rv != SCARD_S_SUCCESS )     {        _lastResult = convertPCSCError( rv );         jlog( "PCSCReader",               "Error when checking for card presence in reader '%s'", _type.c_str() );    }    else if ( rgReaderState.dwEventState & SCARD_STATE_PRESENT )        cardPresent = true;	return _lastResult;}/* =========================================================================	internalExchangeApdu [internal]	Exchange Apdu with the card.   ========================================================================= */jresult PCSCReader::internalExchangeApdu( jbyte * command, int commandLen, 					   jbyte * response, int * responseLen ){    LONG rv;     LPCSCARD_IO_REQUEST pioSendPci;	_lastResult = JY_OK;    // point the right i/o request structure depending on the protocol    if ( _dwActiveProtocol == SCARD_PROTOCOL_T0 )        pioSendPci = SCARD_PCI_T0;    else if ( _dwActiveProtocol == SCARD_PROTOCOL_T1 )        pioSendPci = SCARD_PCI_T1;    else        return _lastResult = JY_UNSUPPORTED_MODE;     // exchange the Apdu with the card    rv = SCardTransmit( _hCard, pioSendPci,                         (LPCBYTE)command, (DWORD)commandLen,                         NULL,                         (LPBYTE)response, (LPDWORD)responseLen );     // need to try a reconnect? (or shared mode, card reset only)    if ( rv != SCARD_S_SUCCESS )    {        _lastResult = convertPCSCError( rv );         jlog( "PCSCReader",               "Error exchanging APDU on reader '%s'", _type.c_str() );     }	return _lastResult;}/* =========================================================================	getSerialNumber	Serial number or identifier of the reader. In case of error, a null     string is returned and lastResult is set.    ========================================================================= */jresult PCSCReader::getSerialNumber( string & serialNumber ){#ifdef WIN32    LONG rv;     BYTE * pbAttr;     DWORD dwAttrLen; 	_lastResult = JY_OK;    // we need a hCard to call SCardGetAttrib, but we're not necessarily     // connected, and if we try to connect without a card inserted,     // SCardConnect won't return a valid hCard anyway.     //     // SO, for the moment, we only try to return the serial if connected    // to a reader and card    if ( _hCard != NULL )    {        // ask for the buffer size needed for the serial        rv = SCardGetAttrib( _hCard,                              // SCARD_ATTR_VENDOR_IFD_VERSION                             SCARD_ATTR_VENDOR_IFD_SERIAL_NO,                              NULL, &dwAttrLen );        if ( rv != SCARD_S_SUCCESS )        {            _lastResult = convertPCSCError( rv );             jlog( "PCSCReader",                   "Error getting the serial number of reader '%s'",                   _type.c_str() );             return _lastResult;        }        // allocate the buffer        pbAttr = (BYTE *) malloc( dwAttrLen*sizeof(BYTE) );        if ( pbAttr == NULL )        {            _lastResult = JY_ALLOCATION_FAILURE;             jlog( "PCSCReader", "Error when allocation memory for "                  "the serial number of reader '%s'", _type.c_str() );             return _lastResult;        }        // ask for the serial number        rv = SCardGetAttrib( _hCard, SCARD_ATTR_VENDOR_IFD_SERIAL_NO,                              pbAttr, &dwAttrLen );        if ( rv != SCARD_S_SUCCESS )        {            _lastResult = convertPCSCError( rv );             jlog( "PCSCReader",                   "Error getting the serial number of reader '%s'",                   _type.c_str() );             return _lastResult;        }        // convert the serial into a string        ostringstream buf;        for (int i=0 ; i<dwAttrLen ; i++ )             buf << pbAttr[i];                       serialNumber = buf.str();    }    else    {        serialNumber = "NoSerial";	    _lastResult = JY_OK;    }	return _lastResult;#else // unix    // *** Need to be implemented, return "NoSerial" for the moment	serialNumber = "NoSerial";	_lastResult = JY_OK;	return _lastResult;#endif // WIN32}/* =========================================================================	_extraCommand [internal]	Allow to pass custom commands to reader.    ========================================================================= */string PCSCReader::_extraCommand( string cmd, string arg ){	return "";}/* =========================================================================	convertPCSCError [internal]	Allow to pass custom commands to reader.    ========================================================================= */jresult PCSCReader::convertPCSCError( LONG rv ){    switch ( rv )    {        case SCARD_S_SUCCESS:             return JY_SUCCESS;        // invalid scope, hContext, hCard or disposition        // (SCardEstablishContext, SCardConnect, SCardReconnect, SCardDisconnect,         //  SCardTransmit, SCardStatus, SCardGetStatusChange)        case SCARD_E_INVALID_VALUE:        case SCARD_E_INVALID_HANDLE:            return JY_BAD_ARGUMENT;        // no card inserted when connecting        // (SCardConnect)        case SCARD_E_NO_SMARTCARD:             return JY_FAILED;  // *** create a new jaya_error        // could not power up the reader or card        // (SCardConnect, SCardReconnect)        case SCARD_E_READER_UNAVAILABLE:         case SCARD_E_NOT_READY: // *** not sure about this one             return JY_NOT_POWERED; // *** create a new jaya_error?        // protocol not supported        // (SCardConnect, SCardReconnect)//        case SCARD_E_UNSUPPORTED_FEATURE: //            return JY_UNSUPPORTED_MODE; // *** or JY_PROTOCOL_ERROR ?        // APDU exchange not successful         // (SCardTransmit)         case SCARD_E_NOT_TRANSACTED:             return JY_FAILED;  // *** create a new jaya_error        // connect protocol is different than desired        // (SCardTransmit)        case SCARD_E_PROTO_MISMATCH:             return JY_PROTOCOL_ERROR;        case SCARD_E_INSUFFICIENT_BUFFER:  // should not happen            return JY_BUFFER_TOO_SMALL;        case SCARD_F_UNKNOWN_ERROR:        case SCARD_F_INTERNAL_ERROR:        case SCARD_E_SHARING_VIOLATION:    // should not happen         case SCARD_W_RESET_CARD:           //            return JY_UNEXPECTED;        default:            return JY_FAILED;    }}/* ========================================================================= */} /* namespace Jayacard */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -