Пример #1
0
nfc_device *
acr122_open (const nfc_connstring connstring)
{
  struct acr122_descriptor ndd;
  int connstring_decode_level = acr122_connstring_decode (connstring, &ndd);

  if (connstring_decode_level < 2) {
    return NULL;
  }
  // FIXME: acr122_open() does not take care about bus index

  char   *pcFirmware;
  nfc_device *pnd = nfc_device_new (connstring);
  pnd->driver_data = malloc (sizeof (struct acr122_data));

  // Alloc and init chip's data
  pn53x_data_new (pnd, &acr122_io);

  SCARDCONTEXT *pscc;
  
  log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to open %s", ndd.pcsc_device_name);
  // Test if context succeeded
  if (!(pscc = acr122_get_scardcontext ()))
    goto error;
  // Test if we were able to connect to the "emulator" card
  if (SCardConnect (*pscc, ndd.pcsc_device_name, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
    // Connect to ACR122 firmware version >2.0
    if (SCardConnect (*pscc, ndd.pcsc_device_name, SCARD_SHARE_DIRECT, 0, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
      // We can not connect to this device.
      log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "PCSC connect failed");
      goto error;
    }
  }
  // Configure I/O settings for card communication
  DRIVER_DATA (pnd)->ioCard.cbPciLength = sizeof (SCARD_IO_REQUEST);

  // Retrieve the current firmware version
  pcFirmware = acr122_firmware (pnd);
  if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) {

    // Done, we found the reader we are looking for
    snprintf (pnd->name, sizeof (pnd->name), "%s / %s", ndd.pcsc_device_name, pcFirmware);

    // 50: empirical tuning on Touchatag
    // 46: empirical tuning on ACR122U
    CHIP_DATA (pnd)->timer_correction = 50;

    pnd->driver = &acr122_driver;

    pn53x_init (pnd);

    return pnd;
  }

error:
  nfc_device_free (pnd);

  return NULL;
}
Пример #2
0
static void smartcard_check_status (SCARDCONTEXT hContext,
		const char* pReader,
		SCARDHANDLE hCardHandle, /* Can be 0 on the first call */
		SCARDHANDLE* newCardHandle, /* The handle returned */
		DWORD* pdwState) {
	DWORD shareMode = SCARD_SHARE_SHARED;
	DWORD preferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
	DWORD dwAP;
	LONG result;

	if (hCardHandle == 0) {
		result = SCardConnect(hContext, pReader, shareMode, preferredProtocols, &hCardHandle, &dwAP);
		DEBUG_SCARD_STATUS("SCardConnect", result);
		if (SCARD_S_SUCCESS != result) {
			hCardHandle = 0;
		}
	}

	char szReader[200];
	DWORD cch = sizeof(szReader);
	BYTE bAttr[32];
	DWORD cByte = 32;
	size_t countStatusAttempts = 0;

	while (hCardHandle && (countStatusAttempts < 2)) {
		*pdwState = SCARD_UNKNOWN;

		result = SCardStatus(hCardHandle, /* Unfortunately we can't use NULL here */ szReader, &cch, pdwState, NULL, (LPBYTE)&bAttr, &cByte);
		DEBUG_SCARD_STATUS("SCardStatus", result);
		countStatusAttempts++;

		if ((SCARD_W_RESET_CARD == result) && (countStatusAttempts < 2)) {
			result = SCardReconnect(hCardHandle, shareMode, preferredProtocols, SCARD_RESET_CARD, &dwAP);
			DEBUG_SCARD_STATUS("SCardReconnect", result);
			if (SCARD_S_SUCCESS != result) {
				break;
			}
		}
		else {
			break;
		}
	}

	if (SCARD_S_SUCCESS != result) {
		if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
			*pdwState = SCARD_ABSENT;
		}
		else {
			*pdwState = SCARD_UNKNOWN;
		}
	}

	if (newCardHandle == NULL) {
		result = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
		DEBUG_SCARD_STATUS("SCardDisconnect", result);
	}
	else {
		*newCardHandle = hCardHandle;
	}
}
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;
}
Пример #4
0
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;
}
Пример #5
0
/*
 * Connect to card.
 */
