// Max. APDU Buffer length. void SmartCardReader::setup( string _readerName ) { ofLogNotice( "Initializing SmartCard reader with name" ) << _readerName ; readerLabel = _readerName ; int len = 64 ; //Establish Context retCode = SCardEstablishContext( SCARD_SCOPE_USER, NULL, NULL, &context ); if( retCode != SCARD_S_SUCCESS ) { ofLogError( "SmartCardReader::setup() FAILED TO ESTABLISH CONTEXT" ) << getSCardErrorMessage( retCode ) ; return ; } else { ofLogNotice( "Context established successfully." ) ; } listAllReaders( ) ; connect( ) ; }
QPCSC::QPCSC( QObject *parent ) : QObject( parent ) , d( new QPCSCPrivate ) { DWORD err = SCardEstablishContext( SCARD_SCOPE_USER, 0, 0, &d->context ); d->running = err != SCARD_E_NO_SERVICE; }
/* then they will all use the same context and avoid overhead */ int readersManagerConnect( tReaderManager *pManager ) { LONG rv; if ( pManager == NULL ) return( SCARD_E_INVALID_PARAMETER ); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, (LPSCARDCONTEXT)&(pManager->hContext) ); if (rv != SCARD_S_SUCCESS) { PCSC_ERROR( pManager, rv, "SCardEstablishContext"); pManager->hContext = NULL; eventDispatch( PCSCD_FAIL, NULL, 0, pManager ); return( rv ); } eventDispatch( PCSCD_CONNECT, NULL, 0, pManager ); /* Find all the readers and fill the readerManager data structure */ rv = readersEnumerate( pManager ); return (rv); }
static UINT32 handle_EstablishContext(IRP* irp) { UINT32 len; UINT32 status; UINT32 scope; SCARDCONTEXT hContext = -1; stream_seek(irp->input, 8); stream_read_UINT32(irp->input, len); if (len != 8) return SCARD_F_INTERNAL_ERROR; stream_seek_UINT32(irp->input); stream_read_UINT32(irp->input, scope); status = SCardEstablishContext(scope, NULL, NULL, &hContext); stream_write_UINT32(irp->output, 4); // cbContext stream_write_UINT32(irp->output, -1); // ReferentID stream_write_UINT32(irp->output, 4); stream_write_UINT32(irp->output, hContext); /* TODO: store hContext in allowed context list */ smartcard_output_alignment(irp, 8); return SCARD_S_SUCCESS; }
/* -------------------------------------------------------------------------- */ LONG sc_init_u (sc_context *ctx, char *rdr) /* *rdr must be a full name */ { SCARD_READERSTATE rSt = {0}; LONG rc=SCARD_S_SUCCESS; DWORD dw=SCARD_AUTOALLOCATE; rc=SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &ctx->hCtx); if (rc == SCARD_S_SUCCESS) { rSt.szReader = rdr; rSt.dwCurrentState = SCARD_STATE_UNAWARE; rc = SCardGetStatusChange(ctx->hCtx, 0, &rSt, 1); if ( (rSt.dwEventState & SCARD_STATE_EMPTY) > 0 ) rc = SC_BAD; else { ctx->rdr = NULL; ctx->rdrsz = SCARD_AUTOALLOCATE; ctx->CLA = 0; ctx->proto = SCARD_PCI_T0; ctx->rw = 0; rc = SCardConnect(ctx->hCtx, rdr, SCARD_SHARE_SHARED, SCARD_MYPROTOSET, &ctx->hCard, &dw); if (rc == SCARD_S_SUCCESS) { SCardGetAttrib(ctx->hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (LPBYTE)&ctx->rdr, &ctx->rdrsz); if (dw == SCARD_PROTOCOL_T1) ctx->proto = SCARD_PCI_T1; else if (dw == SCARD_PROTOCOL_RAW) ctx->proto = SCARD_PCI_RAW; } } if ( rc != SCARD_S_SUCCESS) SCardReleaseContext(ctx->hCtx); } return rc; } /* sc_init */
PCSC::PCSC( std::string& a_stReaderName ) { m_hContextPCSC = 0; m_hCardPCSC = 0; m_bDoTransact = true; LONG lReturn = SCardEstablishContext( 0, NULL, NULL, &m_hContextPCSC ); if( SCARD_S_SUCCESS != lReturn ) { Log::log( "PCSC::PCSC - SCardEstablishContext <%#02x>", lReturn ); throw RemotingException( "PCSC::PCSC - SCardEstablishContext error", lReturn ); } DWORD dwActiveProtocol = SCARD_PROTOCOL_T0; lReturn = SCardConnect( m_hContextPCSC, (LPTSTR)a_stReaderName.c_str( ), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &m_hCardPCSC, &dwActiveProtocol ); if( SCARD_S_SUCCESS != lReturn ) { Log::log( "PCSC::PCSC - SCardConnect <%#02x>", lReturn ); throw RemotingException( (lpCharPtr)"PCSC: SCardConnect error", lReturn ); } m_stReaderName = a_stReaderName; }
static int pcsc_initialize(cardreader_t *reader) { pcsc_data_t* pcsc = malloc(sizeof(pcsc_data_t)); memset(pcsc,0,sizeof(pcsc_data_t)); pcsc->status = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &(pcsc->hcontext)); if (pcsc->status!=SCARD_S_SUCCESS) { log_printf(LOG_ERROR,"Failed to establish PCSC card manager context: %s (error 0x%08x).", pcsc_stringify_error(pcsc->status), pcsc->status ); return 0; } reader->extra_data = pcsc; reader->connect = pcsc_connect; reader->disconnect = pcsc_disconnect; reader->reset = pcsc_reset; reader->transmit = pcsc_transmit; reader->last_atr = pcsc_last_atr; reader->get_info = pcsc_get_info; reader->fail = pcsc_fail; reader->finalize = pcsc_finalize; return 1; }
int main(void) { SCARDCONTEXT hContext; SCARDHANDLE hCard; DWORD dwActiveProtocol; LONG rv; char mszReaders[1024]; DWORD dwReaders = sizeof(mszReaders); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); printf("%lX\n", rv); rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders); printf("%lX\n", rv); rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); printf("%lX\n", rv); printf("remove/insert card\n"); sleep(3); rv = SCardBeginTransaction(hCard); printf("%lX\n", rv); return 0; }
static UINT32 smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, EstablishContext_Call* call) { UINT32 status; SCARDCONTEXT hContext = -1; EstablishContext_Return ret; IRP* irp = operation->irp; status = ret.ReturnCode = SCardEstablishContext(call->dwScope, NULL, NULL, &hContext); if (ret.ReturnCode == SCARD_S_SUCCESS) { SMARTCARD_CONTEXT* pContext; void* key = (void*) (size_t) hContext; pContext = smartcard_context_new(smartcard, hContext); ListDictionary_Add(smartcard->rgSCardContextList, key, (void*) pContext); } smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext); smartcard_trace_establish_context_return(smartcard, &ret); status = smartcard_pack_establish_context_return(smartcard, irp->output, &ret); if (status) return status; return ret.ReturnCode; }
int CPCSCMngr::GetAvailableReaders(char* pReaders, DWORD *pReadersLen) { int status = STAT_OK; LONG retStat = SCARD_S_SUCCESS; SCARDCONTEXT sc; DWORD len = SCARD_AUTOALLOCATE; char* readers = NULL; if ((retStat = SCardEstablishContext(SCARD_SCOPE_USER,0,0,&sc)) == SCARD_S_SUCCESS) { if ((retStat = SCardListReaders(sc, NULL, (char *)&readers, &len)) == SCARD_S_SUCCESS) { // OK, READERS OBTAINED if (*pReadersLen >= len) { memcpy(pReaders, readers, len); } else { // NOT ENOUGHT MEMORY *pReadersLen = len; status = STAT_DATA_INCORRECT_LENGTH; } SCardFreeMemory(sc, readers); } else { m_lastSCardError = retStat; status = STAT_VALUE_NOT_READ; } } SCardReleaseContext(sc); if (retStat != SCARD_S_SUCCESS) status = STAT_SCARD_ERROR; return status; }
/* * Establish context. */ JNIEXPORT jint JNICALL GEN_FUNCNAME(Context_NativeEstablishContext) (JNIEnv *env, jobject _this, jint dwScope, jstring pvReserved1, jstring pvReserved2) { int rv; SCARDCONTEXT ctx; char const *pv1, *pv2; jboolean b; pv1 = (pvReserved1 == NULL) ? NULL : (*env)->GetStringUTFChars(env, pvReserved1, &b); pv2 = (pvReserved2 == NULL) ? NULL : (*env)->GetStringUTFChars(env, pvReserved2, &b); rv = SCardEstablishContext(dwScope, pv1, pv2, &ctx); if (pv1 != NULL) { (*env)->ReleaseStringUTFChars(env, pvReserved1, pv1); } if (pv2 != NULL) { (*env)->ReleaseStringUTFChars(env, pvReserved2, pv2); } if (rv == SCARD_S_SUCCESS) { (*env)->SetLongField(env, _this, CtxField, (jlong) ctx); } return rv; }
static uint32 handle_EstablishContext(IRP* irp) { uint32 len, rv; uint32 scope; SCARDCONTEXT hContext = -1; stream_seek(irp->input, 8); stream_read_uint32(irp->input, len); if (len != 8) return SCARD_F_INTERNAL_ERROR; stream_seek_uint32(irp->input); stream_read_uint32(irp->input, scope); rv = SCardEstablishContext(scope, NULL, NULL, &hContext); stream_write_uint32(irp->output, 4); // ? stream_write_uint32(irp->output, -1); // ? stream_write_uint32(irp->output, 4); stream_write_uint32(irp->output, hContext); /* TODO: store hContext in allowed context list */ return SCARD_S_SUCCESS; }
/* ------------------------------------------------------------------------- */ char *sc_listreaders(void) { SCARDCONTEXT hCtx = {0}; LONG rc = SCARD_S_SUCCESS; DWORD dw = SCARD_AUTOALLOCATE; LPTSTR c = NULL; char *cc = NULL; rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hCtx); if (rc == SCARD_S_SUCCESS) { rc = SCardListReaders(hCtx, NULL, (LPTSTR) &c, &dw); if (rc == SCARD_S_SUCCESS) { cc = (char *) malloc(dw); if (cc != NULL) { cc[--dw]=0; cc[--dw]=0; while (dw--) cc[dw] = (char)((c[dw])?c[dw]:0x0A); } SCardFreeMemory(hCtx, c); } SCardReleaseContext(hCtx); } return cc; } /* sc_listreaders */
//PCSCREADERDLL_API LONG CCONV PCSC_GetReaderList(HANDLE ContextNo, int * ReaderCount, char ResponseBuffer[MAX_READER_NAME]) PCSCREADERDLL_API LONG CCONV PCSC_GetReaderList(int * ReaderCount, char ResponseBuffer[MAX_READER_NAME]) { unsigned long ResponseLength; int j, StringLen; unsigned char ReaderNameTmp[MAX_READER_NAME]; ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ContextHandle); if (ret != SCARD_S_SUCCESS) { return ret; } //The SCardListCards function searches the smart card database //and provides a list of named cards previously introduced to the system by the user. // //The caller specifies an ATR string, a set of interface identifiers (GUIDs), or both. //If both an ATR string and an identifier array are supplied, the cards returned //will match the ATR string supplied and support the interfaces specified. ret = SCardListReaders(ContextHandle, NULL, NULL, &ResponseLength); if (ret != SCARD_S_SUCCESS) { return ret; } ret = SCardListReaders(ContextHandle, NULL, (char *)ResponseBuffer, &ResponseLength); if (ret != SCARD_S_SUCCESS) { return ret; } j=0; // ReaderID = 0; StringLen = 0; while ((unsigned long)StringLen < (ResponseLength - 1)) { strcpy((char*)ReaderNameTmp, (char*)ResponseBuffer+StringLen); ret = SCardConnect(ContextHandle, (char *)ReaderNameTmp, SCARD_SHARE_DIRECT, 0, &SCardHandle, &ActiveProtocol); if ((ret == SCARD_S_SUCCESS)||(ret == SCARD_W_REMOVED_CARD)) { j++; ReaderStatus[j-1][0]=0; ReaderStatus[j-1][1]=0; SCardDisconnect(SCardHandle, SCARD_EJECT_CARD); StringLen += (int)strlen((char*)ReaderNameTmp); StringLen += 1; } else{ return ret; } } *ReaderCount = j; return EXCUTE_SUC ; }
void PCSC::Etablish_context(){ *ReturnValue = SCardEstablishContext( SCARD_SCOPE_USER, // Le contexte est un contexte utilisateur, et toutes les opérations de base sont effectuées dans le domaine de l'utilisateur. NULL, NULL, &Context); // Adresse du buffer ou on stocke le context récupéré Status(); }
//PCSCREADERDRIVERDLL_API unsigned short CCONV HD_ProbeCard(HANDLE ContextNo, HANDLE devNo, short ivPortNo, short ivCardSeat) //PCSCREADERDRIVERDLL_API unsigned short CCONV HD_ProbeCard(HANDLE ContextNo, short ivPortNo, short ivCardSeat) PCSCREADERDRIVERDLL_API unsigned short CCONV HD_ProbeCard(HANDLE devNo,short ivCardSeat) { SCARDCONTEXT ContextNo=NULL; ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ContextNo); if (ret != SCARD_S_SUCCESS) { // GetErrorCode(ret); return CER_PCSC_SCardEstablishContext ; } SCARD_READERSTATE udtReaderState[2]; DWORD EventStatetpm; char Reader[300]; strcpy(Reader,"Gemplus GemPC430 0\0"); udtReaderState[0].szReader=Reader; //udtReaderState[0].dwCurrentState = SCARD_STATE_UNAVAILABLE; //udtReaderState[0].dwCurrentState = SCARD_STATE_PRESENT; udtReaderState[0].dwCurrentState = SCARD_STATE_UNAWARE; // udtReaderState[0].dwEventState = SCARD_STATE_UNKNOWN |SCARD_STATE_CHANGED|SCARD_STATE_IGNORE; // udtReaderState[0].dwEventState = SCARD_STATE_PRESENT; // udtReaderState[0].dwEventState = SCARD_STATE_EMPTY; ret = SCardGetStatusChange(ContextNo, 0, udtReaderState, 1); if (ret != SCARD_S_SUCCESS) { // GetErrorCode(ret); // EventStatetpm = udtReaderState[0].dwEventState; // WriteLog("SCardGetStatusChange1", ivPortNo,EventStatetpm); SCardReleaseContext(ContextNo); ContextHandle = NULL; return CER_PCSC_SCardGetStatusChange; } EventStatetpm = udtReaderState[0].dwEventState; if ((EventStatetpm & 0x00000010)==0x00000010) //0x00000010 -->SCARD_STATE_EMPTY { // GetErrorCode(ret); SCardReleaseContext(ContextNo); ContextHandle = NULL; return CER_NOCARD; } ret = SCardReleaseContext(ContextNo); if (ret != SCARD_S_SUCCESS) { GetErrorCode(ret); return CER_PCSC_SCardReleaseContext; } ContextNo = NULL; return EXCUTE_SUC; }
SCARDCONTEXT * acr122_get_scardcontext (void) { if (_iSCardContextRefCount == 0) { if (SCardEstablishContext (SCARD_SCOPE_USER, NULL, NULL, &_SCardContext) != SCARD_S_SUCCESS) return NULL; } _iSCardContextRefCount++; return &_SCardContext; }
/* :Document-method: new * call-seq: * new(scope) --> context * * Creates an application context connecting to the PC/SC resource manager. * A context is required to access every piece of PC/SC functionality. * Wraps _SCardEstablishContext_ in PC/SC. * * +scope+:: scope of the context; use one of the Smartcard::PCSC::SCOPE_ constants */ static VALUE PCSC_Context_initialize(VALUE self, VALUE scope) { struct SCardContextEx *context; Data_Get_Struct(self, struct SCardContextEx, context); context->pcsc_error = SCardEstablishContext(NUM2INT(scope), NULL, NULL, &context->pcsc_context); if(context->pcsc_error != SCARD_S_SUCCESS) _PCSC_Exception_raise(context->pcsc_error, "SCardEstablishContext"); else context->released = 0; return self; }
LC_CLIENT_RESULT LC_Client_Init(LC_CLIENT *cl) { LONG rv; assert(cl); if (LC_Client_InitCommon()) { DBG_ERROR(LC_LOGDOMAIN, "Error on init"); return LC_Client_ResultInternal; } /* establish context */ rv=SCardEstablishContext(SCARD_SCOPE_SYSTEM, /* scope */ NULL, /* reserved1 */ NULL, /* reserved2 */ &(cl->scardContext)); /* ptr to context */ if (rv!=SCARD_S_SUCCESS) { if (rv == SCARD_E_NO_SERVICE) { DBG_ERROR(LC_LOGDOMAIN, "SCardEstablishContext: " "Error SCARD_E_NO_SERVICE: " "The Smartcard resource manager is not running. " "Maybe you have to start the Smartcard service manually?"); GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error, I18N("The PC/SC service is not running.\n" "Please make sure that the package \"pcscd\" is\n" "installed along with the appropriate driver.\n" "For cyberJack devices you will need to install\n" "the package \"ifd-cyberjack\" (Debian) or\n" "\"cyberjack-ifd\" (SuSE).\n" "For most other readers the package \"libccid\"\n" "needs to be installed." "<html>" "<p>The PC/SC service is not running.</p>" "<p>Please make sure that the package <b>pcscd</b> is " "installed along with the appropriate driver.</p>" "<p>For cyberJack devices you will need to install " "the package <b>ifd-cyberjack</b> (Debian) or " "<b>cyberjack-ifd</b> (SuSE).</p>" "<p>For most other readers the package <b>libccid</b> " "needs to be installed.</p>" "</html>")); } else { DBG_ERROR(LC_LOGDOMAIN, "SCardEstablishContext: %ld (%04lx)", (long int) rv, rv); } LC_Client_FiniCommon(); return LC_Client_ResultIoError; } return LC_Client_ResultOk; }
PCSCReaderProvider::PCSCReaderProvider() : ReaderProvider() { d_scc = 0; long scres = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &d_scc); if (scres != SCARD_S_SUCCESS) { char tmpbuf[128]; memset(tmpbuf, 0x00, sizeof(tmpbuf)); sprintf(tmpbuf, "Can't establish the context for PC/SC service (%x).", static_cast<unsigned int>(scres)); THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, tmpbuf); } }
static VCardStatus passthru_pcsc_lite_init() { LONG rv; if (global_context != 0) { return VCARD_DONE; } rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &global_context); if (rv != SCARD_S_SUCCESS) { return VCARD_FAIL; } return VCARD_DONE; }
/* -------------------------------------------------------------------------- */ LONG sc_init (sc_context *ctx, char *rdr) { SCARD_READERSTATE rSt = {0}; LONG rc=SCARD_S_SUCCESS; LPTSTR c=NULL, cc=NULL; DWORD dw=SCARD_AUTOALLOCATE; rc=SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &ctx->hCtx); if (rc==SCARD_S_SUCCESS) { rc=SCardListReaders(ctx->hCtx, NULL, (LPTSTR) &c, &dw); if (rc==SCARD_S_SUCCESS) { cc=findfirststr(c, rdr); if (cc!=NULL) { rSt.szReader = cc; rSt.dwCurrentState = SCARD_STATE_UNAWARE; rc = SCardGetStatusChange(ctx->hCtx, 0, &rSt, 1); if ( (rSt.dwEventState & SCARD_STATE_EMPTY) > 0 ) rc = SC_BAD; else { ctx->rdr = NULL; ctx->rdrsz = SCARD_AUTOALLOCATE; ctx->CLA = 0; ctx->proto = SCARD_PCI_T0; ctx->rw = 0; rc=SCardConnect(ctx->hCtx, cc, SCARD_SHARE_SHARED, SCARD_MYPROTOSET, &ctx->hCard, &dw); if (dw==SCARD_PROTOCOL_T1) ctx->proto=SCARD_PCI_T1; else if (dw==SCARD_PROTOCOL_RAW) ctx->proto=SCARD_PCI_RAW; if (rc==SCARD_S_SUCCESS) SCardGetAttrib(ctx->hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (LPBYTE)&ctx->rdr, &ctx->rdrsz); } } else rc=SC_BAD; SCardFreeMemory(ctx->hCtx, c); } if ( rc != SCARD_S_SUCCESS) SCardReleaseContext(ctx->hCtx); } return rc; } /* sc_init */
PCSCREADERDRIVERDLL_API unsigned short CCONV HD_ContextInitialize(HANDLE *ContextNo) { SCARDCONTEXT ContextHandle; // // Open a context which communication to the Resource Manager // ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ContextHandle); if (ret != SCARD_S_SUCCESS) { // GetErrorCode(ret); DebugMessage(ret); return CER_PCSC_SCardEstablishContext ; } *ContextNo = (HANDLE)ContextHandle; return EXCUTE_SUC ; }
// // FUNCTION NAME: SIM_Establish_Context // // DESCRIPTION: this is a wrapper for pcsclite SCardEstablishContext function. // Its job is to call that function and manage error messages // eventually returned. // // INPUT PARAMETERS: // DWORD dwScope a pcsclite defined constant that states which scope // the newly created context will have. // // OUTPUT PARAMETERS: SCARDCONTEXT // If nothing goes bad, returns a handler for the new connection, otherwise // exits. // // NOTES: // - For the pcsclite manual is not complete on values returned by its API // functions, further cases may be included in the switch(rv) in the // future. // SCARDCONTEXT SIM_Establish_Context(DWORD dwScope) { SCARDCONTEXT hContext; LONG rv; rv = SCardEstablishContext(dwScope, NULL, NULL, &hContext); switch (rv) { case SCARD_E_INVALID_VALUE: { bail(EXIT_FAILURE, "SIM_Establish_Context:",ERR_INVALID_SCOPE); } case SCARD_S_SUCCESS: { printf("Context has been successfully established.\n"); return(hContext); } default: { bail(EXIT_FAILURE, "SIM_Establish_Context:",ERR_WRONG_RETURN_VALUE); } } }
bool CPCSCClass::EstablishContext() { RetCode = SCardEstablishContext( SCARD_SCOPE_USER, NULL, NULL, &hContext); if(RetCode == SCARD_S_SUCCESS) { mylog.AddToLogs(m_logobj,"SCardEstablishContext Success!"); return true; } else { mylog.AddToLogs(m_logobj,"error: SCardEstablishContext Failed!"); mylog.AddToLogs(m_logobj,TranslatePCSCError()); hContext = 0; return false; } }
int CPCSCMngr::OpenSession(const char* targetCard) { int status = STAT_OK; // CLOSE PREVIOUS SESSION, if (m_hCard) CloseSession(); // OPEN NEW SESSION if (status == STAT_OK) { status = TranslateSCardError(SCardEstablishContext(SCARD_SCOPE_USER,0,0,&m_cardContext)); } // DISPLAY SELECT SMARTCARD DIALOG /* if (status == STAT_OK) { memset( &dlgStruct, 0, sizeof (dlgStruct) ); dlgStruct.dwStructSize = sizeof (dlgStruct); dlgStruct.hSCardContext = m_cardContext; dlgStruct.dwFlags = SC_DLG_FORCE_UI; dlgStruct.lpstrRdr = szReader; dlgStruct.nMaxRdr = 256; dlgStruct.lpstrCard = szCard; dlgStruct.nMaxCard = 256; dlgStruct.lpstrTitle = "Select target card"; dlgStruct.lpstrCardNames = ""; dlgStruct.nMaxCardNames = 20; // Display the select card dialog. status = TranslateSCardError(GetOpenCardName(&dlgStruct)); } /**/ // CONNECT TO CARD if (status == STAT_OK) { status = TranslateSCardError(SCardConnect(m_cardContext, targetCard, SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, &m_hCard, &m_scProtocol)); } return status; }
/* * Class: com_ibm_opencard_terminal_pcsc10_OCFPCSC1 * Method: SCardEstablishContext * Signature: (I)I */ JNIEXPORT jint JNICALL Java_com_ibm_opencard_terminal_pcsc10_OCFPCSC1_SCardEstablishContext (JNIEnv *env, jobject obj, jint scope) { CONTEXT_INFO cInfo; long returnCode; // clear ContextInformation clearContextInfo(&cInfo); returnCode = SCardEstablishContext((DWORD)scope, NULL, NULL, &cInfo.context); if (returnCode != SCARD_S_SUCCESS) { throwPcscException(env, obj, "SCardEstablishContext", "PC/SC Error SCardEstablishContext", returnCode); return 0; } /* add this context to the internal table * it's useful in the case the layer above didn't release the context * the Dll_Main is able to release all established contexts */ addContext(cInfo); return (jint)cInfo.context; }
/********************************************************************************************** 2.PCSC_OpenReader 打开指定读卡器 PCSC_OpenReader(HANDLE *hReader, const char *ReaderName) 参数说明 ReaderName 输入值,指定打开的读卡器名字 hReader 返回值,指定打开的读卡器句柄 返回值 函数返回0x9000表示正确;其余参考Smart Card Return Values ***********************************************************************************************/ PCSCREADERDLL_API LONG CCONV PCSC_OpenReader(HANDLE *hReader, const char *ReaderName) { ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ContextHandle); if (ret != SCARD_S_SUCCESS) { return ret; } #ifdef HED_CIU320A ret = SCardConnect(ContextHandle, (char *)ReaderName, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &SCardHandle, &ActiveProtocol); #else ret = SCardConnect(ContextHandle, (char *)ReaderName, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &SCardHandle, &ActiveProtocol); #endif if ((ret != SCARD_S_SUCCESS)&&(ret != SCARD_W_REMOVED_CARD)) { return ret; } *hReader = (HANDLE)SCardHandle; return EXCUTE_SUC ; }
int main(int argc, char *argv[]) { LONG rv; SCARDCONTEXT hContext; DWORD dwReaders; LPSTR mszReaders = NULL; char *ptr, **readers = NULL; int nbReaders; SCARDHANDLE hCard; DWORD dwActiveProtocol, dwReaderLen, dwState, dwProt, dwAtrLen; BYTE pbAtr[MAX_ATR_SIZE] = ""; char pbReader[MAX_READERNAME] = ""; int reader_nb; unsigned int i; unsigned char bSendBuffer[MAX_BUFFER_SIZE]; unsigned char bRecvBuffer[MAX_BUFFER_SIZE]; DWORD send_length, length; DWORD verify_ioctl = 0; DWORD modify_ioctl = 0; DWORD pin_properties_ioctl = 0; DWORD mct_readerdirect_ioctl = 0; DWORD properties_in_tlv_ioctl = 0; DWORD ccid_esc_command = 0; SCARD_IO_REQUEST pioRecvPci; SCARD_IO_REQUEST pioSendPci; PCSC_TLV_STRUCTURE *pcsc_tlv; #if defined(VERIFY_PIN) | defined(MODIFY_PIN) int offset; #endif #ifdef VERIFY_PIN PIN_VERIFY_STRUCTURE *pin_verify; #endif #ifdef MODIFY_PIN PIN_MODIFY_STRUCTURE *pin_modify; #endif printf("SCardControl sample code\n"); printf("V 1.4 © 2004-2010, Ludovic Rousseau <*****@*****.**>\n\n"); printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL!\n"); printf("Do NOT use it unless you really know what you do.\n\n" NORMAL); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if (rv != SCARD_S_SUCCESS) { printf("SCardEstablishContext: Cannot Connect to Resource Manager %ulX\n", rv); return 1; } /* Retrieve the available readers list */ rv = SCardListReaders(hContext, NULL, NULL, &dwReaders); PCSC_ERROR_EXIT(rv, "SCardListReaders") mszReaders = malloc(sizeof(char)*dwReaders); if (mszReaders == NULL) { printf("malloc: not enough memory\n"); goto end; } rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders); if (rv != SCARD_S_SUCCESS) printf("SCardListReader: %ulX\n", rv); /* Extract readers from the null separated string and get the total * number of readers */ nbReaders = 0; ptr = mszReaders; while (*ptr != '\0') { ptr += strlen(ptr)+1; nbReaders++; } if (nbReaders == 0) { printf("No reader found\n"); goto end; } /* allocate the readers table */ readers = calloc(nbReaders, sizeof(char *)); if (NULL == readers) { printf("Not enough memory for readers[]\n"); goto end; } /* fill the readers table */ nbReaders = 0; ptr = mszReaders; printf("Available readers (use command line argument to select)\n"); while (*ptr != '\0') { printf("%d: %s\n", nbReaders, ptr); readers[nbReaders] = ptr; ptr += strlen(ptr)+1; nbReaders++; } printf("\n"); if (argc > 1) { reader_nb = atoi(argv[1]); if (reader_nb < 0 || reader_nb >= nbReaders) { printf("Wrong reader index: %d\n", reader_nb); goto end; } } else reader_nb = 0; /* connect to a reader (even without a card) */ dwActiveProtocol = -1; printf("Using reader: " GREEN "%s\n" NORMAL, readers[reader_nb]); rv = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); printf(" Protocol: " GREEN "%uld\n" NORMAL, dwActiveProtocol); PCSC_ERROR_EXIT(rv, "SCardConnect") #ifdef GET_GEMPC_FIRMWARE /* get GemPC firmware */ printf(" Get GemPC Firmware\n"); /* this is specific to Gemalto readers */ bSendBuffer[0] = 0x02; rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, bSendBuffer, 1, bRecvBuffer, sizeof(bRecvBuffer), &length); printf(" Firmware: " GREEN); for (i=0; i<length; i++) printf("%02X ", bRecvBuffer[i]); printf(NORMAL "\n"); bRecvBuffer[length] = '\0'; printf(" Firmware: " GREEN "%s" NORMAL" (length " GREEN "%ld" NORMAL " bytes)\n", bRecvBuffer, length); PCSC_ERROR_CONT(rv, "SCardControl") #endif /* does the reader support PIN verification? */ rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, bRecvBuffer, sizeof(bRecvBuffer), &length); PCSC_ERROR_EXIT(rv, "SCardControl") printf(" TLV (%uld): " GREEN, length); for (i=0; i<length; i++) printf("%02X ", bRecvBuffer[i]); printf(NORMAL "\n"); PCSC_ERROR_CONT(rv, "SCardControl(CM_IOCTL_GET_FEATURE_REQUEST)") if (length % sizeof(PCSC_TLV_STRUCTURE)) { printf("Inconsistent result! Bad TLV values!\n"); goto end; } /* get the number of elements instead of the complete size */ length /= sizeof(PCSC_TLV_STRUCTURE); pcsc_tlv = (PCSC_TLV_STRUCTURE *)bRecvBuffer; for (i = 0; i < length; i++) { switch (pcsc_tlv[i].tag) { case FEATURE_VERIFY_PIN_DIRECT: PRINT_GREEN("Reader supports", "FEATURE_VERIFY_PIN_DIRECT"); verify_ioctl = ntohl(pcsc_tlv[i].value); break; case FEATURE_MODIFY_PIN_DIRECT: PRINT_GREEN("Reader supports", "FEATURE_MODIFY_PIN_DIRECT"); modify_ioctl = ntohl(pcsc_tlv[i].value); break; case FEATURE_IFD_PIN_PROPERTIES: PRINT_GREEN("Reader supports", "FEATURE_IFD_PIN_PROPERTIES"); pin_properties_ioctl = ntohl(pcsc_tlv[i].value); break; case FEATURE_MCT_READER_DIRECT: PRINT_GREEN("Reader supports", "FEATURE_MCT_READER_DIRECT"); mct_readerdirect_ioctl = ntohl(pcsc_tlv[i].value); break; case FEATURE_GET_TLV_PROPERTIES: PRINT_GREEN("Reader supports", "FEATURE_GET_TLV_PROPERTIES"); properties_in_tlv_ioctl = ntohl(pcsc_tlv[i].value); break; case FEATURE_CCID_ESC_COMMAND: PRINT_GREEN("Reader supports", "FEATURE_CCID_ESC_COMMAND"); ccid_esc_command = ntohl(pcsc_tlv[i].value); break; default: PRINT_RED_DEC("Can't parse tag", pcsc_tlv[i].tag); } } printf("\n"); if (properties_in_tlv_ioctl) { int value; int ret; rv = SCardControl(hCard, properties_in_tlv_ioctl, NULL, 0, bRecvBuffer, sizeof(bRecvBuffer), &length); PCSC_ERROR_CONT(rv, "SCardControl(GET_TLV_PROPERTIES)") printf("GET_TLV_PROPERTIES (" GREEN "%uld" NORMAL "): " GREEN, length); for (i=0; i<length; i++) printf("%02X ", bRecvBuffer[i]); printf(NORMAL "\n"); printf("\nDisplay all the properties:\n"); parse_properties(bRecvBuffer, length); printf("\nFind a specific property:\n"); ret = PCSCv2Part10_find_TLV_property_by_tag_from_buffer(bRecvBuffer, length, PCSCv2_PART10_PROPERTY_wIdVendor, &value); if (ret) PRINT_RED_DEC(" wIdVendor", ret); else PRINT_GREEN_HEX4(" wIdVendor", value); ret = PCSCv2Part10_find_TLV_property_by_tag_from_hcard(hCard, PCSCv2_PART10_PROPERTY_wIdProduct, &value); if (ret) PRINT_RED_DEC(" wIdProduct", ret); else PRINT_GREEN_HEX4(" wIdProduct", value); printf("\n"); } if (mct_readerdirect_ioctl) { char secoder_info[] = { 0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }; rv = SCardControl(hCard, mct_readerdirect_ioctl, secoder_info, sizeof(secoder_info), bRecvBuffer, sizeof(bRecvBuffer), &length); PCSC_ERROR_CONT(rv, "SCardControl(MCT_READER_DIRECT)") printf("MCT_READER_DIRECT (%uld): ", length); for (i=0; i<length; i++) printf("%02X ", bRecvBuffer[i]); printf("\n"); } if (pin_properties_ioctl) { PIN_PROPERTIES_STRUCTURE *pin_properties; rv = SCardControl(hCard, pin_properties_ioctl, NULL, 0, bRecvBuffer, sizeof(bRecvBuffer), &length); PCSC_ERROR_CONT(rv, "SCardControl(pin_properties_ioctl)") printf("PIN PROPERTIES (" GREEN "%uld" NORMAL "): " GREEN, length); for (i=0; i<length; i++) printf("%02X ", bRecvBuffer[i]); printf(NORMAL "\n"); pin_properties = (PIN_PROPERTIES_STRUCTURE *)bRecvBuffer; PRINT_GREEN_HEX4(" wLcdLayout", pin_properties -> wLcdLayout); PRINT_GREEN_DEC(" bEntryValidationCondition", pin_properties -> bEntryValidationCondition); PRINT_GREEN_DEC(" bTimeOut2", pin_properties -> bTimeOut2); printf("\n"); } #ifdef GET_GEMPC_FIRMWARE if (ccid_esc_command) { /* get GemPC firmware */ printf("Get GemPC Firmware\n"); /* this is specific to Gemalto readers */ bSendBuffer[0] = 0x02; rv = SCardControl(hCard, ccid_esc_command, bSendBuffer, 1, bRecvBuffer, sizeof(bRecvBuffer), &length); printf(" Firmware: " GREEN); for (i=0; i<length; i++) printf("%02X ", bRecvBuffer[i]); printf(NORMAL "\n"); bRecvBuffer[length] = '\0'; printf(" Firmware: " GREEN "%s" NORMAL" (length " GREEN "%ld" NORMAL " bytes)\n", bRecvBuffer, length); PCSC_ERROR_CONT(rv, "SCardControl") } #endif if (0 == verify_ioctl) { printf("Reader %s does not support PIN verification\n", readers[reader_nb]); goto end; } /* get card status */ dwAtrLen = sizeof(pbAtr); dwReaderLen = sizeof(pbReader); rv = SCardStatus(hCard, pbReader, &dwReaderLen, &dwState, &dwProt, pbAtr, &dwAtrLen); printf(" Reader: %s (length %uld bytes)\n", pbReader, dwReaderLen); printf(" State: 0x%04ulX\n", dwState); printf(" Prot: %uld\n", dwProt); printf(" ATR (length %uld bytes):", dwAtrLen); for (i=0; i<dwAtrLen; i++) printf(" %02X", pbAtr[i]); printf("\n"); PCSC_ERROR_CONT(rv, "SCardStatus") if (dwState & SCARD_ABSENT) { printf("No card inserted\n"); goto end; } /* connect to a reader (even without a card) */ dwActiveProtocol = -1; rv = SCardReconnect(hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, SCARD_LEAVE_CARD, &dwActiveProtocol); printf(" Protocol: %uld\n", dwActiveProtocol); PCSC_ERROR_EXIT(rv, "SCardReconnect") switch(dwActiveProtocol) { case SCARD_PROTOCOL_T0: pioSendPci = *SCARD_PCI_T0; break; case SCARD_PROTOCOL_T1: pioSendPci = *SCARD_PCI_T1; break; default: printf("Unknown protocol. No card present?\n"); return -1; } /* APDU select applet */ printf("Select applet: "); send_length = 11; memcpy(bSendBuffer, "\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\xFF", send_length); for (i=0; i<send_length; i++) printf(" %02X", bSendBuffer[i]); printf("\n"); length = sizeof(bRecvBuffer); rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length, &pioRecvPci, bRecvBuffer, &length); printf(" card response:"); for (i=0; i<length; i++) printf(" %02X", bRecvBuffer[i]); printf("\n"); PCSC_ERROR_EXIT(rv, "SCardTransmit") if ((bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00)) { printf("Error: test applet not found!\n"); goto end; } #ifdef VERIFY_PIN /* verify PIN */ printf(" Secure verify PIN\n"); pin_verify = (PIN_VERIFY_STRUCTURE *)bSendBuffer; /* table for bEntryValidationCondition * 0x01: Max size reached * 0x02: Validation key pressed * 0x04: Timeout occured */ /* PC/SC v2.02.05 Part 10 PIN verification data structure */ pin_verify -> bTimerOut = 0x00; pin_verify -> bTimerOut2 = 0x00; pin_verify -> bmFormatString = 0x82; pin_verify -> bmPINBlockString = 0x04; pin_verify -> bmPINLengthFormat = 0x00; pin_verify -> wPINMaxExtraDigit = 0x0408; /* Min Max */ pin_verify -> bEntryValidationCondition = 0x02; /* validation key pressed */ pin_verify -> bNumberMessage = 0x01; pin_verify -> wLangId = 0x0904; pin_verify -> bMsgIndex = 0x00; pin_verify -> bTeoPrologue[0] = 0x00; pin_verify -> bTeoPrologue[1] = 0x00; pin_verify -> bTeoPrologue[2] = 0x00; /* pin_verify -> ulDataLength = 0x00; we don't know the size yet */ /* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */ offset = 0; pin_verify -> abData[offset++] = 0x00; /* CLA */ pin_verify -> abData[offset++] = 0x20; /* INS: VERIFY */ pin_verify -> abData[offset++] = 0x00; /* P1 */ pin_verify -> abData[offset++] = 0x00; /* P2 */ pin_verify -> abData[offset++] = 0x08; /* Lc: 8 data bytes */ pin_verify -> abData[offset++] = 0x30; /* '0' */ pin_verify -> abData[offset++] = 0x30; /* '0' */ pin_verify -> abData[offset++] = 0x30; /* '0' */ pin_verify -> abData[offset++] = 0x30; /* '0' */ pin_verify -> abData[offset++] = 0x00; /* '\0' */ pin_verify -> abData[offset++] = 0x00; /* '\0' */ pin_verify -> abData[offset++] = 0x00; /* '\0' */ pin_verify -> abData[offset++] = 0x00; /* '\0' */ pin_verify -> ulDataLength = offset; /* APDU size */ length = sizeof(PIN_VERIFY_STRUCTURE) + offset -1; /* -1 because PIN_VERIFY_STRUCTURE contains the first byte of abData[] */ printf(" command:"); for (i=0; i<length; i++) printf(" %02X", bSendBuffer[i]); printf("\n"); printf("Enter your PIN: "); fflush(stdout); rv = SCardControl(hCard, verify_ioctl, bSendBuffer, length, bRecvBuffer, sizeof(bRecvBuffer), &length); { #ifndef S_SPLINT_S fd_set fd; #endif struct timeval timeout; FD_ZERO(&fd); FD_SET(STDIN_FILENO, &fd); /* stdin */ timeout.tv_sec = 0; /* timeout = 0.1s */ timeout.tv_usec = 100000; /* we only try to read stdin if the pinpad is on a keyboard * we do not read stdin for a SPR 532 for example */ if (select(1, &fd, NULL, NULL, &timeout) > 0) { /* read the fake digits */ char in[40]; /* 4 digits + \n + \0 */ (void)fgets(in, sizeof(in), stdin); printf("keyboard sent: %s", in); } else /* if it is not a keyboard */ printf("\n"); } printf(" card response:"); for (i=0; i<length; i++) printf(" %02X", bRecvBuffer[i]); printf("\n"); PCSC_ERROR_CONT(rv, "SCardControl") /* verify PIN dump */ printf("\nverify PIN dump: "); send_length = 5; memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF", send_length); for (i=0; i<send_length; i++) printf(" %02X", bSendBuffer[i]); printf("\n"); length = sizeof(bRecvBuffer); rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length, &pioRecvPci, bRecvBuffer, &length); printf(" card response:"); for (i=0; i<length; i++) printf(" %02X", bRecvBuffer[i]); printf("\n"); PCSC_ERROR_EXIT(rv, "SCardTransmit") if ((2 == length) && (0x6C == bRecvBuffer[0])) { printf("\nverify PIN dump: "); send_length = 5; memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF", send_length); bSendBuffer[4] = bRecvBuffer[1]; for (i=0; i<send_length; i++) printf(" %02X", bSendBuffer[i]); printf("\n"); length = sizeof(bRecvBuffer); rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length, &pioRecvPci, bRecvBuffer, &length); printf(" card response:"); for (i=0; i<length; i++) printf(" %02X", bRecvBuffer[i]); printf("\n"); PCSC_ERROR_EXIT(rv, "SCardTransmit") }
int main(/*@unused@*/ int argc, /*@unused@*/ char **argv) { SCARDHANDLE hCard; SCARDCONTEXT hContext; SCARD_READERSTATE rgReaderStates[1]; DWORD dwReaderLen, dwState, dwProt, dwAtrLen; DWORD dwPref, dwReaders = 0; char *pcReader = NULL, *mszReaders; #ifdef USE_AUTOALLOCATE unsigned char *pbAtr = NULL; #else unsigned char pbAtr[MAX_ATR_SIZE]; #endif union { unsigned char as_char[100]; DWORD as_DWORD; uint32_t as_uint32_t; } buf; DWORD dwBufLen; unsigned char *pbAttr = NULL; DWORD pcbAttrLen; char *mszGroups; DWORD dwGroups = 0; long rv; DWORD i; int p, iReader; int iList[16] = {0}; SCARD_IO_REQUEST ioRecvPci = *SCARD_PCI_T0; /* use a default value */ const SCARD_IO_REQUEST *pioSendPci; unsigned char bSendBuffer[MAX_BUFFER_SIZE]; unsigned char bRecvBuffer[MAX_BUFFER_SIZE]; DWORD send_length, length; (void)argc; (void)argv; printf("\nMUSCLE PC/SC Lite unitary test Program\n\n"); printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n"); printf("Do NOT use it unless you really know what you do.\n\n" NORMAL); printf("Testing SCardEstablishContext\t: "); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); test_rv(rv, hContext, PANIC); printf("Testing SCardIsValidContext\t: "); rv = SCardIsValidContext(hContext); test_rv(rv, hContext, PANIC); printf("Testing SCardIsValidContext\t: "); rv = SCardIsValidContext(hContext+1); test_rv(rv, hContext, DONT_PANIC); printf("Testing SCardListReaderGroups\t: "); #ifdef USE_AUTOALLOCATE dwGroups = SCARD_AUTOALLOCATE; rv = SCardListReaderGroups(hContext, (LPSTR)&mszGroups, &dwGroups); #else rv = SCardListReaderGroups(hContext, NULL, &dwGroups); test_rv(rv, hContext, PANIC); printf("Testing SCardListReaderGroups\t: "); mszGroups = calloc(dwGroups, sizeof(char)); rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups); #endif test_rv(rv, hContext, PANIC); /* * Have to understand the multi-string here */ p = 0; for (i = 0; i+1 < dwGroups; i++) { ++p; printf(GREEN "Group %02d: %s\n" NORMAL, p, &mszGroups[i]); while (mszGroups[++i] != 0) ; } #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, mszGroups); test_rv(rv, hContext, PANIC); #else free(mszGroups); #endif wait_for_card_again: mszGroups = NULL; printf("Testing SCardListReaders\t: "); rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders); test_rv(rv, hContext, DONT_PANIC); if (SCARD_E_NO_READERS_AVAILABLE == rv) { printf("Testing SCardGetStatusChange \n"); printf("Please insert a working reader\t: "); (void)fflush(stdout); rgReaderStates[0].szReader = "\\\\?PnP?\\Notification"; rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY; rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1); test_rv(rv, hContext, PANIC); } printf("Testing SCardListReaders\t: "); #ifdef USE_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; rv = SCardListReaders(hContext, mszGroups, (LPSTR)&mszReaders, &dwReaders); #else rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders); test_rv(rv, hContext, PANIC); printf("Testing SCardListReaders\t: "); mszReaders = calloc(dwReaders, sizeof(char)); rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders); #endif test_rv(rv, hContext, DONT_PANIC); /* * Have to understand the multi-string here */ p = 0; for (i = 0; i+1 < dwReaders; i++) { ++p; printf(GREEN "Reader %02d: %s\n" NORMAL, p, &mszReaders[i]); iList[p] = i; while (mszReaders[++i] != 0) ; } if (p > 1) do { char input[80]; char *r; printf("Enter the reader number\t\t: "); r = fgets(input, sizeof(input), stdin); if (NULL == r) iReader = -1; else iReader = atoi(input); if (iReader > p || iReader <= 0) printf("Invalid Value - try again\n"); } while (iReader > p || iReader <= 0); else iReader = 1; rgReaderStates[0].szReader = &mszReaders[iList[iReader]]; rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY; printf("Waiting for card insertion\t: "); (void)fflush(stdout); rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1); test_rv(rv, hContext, PANIC); if (rgReaderStates[0].dwEventState & SCARD_STATE_UNKNOWN) { printf("\nA reader has been connected/disconnected\n"); goto wait_for_card_again; } printf("Testing SCardConnect\t\t: "); rv = SCardConnect(hContext, &mszReaders[iList[iReader]], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwPref); test_rv(rv, hContext, PANIC); switch(dwPref) { case SCARD_PROTOCOL_T0: pioSendPci = SCARD_PCI_T0; break; case SCARD_PROTOCOL_T1: pioSendPci = SCARD_PCI_T1; break; case SCARD_PROTOCOL_RAW: pioSendPci = SCARD_PCI_RAW; break; default: printf("Unknown protocol\n"); return -1; } /* APDU select file */ printf("Select file:"); send_length = 7; memcpy(bSendBuffer, "\x00\xA4\x00\x00\x02\x3F\x00", send_length); for (i=0; i<send_length; i++) printf(" %02X", bSendBuffer[i]); printf("\n"); length = sizeof(bRecvBuffer); printf("Testing SCardTransmit\t\t: "); rv = SCardTransmit(hCard, pioSendPci, bSendBuffer, send_length, &ioRecvPci, bRecvBuffer, &length); test_rv(rv, hContext, PANIC); printf(" card response:" GREEN); for (i=0; i<length; i++) printf(" %02X", bRecvBuffer[i]); printf("\n" NORMAL); printf("Testing SCardControl\t\t: "); #ifdef PCSC_PRE_120 { char buffer[1024] = "Foobar"; DWORD cbRecvLength = sizeof(buffer); rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength); } #else { char buffer[1024] = { 0x02 }; DWORD cbRecvLength = sizeof(buffer); rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer, sizeof(buffer), &cbRecvLength); if (cbRecvLength && (SCARD_S_SUCCESS == rv)) { for (i=0; i<cbRecvLength; i++) printf("%c", buffer[i]); printf(" "); } } #endif test_rv(rv, hContext, DONT_PANIC); printf("Testing SCardGetAttrib\t\t: "); #ifdef USE_AUTOALLOCATE pcbAttrLen = SCARD_AUTOALLOCATE; rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (unsigned char *)&pbAttr, &pcbAttrLen); #else rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, NULL, &pcbAttrLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME length: " GREEN "%ld\n" NORMAL, pcbAttrLen); pbAttr = malloc(pcbAttrLen); } printf("Testing SCardGetAttrib\t\t: "); rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, pbAttr, &pcbAttrLen); #endif test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME: " GREEN "%s\n" NORMAL, pbAttr); #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, pbAttr); test_rv(rv, hContext, PANIC); #else if (pbAttr) free(pbAttr); #endif printf("Testing SCardGetAttrib\t\t: "); #ifdef USE_AUTOALLOCATE pcbAttrLen = SCARD_AUTOALLOCATE; rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (unsigned char *)&pbAttr, &pcbAttrLen); #else rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &pcbAttrLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen); pbAttr = malloc(pcbAttrLen); } printf("Testing SCardGetAttrib\t\t: "); rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAttr, &pcbAttrLen); #endif test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen); printf("SCARD_ATTR_ATR_STRING: " GREEN); for (i = 0; i < pcbAttrLen; i++) printf("%02X ", pbAttr[i]); printf("\n" NORMAL); } #ifdef USE_AUTOALLOCATE printf("Testing SCardFreeMemory\t\t: "); rv = SCardFreeMemory(hContext, pbAttr); test_rv(rv, hContext, PANIC); #else if (pbAttr) free(pbAttr); #endif printf("Testing SCardGetAttrib\t\t: "); dwBufLen = sizeof(buf); rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, buf.as_char, &dwBufLen); test_rv(rv, hContext, DONT_PANIC); if (rv == SCARD_S_SUCCESS) { int valid = 1; /* valid value by default */ long value; printf("Vendor IFD version\t\t: "); if (dwBufLen == sizeof(DWORD)) value = buf.as_DWORD; else { if (dwBufLen == sizeof(uint32_t)) value = buf.as_uint32_t; else { printf(RED "Unsupported size\n" NORMAL); valid = 0; /* invalid value */ } } if (valid) { int M = (value & 0xFF000000) >> 24; /* Major */ int m = (value & 0x00FF0000) >> 16; /* Minor */ int b = (value & 0x0000FFFF); /* build */ printf(GREEN "%d.%d.%d\n" NORMAL, M, m, b); } }