JNIEXPORT jint JNICALL GEN_FUNCNAME(Context_NativeConnect)
(JNIEnv *env, jobject _this, jobject _card, jstring jrdrName, jint dwSharedMode, jint dwPreferredProtocols)
{
    SCARDCONTEXT ctx;
    SCARDHANDLE card;
    const char *crdrName;
    jboolean isCopy;
    DWORD proto;
    LONG rv;

    crdrName = (*env)->GetStringUTFChars(env, jrdrName, &isCopy);

    ctx = (SCARDCONTEXT) (*env)->GetLongField(env, _this, CtxField);

    JPCSC_LOG(("NativeConnect(): reader %s, mode %d, proto %d\n", crdrName, dwSharedMode, dwPreferredProtocols));

    rv = SCardConnect(ctx, crdrName, dwSharedMode, dwPreferredProtocols, &card, &proto);

    (*env)->ReleaseStringUTFChars(env, jrdrName, crdrName);

    if (rv != SCARD_S_SUCCESS) {
        return rv;
    }

    JPCSC_LOG(("NativeConnect(): card 0x%x, proto 0x%x\n", (int) card, (int) proto));

    (*env)->SetLongField(env, _card, CardField, card);
    (*env)->SetIntField(env, _card, ProtoField, proto);

    return rv;
}
Пример #6
0
/* -------------------------------------------------------------------------- */
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 */
Пример #7
0
static int32_t pcsc_check_card_inserted(struct s_reader *pcsc_reader)
{
    struct pcsc_data *crdr_data = pcsc_reader->crdr_data;
    DWORD dwState, dwAtrLen, dwReaderLen;
    unsigned char pbAtr[64];
    SCARDHANDLE rv;

    dwAtrLen = sizeof(pbAtr);
    rv=0;
    dwState=0;
    dwReaderLen=0;

    // Do we have a card ?
    if (!crdr_data->pcsc_has_card && !crdr_data->hCard) {
        // try connecting to the card
        rv = SCardConnect(crdr_data->hContext, crdr_data->pcsc_name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &crdr_data->hCard, &crdr_data->dwActiveProtocol);
        if (rv == (LONG)SCARD_E_NO_SMARTCARD) {
            // no card in pcsc_reader
            crdr_data->pcsc_has_card=0;
            if(crdr_data->hCard) {
                SCardDisconnect(crdr_data->hCard, SCARD_RESET_CARD);
                crdr_data->hCard=0;
            }
            // rdr_debug_mask(pcsc_reader, D_DEVICE, "PCSC card in %s removed / absent [dwstate=%lx rv=(%lx)]", crdr_data->pcsc_name, dwState, (unsigned long)rv );
            return OK;
        }
        else if (rv == (LONG)SCARD_W_UNRESPONSIVE_CARD) {
            // there is a problem with the card in the pcsc_reader
            crdr_data->pcsc_has_card=0;
            crdr_data->hCard=0;
            rdr_log(pcsc_reader, "PCSC card in %s is unresponsive. Eject and re-insert please.", crdr_data->pcsc_name);
            return ERROR;
        }
        else if( rv == SCARD_S_SUCCESS ) {
            // we have a card
            crdr_data->pcsc_has_card=1;
            rdr_log(pcsc_reader, "PCSC was opened with handle: %ld", (long)crdr_data->hCard);
        }
        else {
            // if we get here we have a bigger problem -> display status and debug
            // rdr_debug_mask(pcsc_reader, D_DEVICE, "PCSC pcsc_reader %s status [dwstate=%lx rv=(%lx)]", crdr_data->pcsc_name, dwState, (unsigned long)rv );
            return ERROR;
        }

    }

    // if we get there the card is ready, check its status
    rv = SCardStatus(crdr_data->hCard, NULL, &dwReaderLen, &dwState, &crdr_data->dwActiveProtocol, pbAtr, &dwAtrLen);

    if (rv == SCARD_S_SUCCESS && (dwState & (SCARD_PRESENT | SCARD_NEGOTIABLE | SCARD_POWERED ) )) {
        return OK;
    }
    else {
        SCardDisconnect(crdr_data->hCard, SCARD_RESET_CARD);
        crdr_data->hCard = 0;
        crdr_data->pcsc_has_card = 0;
    }

    return ERROR;
}
Пример #8
0
//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 ;	

}
Пример #9
0
int32_t pcsc_check_card_inserted(struct s_reader *pcsc_reader)
{
    DWORD dwState, dwAtrLen, dwReaderLen;
    BYTE pbAtr[64];
    LONG rv;

    dwAtrLen = sizeof(pbAtr);
    rv=0;
    dwState=0;
    dwReaderLen=0;

    // Do we have a card ?
    if (!pcsc_reader->pcsc_has_card && !(SCARDHANDLE)(pcsc_reader->hCard)) {
        // try connecting to the card
        rv = SCardConnect(pcsc_reader->hContext, pcsc_reader->pcsc_name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &pcsc_reader->hCard, &pcsc_reader->dwActiveProtocol);
        if (rv==SCARD_E_NO_SMARTCARD) {
            // no card in pcsc_reader
            pcsc_reader->pcsc_has_card=0;
            if((SCARDHANDLE)(pcsc_reader->hCard)) {
                SCardDisconnect((SCARDHANDLE)(pcsc_reader->hCard),SCARD_RESET_CARD);
                pcsc_reader->hCard=0;
            }
            // rdr_debug_mask(pcsc_reader, D_DEVICE, "PCSC card in %s removed / absent [dwstate=%lx rv=(%lx)]", pcsc_reader->pcsc_name, dwState, (unsigned long)rv );
            return 0;
        }
        else if( rv == SCARD_W_UNRESPONSIVE_CARD ) {
            // there is a problem with the card in the pcsc_reader
            pcsc_reader->pcsc_has_card=0;
            pcsc_reader->hCard=0;
            rdr_log(pcsc_reader, "PCSC card in %s is unresponsive. Eject and re-insert please.", pcsc_reader->pcsc_name);
            return 0;
        }
        else if( rv == SCARD_S_SUCCESS ) {
            // we have a card
            pcsc_reader->pcsc_has_card=1;
        }
        else {
            // if we get here we have a bigger problem -> display status and debug
            // rdr_debug_mask(pcsc_reader, D_DEVICE, "PCSC pcsc_reader %s status [dwstate=%lx rv=(%lx)]", pcsc_reader->pcsc_name, dwState, (unsigned long)rv );
            return 0;
        }

    }

    // if we get there the card is ready, check its status
    rv = SCardStatus((SCARDHANDLE)(pcsc_reader->hCard), NULL, &dwReaderLen, &dwState, &pcsc_reader->dwActiveProtocol, pbAtr, &dwAtrLen);

    if (rv == SCARD_S_SUCCESS && (dwState & (SCARD_PRESENT | SCARD_NEGOTIABLE | SCARD_POWERED ) )) {
        return CARD_INSERTED;
    }
    else {
        SCardDisconnect((SCARDHANDLE)(pcsc_reader->hCard),SCARD_RESET_CARD);
        pcsc_reader->hCard=0;
        pcsc_reader->pcsc_has_card=0;
    }

    return 0;
}
Пример #10
0
testA(int argc,char** argv ) {
	int i;
myprintf("=============================\n");
myprintf("Part A: Checking card monitor\n");
myprintf("=============================\n");
	(rgReaderStates[0])->dwCurrentState = SCARD_STATE_UNAWARE;
	 rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 ); 
	 if( (rgReaderStates[0])->dwEventState & SCARD_STATE_PRESENT ) {
		myprintf("<<  Please remove smart card \n");
		(rgReaderStates[0])->dwCurrentState = SCARD_STATE_PRESENT;
	 	rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 ); 
	 }
	printit("1.Please insert smart card");
		(rgReaderStates[0])->dwCurrentState = SCARD_STATE_EMPTY;
		rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 );
	 myprintf("Passed\n");
	 printit("2. IOCTL_SMARTCARD_IS_PRESENT");
	 myprintf("Passed\n");
	 printit("3. Please remove smart card ");
	 (rgReaderStates[0])->dwCurrentState = SCARD_STATE_PRESENT; 
     rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 );
     if( rv != SCARD_S_SUCCESS )
        return -1;
	 if( (rgReaderStates[0])->dwEventState & SCARD_STATE_EMPTY) myprintf("Passed\n");
	 else 
		myprintf("Failed \n");
	 printit("4. IOCTL_SMARTCARD_IS_ABSENT");
	 myprintf("Passed\n");
	 printit("5. Insert and remove a smart card repeatedly");
	(rgReaderStates[0])->dwCurrentState = SCARD_STATE_EMPTY;
	for(i=0;i<10;i++) {
	 	rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 ); 
		(rgReaderStates[0])->dwCurrentState = (rgReaderStates[0])->dwEventState;
	 }
	 myprintf("Passed \n");
	 if( more_details ) {
		 rv = SCardConnect(hContext, readerName,
            SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0| SCARD_PROTOCOL_T1,
            &hCard, &dwPref);
     	if ( rv != SCARD_S_SUCCESS ) {
     		SCardReleaseContext( hContext );
    		return 0;
 	 	}                         
		readerlen=100;
	 	rv = SCardStatus(hCard,readerName,&readerlen,&readerstate,&protocol,r,&atrlen);
	 	if( rv != SCARD_S_SUCCESS ) {
			return -1;
		 }
		 myprintf("ATR :");
		 for(i=0;i<atrlen;i++) {
			myprintf("%0x ",r[i]);
		 }
		 myprintf("\n");
		 myprintf("Powered up successfully \n");
	 }
	 return 0;
}
Пример #11
0
bool QPCSCReader::connect( Connect connect )
{
	if( !d->d->context )
		return false;
	LONG err = SCardConnect( d->d->context, d->state.szReader, connect,
		SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, &d->card, &d->proto );
	d->updateState();
	return err == SCARD_S_SUCCESS;
}
Пример #12
0
void PCSC::Connect(){
	*ReturnValue = SCardConnect( 
					Context, // Adresse du buffer ou on stocke le context récupéré
					nameCardreader,     //nom du lecteur
					SCARD_SHARE_EXCLUSIVE,  // mode de partage
					SCARD_PROTOCOL_Tx, //protocole (T=0 ou T=1).
					&Cardhandle,               // retourn l'handle de la carte
					&ActiveProtocol);
	Status();
}
Пример #13
0
/*
 * Class:     com_ibm_opencard_terminal_pcsc10_OCFPCSC1
 * Method:    SCardConnect
 * Signature: (ILjava/lang/String;IILjava/lang/Integer;)I
 */
JNIEXPORT jint JNICALL Java_com_ibm_opencard_terminal_pcsc10_OCFPCSC1_SCardConnect
(JNIEnv *env, jobject obj, jint context, jstring jReader,
 jint jShareMode, jint jPreferredProtocol, jobject jActiveProtocol) {

    const char   *readerUTF;
    long	       cardHandle;
    DWORD        activeProtocol;
    int		       cPos;
    long	       returnCode;
    CONTEXT_INFO cInfo;

    /* check if context exists */
    if (cPos = isContextAvailable((long)context) < 0) {
        throwPcscException(env, obj, "SCardConnect", "PC/SC Wrapper Error: context not in table", 0);
        return 0;
    }

    // get contextInformationRecord
    cInfo = getContextInfoViaContext((SCARDCONTEXT)context);
    if (cInfo.context == 0) {
        throwPcscException(env, obj, "SCardConnect", "PC/SC Wrapper Error: couldn't get context information record", 0);
        return 0;
    }

    /* get the readers friendly name as 8bit code */
    readerUTF = env->GetStringUTFChars(jReader, NULL);

    /* get a connection to the card */
    returnCode = SCardConnect(  (SCARDCONTEXT)context,
                                readerUTF,
                                (DWORD)jShareMode,
                                (DWORD)jPreferredProtocol,
                                (LPSCARDHANDLE)&cardHandle,
                                (DWORD *)&activeProtocol);

    /* release the readers friendly name */
    env->ReleaseStringUTFChars(jReader, readerUTF);

    if (returnCode != SCARD_S_SUCCESS) {
        throwPcscException(env, obj, "SCardConnect", "PC/SC Error SCardConnect", returnCode);
        return 0;
    }

    // store the cardHandle and the activeProtocol in the information record
    cInfo.cardHandle = cardHandle;
    cInfo.protocol = activeProtocol;

    // store the current context information
    if (setContextInformation(cInfo) != 0) {
        throwPcscException(env, obj, "SCardConnect", "PC/SC Wrapper Error: couldn't store context information record", 0);
        return 0;
    }

    return cardHandle;
}
Пример #14
0
int
Test_CardConnecting()
{
	int trycnt;
	long result;

	printf("==============================================================\n");
	printf("Part B : Card Connect/Disconnect\n");
	printf("==============================================================\n");
	trycnt = 0;
	printf("Testing");
	while(trycnt < 5)
	{
		trycnt++;
		printf("...");
#ifdef LINUX_OS
		fflush(stdout);
#endif
		result = SCardConnect(	 ScardContext,
							 ScardReaderState[CurrentReader].szReader,
							 SCARD_SHARE_EXCLUSIVE,
							 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
							 &ScardHandle[CurrentReader],
							 &ScardProtocol[CurrentReader]);

		if(result != SCARD_S_SUCCESS)
		{
			MyPrintf(strlen("Testing"), strlen("..."), trycnt * 2 - 1, "Failed\n");
			PRINTERR(("SCardConnect Fail : %08X\n", result));
			return FALSE;
		}
		
		printf("...");
#ifdef LINUX_OS
		fflush(stdout);
#endif
		result = SCardDisconnect(ScardHandle[CurrentReader],
										   SCARD_UNPOWER_CARD);

		if(result != SCARD_S_SUCCESS)
		{
			MyPrintf(strlen("Testing"), strlen("..."), trycnt * 2, "Failed\n");
			PRINTERR(("SCardDisconnect Fail : %08X\n", result));
			return FALSE;
		}
	}
	MyPrintf(strlen("Testing"), strlen("..."), trycnt * 2, "Passed\n");

	printf("\n                Part B Test Successfully\n\n");

	return TRUE;
}
Пример #15
0
static void smartcard_check_status (SCARDCONTEXT hContext,
		const char* pReader,
		SCARDHANDLE hCardHandle, /* Can be 0 on the first call */
		SCARDHANDLE* newCardHandle, /* The handle returned */
		DWORD* pdwState) {
	if (hCardHandle == 0) {
		DWORD dwAP;
		LONG result = SCardConnect(hContext, pReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCardHandle, &dwAP);
		if (SCARD_S_SUCCESS != result) {
			hCardHandle = 0;
			if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
				*pdwState = SCARD_ABSENT;
			}
			else {
				*pdwState = SCARD_UNKNOWN;
			}

			if (newCardHandle == NULL) {
				(void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
				hCardHandle = 0;
			}
			else {
				*newCardHandle = hCardHandle;
			}
		}
	}

	char szReader[200];
	DWORD cch = sizeof(szReader);
	BYTE bAttr[32];
	DWORD cByte = 32;
	LONG result = SCardStatus(hCardHandle, /* Unfortunately we can't use NULL here */ szReader, &cch, pdwState, NULL, (LPBYTE)&bAttr, &cByte);

	if (SCARD_S_SUCCESS != result) {
		if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
			*pdwState = SCARD_ABSENT;
		}
		else {
			*pdwState = SCARD_UNKNOWN;
		}
	}

	if (newCardHandle == NULL) {
		(void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
		hCardHandle = 0;
	}
	else {
		*newCardHandle = hCardHandle;
	}
}
Пример #16
0
long CardConnect(LPCSTR szReader,
  DWORD dwShareMode,
  DWORD dwPreferredProtocols,
  LPSCARDHANDLE phCard,
  LPDWORD pdwActiveProtocol)
{
	long lRet = SCardConnect(g_poPCSC->GetContext(), szReader,
			dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol);

	//printf("SCardConnect(sharemode=0x%0x, prefprotocols=0x%0x): r = 0x%0x (%d), protocol=0x%0x\n\n",
	//	dwShareMode, dwPreferredProtocols, lRet, lRet, * pdwActiveProtocol);

	return lRet;
}
Пример #17
0
/**********************************************************************************************
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 ;	

}
Пример #18
0
logicalaccess::PCSCConnection::PCSCConnection(PCSCShareMode mode,
                                              unsigned long protocol,
                                              SCARDCONTEXT context,
                                              const std::string &device)
    : handle_(0)
    , share_mode_(mode)
    , protocol_(protocol)
{
    LONG lReturn = SCardConnect(context, device.c_str(), mode, protocol,
                                &handle_, &active_protocol_);
    if (lReturn != SCARD_S_SUCCESS)
    {
        THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException,
                                 "Failed to establish PCSC connection: " +
                                     PCSCConnection::strerror(lReturn));
    }
}
Пример #19
0
static uint32 handle_Connect(IRP* irp, tbool wide)
{
	LONG rv;
	SCARDCONTEXT hContext;
	char *readerName = NULL;
	DWORD dwShareMode = 0;
	DWORD dwPreferredProtocol = 0;
	DWORD dwActiveProtocol = 0;
	SCARDHANDLE hCard;

	stream_seek(irp->input, 0x1c);
	stream_read_uint32(irp->input, dwShareMode);
	stream_read_uint32(irp->input, dwPreferredProtocol);

	sc_input_reader_name(irp, &readerName, wide);

	stream_seek(irp->input, 4);
	stream_read_uint32(irp->input, hContext);

	DEBUG_SCARD("(context: 0x%08x, share: 0x%08x, proto: 0x%08x, reader: \"%s\")",
		(unsigned) hContext, (unsigned) dwShareMode,
		(unsigned) dwPreferredProtocol, readerName ? readerName : "NULL");

	rv = SCardConnect(hContext, readerName, (DWORD) dwShareMode,
		(DWORD) dwPreferredProtocol, &hCard, (DWORD *) &dwActiveProtocol);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s 0x%08x", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success 0x%08x", (unsigned) hCard);

	stream_write_uint32(irp->output, 0x00000000);
	stream_write_uint32(irp->output, 0x00000000);
	stream_write_uint32(irp->output, 0x00000004);
	stream_write_uint32(irp->output, 0x016Cff34);
	stream_write_uint32(irp->output, dwActiveProtocol);
	stream_write_uint32(irp->output, 0x00000004);
	stream_write_uint32(irp->output, hCard);
	stream_seek(irp->output, 28);

	sc_output_alignment(irp, 8);

	xfree(readerName);
	return rv;
}
BOOL TestDesfire(SCARDCONTEXT hContext, const char *szReader)
{
  SCARDHANDLE hCard;
  DWORD dwProtocol;
  LONG rc;
  BOOL f;

  printf("Testing the Desfire library on this card...\n");

  /*
   * Connect to the card, accept either T=0 or T=1
   * ---------------------------------------------
   */
  rc = SCardConnect(hContext,
                    szReader,
                    SCARD_SHARE_SHARED,
                    SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1,
                    &hCard,
                    &dwProtocol);
	if (rc != SCARD_S_SUCCESS)
  {
    printf("\tSCardConnect error %08lX\n",rc);
		return FALSE;
  }

  printf("\tConnected to the card, protocol ");
  switch (dwProtocol)
  {
    case SCARD_PROTOCOL_T0 : printf("T=0"); break;
    case SCARD_PROTOCOL_T1 : printf("T=1"); break;
    default                : printf("%08lX", dwProtocol);
  }
  printf("\n");

  
  SCardDesfire_AttachLibrary(hCard);
  f = TestDesfire_Ex(hCard);
  SCardDesfire_DetachLibrary(hCard);

  SCardDisconnect(hCard, SCARD_EJECT_CARD);


  printf("\n\n\n");
  return f;
}
Пример #21
0
/* -------------------------------------------------------------------------- */
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 */
Пример #22
0
static VCardAppletPrivate *
passthru_new_applet_private(VReader *reader)
{
    VCardAppletPrivate *applet_private = NULL;
    LONG rv;

    applet_private = (VCardAppletPrivate *)malloc(sizeof(VCardAppletPrivate));

    if (applet_private == NULL) {
        goto fail;
    }
    applet_private->hCard = 0;
    applet_private->reader_name = NULL;

    applet_private->reader_name = passthru_get_reader_name(reader);
    if (applet_private->reader_name == NULL) {
        goto fail;
    }

    rv = SCardConnect( global_context, applet_private->reader_name,
       SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1,
        &applet_private->hCard,
        &applet_private->hProtocol);
    if (rv !=  SCARD_S_SUCCESS) {
        goto fail;
    }

    if (applet_private->hProtocol == SCARD_PROTOCOL_T0) {
        applet_private->send_io = SCARD_PCI_T0;
    } else {
        applet_private->send_io = SCARD_PCI_T1;
    }
    applet_private->atr_len = 0;
    return applet_private;

fail:
    if (applet_private) {
        passthru_delete_applet_private(applet_private);
    }
    return NULL;
}
Пример #23
0
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;
}
Пример #24
0
//
// FUNCTION NAME: SIM_Connect
//
// DESCRIPTION: this is a wrapper for pcsclite SCardConnect function.
//              Its job is to call that function and manage error messages
//              eventually returned.
// 
// INPUT PARAMETERS: 
//   SCARDCONTEXT  hContext    connection context to the PC/SC resource manager
//   LPCSTR        szReader    reader name to connect to
//
// OUTPUT PARAMETERS:  LPSCARDHANDLE
//   If nothing goes bad, returns a handler for this card connection, otherwise
//   exits.
//
// NOTES:
//   - Possible extension will require additional parameters to be chosen by
//     the caller.
//
SCARDHANDLE SIM_Connect(SCARDCONTEXT hContext, LPSTR szReader) {
  SCARDHANDLE hCard;
  DWORD dwActiveProtocol;
  LONG rv;

  rv = SCardConnect(hContext, szReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
  switch(rv) {
    case SCARD_E_NOT_READY: {
      bail(EXIT_FAILURE, "SIM_Connect:",ERR_PORT_NOT_READY);
    }
    case SCARD_E_INVALID_VALUE: {
      bail(EXIT_FAILURE, "SIM_Connect:",ERR_INVALID_PARAMETER_VALUE);
    }
    case SCARD_E_READER_UNAVAILABLE: {
      bail(EXIT_FAILURE, "SIM_Connect:",ERR_READER_UNAVAILABLE);
    }
    case SCARD_E_UNSUPPORTED_FEATURE: {
      bail(EXIT_FAILURE, "SIM_Connect:",ERR_PROTOCOL_UNAVAILABLE);
    }
    case SCARD_E_SHARING_VIOLATION: {
      bail(EXIT_FAILURE, "SIM_Connect:",ERR_SHARING_VIOLATION);
    }
    case SCARD_E_INVALID_HANDLE: {
      bail(EXIT_FAILURE, "SIM_Connect:",ERR_INVALID_CONTEXT_HANDLER);
    }
    case SCARD_S_SUCCESS: {
      printf("Connection with SIM card opened successfully.\n");
      return(hCard);
    }
    default: {
      int errno_saved = errno;
      printf("The card returned: %li.\n",rv);
      printf("Suggestion: maybe card name was mistyped.\n");
      bail_with_errno(EXIT_FAILURE, errno_saved, "SIM_Connect:",ERR_WRONG_RETURN_VALUE);
    }
  }
}
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")
	}
Пример #26
0
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);
		}
	}
Пример #27
0
int main(/*@unused@*/ int argc, /*@unused@*/ char **argv)
{
	SCARDHANDLE hCard;
	SCARDCONTEXT hContext;
	SCARD_READERSTATE_A rgReaderStates[1];
	DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
	DWORD dwPref, dwReaders = 0;
	char *pcReaders = 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];
	SCARD_IO_REQUEST pioRecvPci;
	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];

			printf("Enter the reader number\t\t: ");
			(void)fgets(input, sizeof(input), stdin);
			(void)sscanf(input, "%d", &iReader);

			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;
	}

	int bBreak = 0;

	while (1)
	{
		char inputCommand[1024];	
		char inputAPDU[1024];
		int inputAPDULen = sizeof(inputAPDU);
		printf("Enter APDU to send, (e.g. 00:A4:04:00:00)\n");
		printf("Command APDU: ");
		(void)fgets(inputCommand, sizeof(inputCommand), stdin);
		
		int stringlen = strlen(inputCommand);
		if( inputCommand[stringlen-1] == '\n' ) { inputCommand[stringlen-1] = 0; } //remove newline

		int bError = sc_hex_to_bin(inputCommand, inputAPDU, &inputAPDULen);
		//printf("debug - value bError: %i\n",bError);
		if (bError) { printf("Error parsing input\n\n"); continue; }

		send_length = inputAPDULen;
		if (inputAPDULen == 0) { break; }
		printf("debug inputAPDULen: %i\n",inputAPDULen); 
		memcpy(bSendBuffer, inputAPDU, send_length);
		length = sizeof(bRecvBuffer);

		printf("Testing SCardTransmit:\n "); printf("-> ");
		for (i=0; i<send_length; i++) { printf(" %02X", bSendBuffer[i]); }
		printf("\n");
		rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
			&pioRecvPci, bRecvBuffer, &length);
		test_rv(rv, hContext, PANIC);
		printf("<- " GREEN);
		for (i=0; i<length; i++)
			printf(" %02X", bRecvBuffer[i]);
		printf("\n" NORMAL);
	}

	testrun(&hCard, &hContext, &pioSendPci, 0);
	testrun(&hCard, &hContext, &pioSendPci, 1);
	testrun(&hCard, &hContext, &pioSendPci, 2);
	testrun(&hCard, &hContext, &pioSendPci, 3);

	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)
		printf("Vendor IFD version\t\t: " GREEN "0x%08lX\n" NORMAL,
			buf.as_DWORD);

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_MAXINPUT, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		if (dwBufLen == sizeof(uint32_t))
			printf("Max message length\t\t: " GREEN "%d\n" NORMAL,
				buf.as_uint32_t);
		else
			printf(RED "Wrong size" NORMAL);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_NAME, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
		printf("Vendor name\t\t\t: " GREEN "%s\n" NORMAL, buf.as_char);

	printf("Testing SCardSetAttrib\t\t: ");
	rv = SCardSetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPCBYTE)"", 1);
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardStatus\t\t: ");

#ifdef USE_AUTOALLOCATE
	dwReaderLen = SCARD_AUTOALLOCATE;
	dwAtrLen = SCARD_AUTOALLOCATE;
	rv = SCardStatus(hCard, (LPSTR)&pcReaders, &dwReaderLen, &dwState, &dwProt,
		(LPBYTE)&pbAtr, &dwAtrLen);
#else
	dwReaderLen = 100;
	pcReaders   = malloc(sizeof(char) * 100);
	dwAtrLen    = MAX_ATR_SIZE;

	rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt,
		pbAtr, &dwAtrLen);
#endif
	test_rv(rv, hContext, PANIC);

	printf("Current Reader Name\t\t: " GREEN "%s\n" NORMAL, pcReaders);
	printf("Current Reader State\t\t: " GREEN "0x%.4lx\n" NORMAL, dwState);
	printf("Current Reader Protocol\t\t: T=" GREEN "%ld\n" NORMAL, dwProt - 1);
	printf("Current Reader ATR Size\t\t: " GREEN "%ld" NORMAL " bytes\n",
		dwAtrLen);
	printf("Current Reader ATR Value\t: " GREEN);

	for (i = 0; i < dwAtrLen; i++)
	{
		printf("%02X ", pbAtr[i]);
	}
	printf(NORMAL "\n");

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pcReaders);
	test_rv(rv, hContext, PANIC);
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAtr);
	test_rv(rv, hContext, PANIC);
#else
	if (pcReaders)
		free(pcReaders);
#endif

	if (rv != SCARD_S_SUCCESS)
	{
		(void)SCardDisconnect(hCard, SCARD_RESET_CARD);
		(void)SCardReleaseContext(hContext);
	}

	printf("Press enter: ");
	(void)getchar();
	printf("Testing SCardReconnect\t\t: ");
	rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
		SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardDisconnect\t\t: ");
	rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
	test_rv(rv, hContext, PANIC);

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, mszReaders);
	test_rv(rv, hContext, PANIC);
#else
	free(mszReaders);
#endif

	printf("Testing SCardReleaseContext\t: ");
	rv = SCardReleaseContext(hContext);
	test_rv(rv, hContext, PANIC);

	printf("\n");
	printf("PC/SC Test Completed Successfully !\n");

	return 0;
}
Пример #28
0
/**
 * checkForNewPCSCToken looks into a specific slot for a token.
 *
 * @param slot       Pointer to slot structure.
 *
 * @return
 *                   <P><TABLE>
 *                   <TR><TD>Code</TD><TD>Meaning</TD></TR>
 *                   <TR>
 *                   <TD>CKR_OK                                 </TD>
 *                   <TD>Success                                </TD>
 *                   </TR>
 *                   <TR>
 *                   <TD>CKR_HOST_MEMORY                        </TD>
 *                   <TD>Error getting memory (malloc)          </TD>
 *                   </TR>
 *                   <TR>
 *                   <TD>CKR_GENERAL_ERROR                      </TD>
 *                   <TD>Error opening slot directory           </TD>
 *                   </TR>
 *                   </TABLE></P>
 */
static int checkForNewPCSCToken(struct p11Slot_t *slot)
{
	struct p11Token_t *ptoken;
	int rc, i;
	LONG rv;
	DWORD dwActiveProtocol;
	WORD feature;
	DWORD featurecode, lenr, atrlen,readernamelen,state,protocol;
	unsigned char buf[256];
	unsigned char atr[36];
	char *po;

	FUNC_CALLED();

	if (slot->closed) {
		FUNC_RETURNS(CKR_TOKEN_NOT_PRESENT);
	}

	rv = SCardConnect(slot->context, slot->readername, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &(slot->card), &dwActiveProtocol);

#ifdef DEBUG
	debug("SCardConnect (%i, %s): %s\n", slot->id, slot->readername, pcsc_error_to_string(rv));
#endif

	if (rv == SCARD_E_NO_SMARTCARD || rv == SCARD_W_REMOVED_CARD || rv == SCARD_E_SHARING_VIOLATION) {
		FUNC_RETURNS(CKR_TOKEN_NOT_PRESENT);
	}

	if (rv != SCARD_S_SUCCESS) {
		closeSlot(slot);
		FUNC_FAILS(CKR_DEVICE_ERROR, pcsc_error_to_string(rv));
	}

	if (!slot->hasFeatureVerifyPINDirect) {
		rv = SCardControl(slot->card, SCARD_CTL_CODE(3400), NULL,0, buf, sizeof(buf), &lenr);

#ifdef DEBUG
		debug("SCardControl (CM_IOCTL_GET_FEATURE_REQUEST): %s\n", pcsc_error_to_string(rv));
#endif

		/* Ignore the feature codes if an error occured */
		if (rv == SCARD_S_SUCCESS) {
			for (i = 0; i < lenr; i += 6) {
				feature = buf[i];
				featurecode = (buf[i + 2] << 24) + (buf[i + 3] << 16) + (buf[i + 4] << 8) + buf[i + 5];
	#ifdef DEBUG
				debug("%s - 0x%08X\n", pcsc_feature_to_string(feature), featurecode);
	#endif
				if (feature == FEATURE_VERIFY_PIN_DIRECT) {
					po = getenv("PKCS11_IGNORE_PINPAD");
	#ifdef DEBUG
					if (po) {
						debug("PKCS11_IGNORE_PINPAD=%s\n", po);
					} else {
						debug("PKCS11_IGNORE_PINPAD not found\n");
					}
	#endif
					if (!po || (*po == '0')) {
	#ifdef DEBUG
						debug("Slot supports feature VERIFY_PIN_DIRECT - setting CKF_PROTECTED_AUTHENTICATION_PATH for token\n");
	#endif
						slot->hasFeatureVerifyPINDirect = featurecode;
					}
				}
			}
		}
	}

	readernamelen = 0;
	atrlen = sizeof(atr);

	rc = SCardStatus(slot->card, NULL, &readernamelen, &state, &protocol, atr, &atrlen);

	if (rc != SCARD_S_SUCCESS) {
		closeSlot(slot);
		FUNC_FAILS(CKR_DEVICE_ERROR, pcsc_error_to_string(rc));
	}

	rc = newToken(slot, atr, atrlen, &ptoken);

	if (rc != CKR_OK) {
		FUNC_FAILS(rc, "newToken() failed");
	}

	FUNC_RETURNS(rc);
}
PCSCREADERDRIVERDLL_API unsigned short CCONV HD_OpenPort(short ivPortNo, const char* devicename, HANDLE* devNo)
{
	SCARDHANDLE	CardHandle=NULL;
//	unsigned long ActiveProtocol;

///////////////////////////////////////////////////////////////////////////////////////////
	//
	//	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 ;
	}


	unsigned char ResponseBuffer[4096];
	unsigned long ResponseLength;
	int StringLen,port;
	unsigned char ReaderNameTmp[255];

	int slen;

	//
	//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) 
	{
//		GetErrorCode(ret);
		DebugMessage(ret);
		return(CER_PCSC_SCardListReaders);
	}

	ret = SCardListReaders(ContextHandle, NULL, (char *)ResponseBuffer, &ResponseLength);
	if (ret != SCARD_S_SUCCESS) 
	{
//		GetErrorCode(ret);
		DebugMessage(ret);
		return(CER_PCSC_SCardListReaders);
	}

	StringLen = 0;
	
	if (ivPortNo>20)
	{
		port = ivPortNo-21;
	}
	else
	{
		port = ivPortNo-1;
	}

	//DecHstr( port, 1, strtmp );

	strcpy((char*)ReaderNameTmp,(char*)ResponseBuffer+StringLen);
	slen = strlen((char *)ReaderNameTmp);
	//如果不是指定的读卡器,

	if (memcmp((char *)ReaderNameTmp, (char*)devicename, slen) != 0)		
	{
		while (StringLen < ResponseLength) 
		{
			StringLen = StringLen+strlen((char*)ReaderNameTmp);
			StringLen = StringLen+1;
			strcpy((char*)ReaderNameTmp,(char*)ResponseBuffer+StringLen);
			if (memcmp((char *)ReaderNameTmp, (char*)devicename, slen) == 0)
				break;
		}
		DebugMessage(ERR_PCSC_READER_NOT_FOUND);
	}


		ret = SCardConnect(ContextHandle, (char *)ReaderNameTmp, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &CardHandle, &ActiveProtocol);
		//ActiveProtocol = SCARD_PROTOCOL_T0;
		if (ret != SCARD_S_SUCCESS)
		{
			
			DebugMessage(ret);
			if (CardHandle==NULL)
			{
				return CER_NOCARD;
			}
			return CER_PCSC_SCardConnect ;
		}

	*devNo =(HANDLE) CardHandle;
		
	return EXCUTE_SUC ;	

}
PCSCREADERDRIVERDLL_API unsigned short CCONV HD_GetReaderList(HANDLE ContextNo, int * ReaderNo, int * ReaderCount )
{
	SCARDHANDLE	CardHandle;
	unsigned char ResponseBuffer[4096];
	unsigned long ResponseLength;
	int i,j, StringLen;
	unsigned char ReaderNameTmp[255];

	//
	//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((SCARDCONTEXT)ContextNo, NULL, NULL, &ResponseLength);
	if (ret != SCARD_S_SUCCESS) 
	{
//		GetErrorCode(ret);
		DebugMessage(ret);
		return(CER_PCSC_SCardListReaders);
	}

	ret = SCardListReaders((SCARDCONTEXT)ContextNo, NULL, (char *)ResponseBuffer, &ResponseLength);
	if (ret != SCARD_S_SUCCESS) 
	{
//		GetErrorCode(ret);
		DebugMessage(ret);
		return(CER_PCSC_SCardListReaders);
	}

	j=0;
	ReaderID = 0;
	StringLen = 0;
	while ((unsigned long)StringLen<ResponseLength-1)
	{
		strcpy((char*)ReaderNameTmp,(char*)ResponseBuffer+StringLen);
		
		ret = SCardConnect((SCARDCONTEXT)ContextNo, (char *)ReaderNameTmp, SCARD_SHARE_DIRECT, 0, &CardHandle, &ActiveProtocol);
		if ((ret == SCARD_S_SUCCESS)||(ret == SCARD_W_REMOVED_CARD))
		{
			j++;
			ReaderStatus[j-1][0]=0;
			ReaderStatus[j-1][1]=0;
			SCardDisconnect(CardHandle, SCARD_EJECT_CARD);
		}
		StringLen = StringLen+strlen((char*)ReaderNameTmp);
		StringLen = StringLen+1;
	}

	*ReaderCount = j;
	ReaderID = j;

	for (i=0;i<j;i++)
		 ReaderNo[i] = i+1;
	
	return EXCUTE_SUC ;	

}