Exemple #1
0
static int testSCardGetAttrib(SCARDCONTEXT hContext, SCARDCONTEXT hCard)
{
	int           errCount = 0;
    BYTE          *attrib = NULL;
    DWORD         attribLen = SCARD_AUTOALLOCATE;

    int ret = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPBYTE)&attrib, &attribLen);
	CHECK_PCSC_RET("SCardGetAttrib()", ret);

    if (attribLen < 8)
	{
        printf("ERR: SCardGetAttrib(): ATR length looks too small (%d) for a BE eID card\n", (int) attribLen);
		errCount++;
	}
    else if (attrib[0] != 0x3B)
    {
        printf("ERR: SCardGetAttrib(): ATR should start with 0x3B (instead of 0x%0x) for a BE eID card\n", attrib[0]);
		errCount++;
    }

    ret = SCardFreeMemory(hContext, attrib);
	CHECK_PCSC_RET("SCardFreeMemory()", ret);

    return errCount;
}
Exemple #2
0
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;
}
Exemple #3
0
/* -------------------------------------------------------------------------  */
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 */
static UINT32 smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ListReaders_Call* call)
{
	UINT32 status;
	ListReaders_Return ret;
	LPWSTR mszReaders = NULL;
	DWORD cchReaders = 0;
	IRP* irp = operation->irp;

	cchReaders = SCARD_AUTOALLOCATE;

	status = ret.ReturnCode = SCardListReadersW(operation->hContext, (LPCWSTR) call->mszGroups, (LPWSTR) &mszReaders, &cchReaders);

	ret.msz = (BYTE*) mszReaders;
	ret.cBytes = cchReaders * 2;

	if (status != SCARD_S_SUCCESS)
		return status;

	smartcard_trace_list_readers_return(smartcard, &ret, TRUE);

	status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret);

	if (status != SCARD_S_SUCCESS)
		return status;

	if (mszReaders)
		SCardFreeMemory(operation->hContext, mszReaders);

	if (call->mszGroups)
		free(call->mszGroups);

	return ret.ReturnCode;
}
static DWORD smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Status_Call* call)
{
	LONG status;
	Status_Return ret;
	DWORD cchReaderLen = 0;
	LPWSTR mszReaderNames = NULL;
	IRP* irp = operation->irp;

	if (call->cbAtrLen > 32)
		call->cbAtrLen = 32;

	ret.cbAtrLen = call->cbAtrLen;
	ZeroMemory(ret.pbAtr, 32);

	cchReaderLen = SCARD_AUTOALLOCATE;

	status = ret.ReturnCode = SCardStatusW(operation->hCard, (LPWSTR) &mszReaderNames, &cchReaderLen,
			&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);

	ret.mszReaderNames = (BYTE*) mszReaderNames;
	ret.cBytes = cchReaderLen * 2;

	smartcard_trace_status_return(smartcard, &ret, TRUE);

	status = smartcard_pack_status_return(smartcard, irp->output, &ret);

	if (status != SCARD_S_SUCCESS)
		return status;

	if (mszReaderNames)
		SCardFreeMemory(operation->hContext, mszReaderNames);

	return ret.ReturnCode;
}
Exemple #6
0
bool CPCSCClass::ListReadernames(CComboBox* m_cblist)
{
	char *pReaderList = NULL;
	DWORD ReaderListSize = SCARD_AUTOALLOCATE;
	char *pch;

	if(m_cblist == NULL)
	{
		mylog.AddToLogs(m_logobj,"error: NULL combobox class");
		return false;
	}
	
	//save the combobox to class
	m_cbListObj = m_cblist;

	m_cblist->ResetContent();

	RetCode = SCardListReadersA(
		hContext,
		NULL,
		(LPSTR)&pReaderList,
		&ReaderListSize);

	if (RetCode != SCARD_S_SUCCESS)
	{
		mylog.AddToLogs(m_logobj,"error: SCardListReaders Failed");
		mylog.AddToLogs(m_logobj,TranslatePCSCError());
		return false;

	}
	else
	{
		mylog.AddToLogs(m_logobj,"SCardListReaders Success");
		
	}

	pch = pReaderList;

	while (*pch != 0)
	{
		m_cblist->AddString (pch);
		pch += strlen (pch) + 1;
	}
	m_cblist->SetCurSel(0);


	RetCode = SCardFreeMemory( hContext, pReaderList );
	if (RetCode != SCARD_S_SUCCESS)
	{
		mylog.AddToLogs(m_logobj,"error: SCardFreeMemory Failed");
	}

	return true;
}
Exemple #7
0
static int testListReadersW(SCARDCONTEXT hContext)
{
	int errCount = 0;

    wchar_t staticBuf[2000];
    DWORD staticLen = (DWORD) (sizeof(staticBuf) / sizeof(wchar_t));
    long ret = SCardListReadersW(hContext, NULL, staticBuf, &staticLen);
	CHECK_PCSC_RET("SCardListReadersW(1)", ret);

    wchar_t *dynBuf = NULL;
    DWORD dynLen = 0;
    ret = SCardListReadersW(hContext, NULL, dynBuf, &dynLen);
	CHECK_PCSC_RET("SCardListReadersW(2)", ret);

    dynBuf = (wchar_t *) malloc(dynLen * sizeof(wchar_t));
    ret = SCardListReadersW(hContext, NULL, dynBuf, &dynLen);
	CHECK_PCSC_RET("SCardListReadersW(3)", ret);

    wchar_t *autoBuf = NULL;
    DWORD autoLen = SCARD_AUTOALLOCATE;
    ret = SCardListReadersW(hContext, NULL, (wchar_t*) &autoBuf, &autoLen);
	CHECK_PCSC_RET("SCardListReadersW(4)", ret);

    wchar_t *auto2Buf = NULL;
    DWORD auto2Len = SCARD_AUTOALLOCATE;
    ret = SCardListReadersW(hContext, NULL, (wchar_t*) &auto2Buf, &auto2Len);
	CHECK_PCSC_RET("SCardListReadersW(5)", ret);

    if (staticLen != dynLen || dynLen != autoLen || dynLen != auto2Len)
    {
		printf("ERR: SCardListReadersW() returned buffers lengths of different size\n");
        printf("  (staticLen = %d, dynLen = %d, autoLen = %d, auto2Len = %d\n", staticLen, dynLen, autoLen, auto2Len);
        errCount++;
    }
    else if (memcmp(staticBuf, dynBuf, dynLen) != 0 || memcmp(dynBuf, autoBuf, dynLen) != 0 ||
        memcmp(dynBuf, auto2Buf, dynLen) != 0)
    {
		printf("ERR: SCardListReadersW() returned different data\n");
        dump("  staticBuf = '%S'\n", staticBuf, dynLen);
        dump("  dynBuf = '%S'\n", dynBuf, dynLen);
        dump("  autoBuf = '%S'\n", autoBuf, dynLen);
        dump("  auto2Buf = '%S'\n", auto2Buf, dynLen);
        errCount++;
    }

    free(dynBuf);

    ret = SCardFreeMemory(hContext, autoBuf);
	CHECK_PCSC_RET("SCardFreeMemory()", ret);

    return errCount;
}
void SmartCardReader::listAllReaders( )
{

    LPTSTR          pmszReaders = NULL;
    LPTSTR          pReader;
    LONG            lReturn, lReturn2;
    DWORD           cch = SCARD_AUTOALLOCATE;

    // Retrieve the list the readers.
    // hSC was set by a previous call to SCardEstablishContext.
    lReturn = SCardListReaders( context,
                                NULL,
                                (LPTSTR)&pmszReaders,
                                &cch );

    if( retCode != SCARD_S_SUCCESS )
    {
        ofLogError( "SmartCardReader::setup() FAILED TO LIST ALL READERS" ) << getSCardErrorMessage( retCode ) ;
        return;
    }
    else
    {
        // Do something with the multi string of readers.
        // Output the values.
        // A double-null terminates the list of values.
        pReader = pmszReaders;
        while ( '\0' != *pReader )
        {
            // Display the value.
            printf("Reader: %S\n", pReader );
            // Advance to the next value.
            pReader = pReader + wcslen((wchar_t *)pReader) + 1;
        }
        // Free the memory.
        lReturn2 = SCardFreeMemory( context ,
                                    pmszReaders );
        if ( SCARD_S_SUCCESS != lReturn2 )
            printf("Failed SCardFreeMemory\n");
    }

    if( readerName == NULL )
    {

        ofLogError( "READER NAME IS INVALID" ) << getSCardErrorMessage( retCode ) ;
        return;
    }
}
Exemple #9
0
/* -------------------------------------------------------------------------- */
LONG sc_done (sc_context *ctx, DWORD lvSt)
{
  LONG rc=SCARD_S_SUCCESS;
  register BYTE i=0xFF;

  rc=SCardDisconnect(ctx->hCard, lvSt); /* SCARD_LEAVE_CARD); */
  if (rc==SCARD_S_SUCCESS)
  {
    if (ctx->rdr != NULL) SCardFreeMemory( ctx->hCtx, ctx->rdr);
    ctx->rdrsz=0; ctx->rdr = NULL;
    rc=SCardReleaseContext(ctx->hCtx);
  }
  while(i-- > 0) ctx->sw[i]=0;
  ctx->rw = 0;

  return rc;
} /* sc_finish */
Exemple #10
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 */
Exemple #11
0
static int testListReadersA(SCARDCONTEXT hContext)
{
	int errCount = 0;

    char staticBuf[2000];
    DWORD staticLen = (DWORD) sizeof(staticBuf);
    long ret = SCardListReadersA(hContext, NULL, staticBuf, &staticLen);
    CHECK_PCSC_RET("SCardListReadersA(1)", ret);

    char *dynBuf = NULL;
    DWORD dynLen = 0;
    ret = SCardListReadersA(hContext, NULL, dynBuf, &dynLen);
    CHECK_PCSC_RET("SCardListReadersA(2)", ret);
    dynBuf = (char *) malloc(dynLen);
    ret = SCardListReadersA(hContext, NULL, dynBuf, &dynLen);
    CHECK_PCSC_RET("SCardListReadersA(1)", ret);

#ifndef MAC_OS_X
    char *autoBuf = NULL;
    DWORD autoLen = SCARD_AUTOALLOCATE;
    ret = SCardListReadersA(hContext, NULL, (char*) &autoBuf, &autoLen);
    CHECK_PCSC_RET("SCardListReadersA(3)", ret);

    if (staticLen != dynLen || dynLen != autoLen)
    {
		printf("ERR: SCardListReadersA() returned buffers lengths of different size\n");
        errCount++;
    }
    else if (memcmp(staticBuf, dynBuf, dynLen) != 0 || memcmp(dynBuf, autoBuf, dynLen) != 0)
    {
		printf("ERR: SCardListReadersA() returned different data\n");
        errCount++;
    }

    ret = SCardFreeMemory(hContext, autoBuf);
    CHECK_PCSC_RET("SCardFreeMemory()", ret);
#endif

    free(dynBuf);

    return errCount;
}
Exemple #12
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;
}
Exemple #13
0
int main(int argc, char *argv[])
{
	int Index = 0;
	int Arg = 1;
	char *VirtualCard = NULL;
	BCAS::Manager::Abstract *Card;

	argc--;
	while (argc > 0) {
		if (strcmp(argv[Arg], "-virtual") == 0) {
			if (argc == 1) {
				printf("Missing file parameter.\n");
				return 1;
			}	
			VirtualCard = _strdup(argv[++Arg]);
			argc--;
		} else if (strcmp(argv[Arg], "-reader") == 0) {
			if (argc == 1) {
				printf("Missing file parameter.\n");
				return 1;
			}
			Index = atoi(argv[++Arg]);
			argc--;
		} else if (strcmp(argv[Arg], "-list") == 0) {
			Index = -1;
		} else {
			printf("Invalid parameter: %s\n", argv[Arg]);
			return 1;
		}
		Arg++;
		argc--;
	}

	if (VirtualCard == NULL) {
		SCARDCONTEXT Ctx;
		LONG Result;
		char *Reader = NULL;

		Result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &Ctx);

		if (Result != SCARD_S_SUCCESS) {
			printf("Failed to establish context, error: %08x\n", Result);
			return 1;
		}

		DWORD Count = SCARD_AUTOALLOCATE;
		LPTSTR Readers = NULL;

		Result = SCardListReaders(Ctx, NULL, (LPTSTR)&Readers, &Count);
		if (Result != SCARD_S_SUCCESS) {
			if (Result == SCARD_E_NO_READERS_AVAILABLE)
				printf("No card readers available.\n");
			else
				printf("Failed to list card readers, error: %08x\n", Result);
			SCardReleaseContext(Ctx);
			return 1;
		}

		LPTSTR R = Readers;
		Count = 0;
		while (*R != 0) {
			if (Index == Count) {
				Reader = _strdup(R);
				break;
			} else if (Index == -1) {
				printf("Reader %d: %s\n", Count, R);
			}
			R += strlen(R) + 1;
			Count++;
		}
		SCardFreeMemory(Ctx, Readers);

		if (Reader == NULL) {
			if (Index != -1)
				printf("Cannot find a reader at index %d\n", Index);
			SCardReleaseContext(Ctx);
			return 1;
		}
		BCAS::Manager::Card *RealCard = new BCAS::Manager::Card;
		RealCard->SetReader(Reader);
		Card = RealCard;
	} else {
		BCAS::Manager::Virtual *Dump = new BCAS::Manager::Virtual;
		Dump->SetReader(VirtualCard);
		Card = Dump;
	}

	BCAS::Keys::RegisterAll();

	Card->Init();
	BCAS::Manager::Ops *Ops = new BCAS::Manager::Ops;
	Ops->SetCard(Card);

	BCAS::Manager::Manager *Mgr = new BCAS::Manager::Manager(Ops);

	bool Quit = false;
	u16 Date;
	SYSTEMTIME Time;

	GetSystemTime(&Time);
	Date = ConvertDateToMJD(Time.wYear, Time.wMonth & 0xff, Time.wDay & 0xff) + 7;

	while (!Quit) {
		bool NewCard = false;
		bool HasCard;
		u16 Expiry;

		HasCard = Card->WaitForEvent(NewCard);
		if (NewCard == true) {
			Mgr->PrintCardInformation(CardType);
			if (CardType == kType_INVALID)
				break;
			PrintMenu();
			continue;
		}
		if (HasCard == false) {
			if (_kbhit()) {
				int Selection = _getch();
				if (Selection == 27) {
					break;
				}
				if (Selection == 0)
					_getch();
			}
			continue;
		}

		int Key = _getch();
		switch (Key) {
		case 27:
				Quit = true;
				break;

		case 0:
			Key = _getch();
			switch (Key) {
			case 59:
				Mgr->DumpMode();
				break;
			case 60:
				Mgr->PrintEntitlements();
				break;
			case 61:
				Mgr->PrintEmail();
				break;
			case 62:
				DateState = (DateState + 1) % 7;
				switch (DateState) {
				case 0:
					Expiry = 7;
					break;
				case 1:
					Expiry = 15;
					break;
				case 2:
					Expiry = 30;
					break;
				case 3:
					Expiry = 90;
					break;
				case 4:
					Expiry = 180;
					break;
				case 5:
					Expiry = 365 * 2;
					break;
				case 6:
					break;
				}
				if (DateState != 6) {
					GetSystemTime(&Time);
					Date = ConvertDateToMJD(Time.wYear, Time.wMonth & 0xff, Time.wDay & 0xff) + Expiry;
				} else {
					Date = 0xffff;
				}
				break;

			default:
				printf("%d\n", Key);
				break;
			}
			break;

		// UpdateTiers
		case 49:
			Mgr->AddEntitlement(BCAS::Keys::KEYSET_WOWOW, Date);
			break;
		case 50:
			Mgr->AddEntitlement(BCAS::Keys::KEYSET_STARCHANNELHD, Date);
			break;
		case 51:
			Mgr->AddEntitlement(BCAS::Keys::KEYSET_E2_110CS, Date);
			break;
		case 52:
			Mgr->AddEntitlement(BCAS::Keys::KEYSET_SAFETYNET, Date);
			break;
		case 53:
			Mgr->AddEntitlement(BCAS::Keys::KEYSET_NHK, Date);
			break;

		// InvalidateTiers
		case 113:
			Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_WOWOW);
			break;
		case 119:
			Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_STARCHANNELHD);
			break;
		case 101:
			Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_E2_110CS);
			break;
		case 114:
			Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_SAFETYNET);
			break;
		case 116:
			Mgr->InvalidateEntitlement(BCAS::Keys::KEYSET_NHK);
			break;

		// DeleteEmail
		case 97:
			Mgr->DeleteEmail(BCAS::Keys::KEYSET_WOWOW);
			break;
		case 115:
			Mgr->DeleteEmail(BCAS::Keys::KEYSET_STARCHANNELHD);
			break;
		case 100:
			Mgr->DeleteEmail(BCAS::Keys::KEYSET_E2_110CS);
			break;
		case 102:
			Mgr->DeleteEmail(BCAS::Keys::KEYSET_SAFETYNET);
			break;
		case 103:
			Mgr->DeleteEmail(BCAS::Keys::KEYSET_NHK);
			break;
		case 104:
			Mgr->DeleteEmail(BCAS::Keys::KEYSET_EMAIL);
			break;

		// ActivateTrial
		case 122:
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_WOWOW, false, Date);
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_WOWOW, true, Date);
			break;
		case 120:
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_STARCHANNELHD, false, Date);
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_STARCHANNELHD, true, Date);
			break;
		case 99:
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_E2_110CS, false, Date);
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_E2_110CS, true, Date);
			break;
		case 118:
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_SAFETYNET, false, Date);
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_SAFETYNET, true, Date);
			break;
		case 98:
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_NHK, false, Date);
			Mgr->ActivateTrial(BCAS::Keys::KEYSET_NHK, true, Date);
			break;

		default:
			printf("%d\n", Key);
			break;
		}

		if (!Quit)
			PrintMenu();
	}

	return 0;
}
BOOL ProcessCardAtr(SCARDCONTEXT hContext, BYTE atr[], DWORD atrlen)
{
  LONG lReturn = NO_ERROR;
  DWORD dwActiveProtocol = 0;
  DWORD cbAtr = MAX_ATR_LEN;
  DWORD dwIndex = 0;
  DWORD cchCards;
  char *pmszCards = NULL;
	BYTE name[MAX_PATH];
	LONG rc;
  BOOL success = TRUE;


  /* Determine if the ATR is already in the Smart Card Database */
  cchCards = SCARD_AUTOALLOCATE;
  rc = SCardListCards(hContext,
                      atr,
                      NULL,
											0,
											(char *) &pmszCards,
											&cchCards);
  if (rc != SCARD_S_SUCCESS)
  {
	  printf("SCardListCards error 0x%08lX (%lu).\n", rc, rc);
		return FALSE;
  }

	if ((pmszCards == NULL) || (*pmszCards == 0))
  {
    /* Card not found. We need to add it. */
    printf("\tThis card is currently not recognized by the system.\n");

		if (!Confirm("Do you want to add this card to the 'no driver' list ?"))
			return TRUE;

		printf("\tAdding card's ATR...\n");


    sprintf(name, "%s-", name_prefix);
		if (!ComputeCardNameFromAtr(&name[strlen(name)], atr, NULL, atrlen))
		{
      printf("Failed to compute a name for the card.\n");
			return FALSE;
		}

    success = IntroduceCardAtr(hContext, atr, NULL, atrlen, name);
		if (success)
		  printf("\tOK!\n");

  } else
  {
    printf("\tThis card is already known by the system.\n");
		printf("\t(%s)\n", pmszCards);
  }

  // Free resources
  if (pmszCards != NULL)
  {
    SCardFreeMemory(hContext, pmszCards);
  }

  return success;
}
int main(int argc, char **argv)
{
  SCARDCONTEXT      hContext;
  SCARD_READERSTATE rgscState[MAXIMUM_SMARTCARD_READERS];

  DWORD             dwReaders, dwReadersOld = 0;

  LPSTR  szReaders = NULL;
  DWORD  dwReadersSz;

  BOOL   first_run = TRUE;
  DWORD  i, j;
  LONG   rc;
  
  if ((argc >= 2) && (!strcmp(argv[1], "-m")))
    gbChangeMasterKey = TRUE;

  /*
   * Welcome message, check parameters
   * ---------------------------------
   */
  printf("SpringCard SDK for PC/SC (CSB6 family)\n");
  printf("\n");
  printf("NXP DESFIRE EV0 reference demo\n");
  printf("------------------------------\n");
  printf("www.springcard.com\n\n");
  printf("\n");
  printf("Press <Ctrl+C> to exit\n\n");

  /*
   * Get a handle to the PC/SC resource manager
   * ------------------------------------------
   */
  rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
  if(rc != SCARD_S_SUCCESS)
  {
    printf("SCardEstablishContext :%08lX\n",rc);
	  return EXIT_FAILURE;
  }

  /*
   * Infinite loop, we'll exit only when killed by Ctrl+C
   * ----------------------------------------------------
   */
  for (;;)
  {
    /*
     * Get the list of available readers
  	 */

    dwReadersSz = SCARD_AUTOALLOCATE;
	  rc = SCardListReaders(hContext,
                            NULL,                /* Any group */
                            (LPTSTR) &szReaders, /* Diabolic cast for buffer auto-allocation */
                            &dwReadersSz);       /* Beg for auto-allocation */
	  
	if (rc == SCARD_E_NO_READERS_AVAILABLE)
	{
	  /* No reader at all */
	  dwReaders = 0;
	} else if (rc != SCARD_S_SUCCESS)
	{
      printf("SCardListReaders error %08lX\n",rc);
	  break;
	} else
	{
	  /* Track events on found readers. */
	  LPTSTR pReader = szReaders;

	  for (dwReaders=0; dwReaders<MAXIMUM_SMARTCARD_READERS; dwReaders++)
	  {
        /* End of multi-string array */
		if (*pReader == '\0') break;

        /* Remember this reader's name */
		rgscState[dwReaders].szReader = pReader;

        /* Jump to next entry in multi-string array */
		pReader += strlen(pReader) + 1;
	  }
	}

	if (first_run)
    {
      /* Program startup, display the number of readers */
      if (dwReaders == 0)
      {
        printf("No PC/SC reader\n\n");
      } else
      {
        printf("%lu PC/SC reader%s found\n\n", dwReaders, dwReaders ? "s" : "");
      }
    }
      
	if (dwReadersOld != dwReaders)
	{
	  /* Reader added, or reader removed           */
      /* (re)set the initial state for all readers */
	  for (i=0; i<dwReaders; i++)
		rgscState[i].dwCurrentState = SCARD_STATE_UNAWARE;

      if (!first_run)
	  {
        int c;

	    /* Not the program startup, explain the event */
	    if (dwReadersOld > dwReaders)
		{
          c = (int) dwReadersOld-dwReaders;
		  printf("%d reader%s ha%s been removed from the system\n\n", c, (c==1)?" ":"s", (c==1)?"s":"ve");
		} else
		{
          c = (int) dwReaders-dwReadersOld;
		  printf("%d reader%s ha%s been added to the system\n\n", c, (c==1)?" ":"s", (c==1)?"s":"ve");
		}
	  }

      dwReadersOld = dwReaders;
	}

    if (dwReaders == 0)
    {
      /* We must wait here, because the SCardGetStatusChange doesn't wait  */
      /* at all in case there's no reader in the system. Silly, isn't it ? */
#ifdef WIN32
      Sleep(1000);
#endif
#ifdef __linux__
      sleep(1);
#endif
    }

	/*
     * Interesting part of the job : call SCardGetStatusChange to monitor all changes
     * taking place in the PC/SC reader(s)
     */
	
	rc = SCardGetStatusChange(hContext, INFINITE, rgscState, dwReaders);	
		
	if (rc != SCARD_S_SUCCESS)
    {
      printf("SCardGetStatusChange error %08lX\n",rc);
      break;
    }

	for (i=0; i<dwReaders; i++)
	{
	  BOOL just_inserted = FALSE;

      if (rgscState[i].dwEventState & SCARD_STATE_CHANGED)
	  {
        /* Something changed since last loop        */
        if ( (rgscState[i].dwEventState & SCARD_STATE_PRESENT)
         && !(rgscState[i].dwCurrentState & SCARD_STATE_PRESENT) )
          just_inserted = TRUE;

        /* Remember new current state for next loop */
        rgscState[i].dwCurrentState = rgscState[i].dwEventState;
	  } else
	  {
        /* Nothing new, don't display anything for this reader */
        /* (unless we're in the first run)                     */
        if (!first_run)
          continue;
	  }

      /*
       * Display current reader's state
       * ------------------------------
       */

	    /* Reader's name */
      printf("Reader %lu: %s\n", i, rgscState[i].szReader);

      /* Complete status */
      printf("\tCard state:\n");

      if (rgscState[i].dwEventState & SCARD_STATE_IGNORE)
        printf("\t\tIgnore this reader\n");

      if (rgscState[i].dwEventState & SCARD_STATE_UNKNOWN)
        printf("\t\tReader unknown\n");

      if (rgscState[i].dwEventState & SCARD_STATE_UNAVAILABLE)
        printf("\t\tStatus unavailable\n");

      if (rgscState[i].dwEventState & SCARD_STATE_EMPTY)
        printf("\t\tNo card in the reader\n");

      if (rgscState[i].dwEventState & SCARD_STATE_PRESENT)
        printf("\t\tCard present\n");

      if (rgscState[i].dwEventState & SCARD_STATE_ATRMATCH)
        printf("\t\tATR match\n");
  
      if (rgscState[i].dwEventState & SCARD_STATE_EXCLUSIVE)
        printf("\t\tReader reserved for exclusive use\n");

      if (rgscState[i].dwEventState & SCARD_STATE_INUSE)
        printf("\t\tReader/card in use\n");

      if (rgscState[i].dwEventState & SCARD_STATE_MUTE)
        printf("\t\tCard mute\n");

      if (just_inserted)
	  {
        /*
         * Display card's ATR
         * ------------------
         */

        if (rgscState[i].cbAtr)
		{
	      printf("\tCard ATR:");
		  for (j=0; j<rgscState[i].cbAtr; j++)
            printf(" %02X", rgscState[i].rgbAtr[j]);
          printf("\n");
		}

       /*
        * Do the Desfire library test on this card
        * ----------------------------------------
        */
        TestDesfire(hContext, rgscState[i].szReader);
	  }
	}

    /* Free the list of readers  */
    if (szReaders != NULL)
    {
      SCardFreeMemory(hContext, szReaders);
      szReaders = NULL;
    }
      
    /* Not the first run anymore */
		first_run = FALSE;
	}


  rc = SCardReleaseContext(hContext);

  /* Never go here (Ctrl+C kill us before !) */
  return EXIT_FAILURE;
}
Exemple #16
0
BOOL PCSC_IccConnect (MRTD_CTX_ST * ctx, const char *pcsc_reader)
{
  LONG rc;
  char *reader_name = NULL;
  char *reader_list = NULL;
  DWORD reader_list_sz;
  int reader_sel = -1;

  if (ctx == NULL)
    return FALSE;

#ifdef WIN32
  if (LoadLibrary("winscard.dll") == NULL)
  {
    MrtdSetLastError(ctx, MRTD_E_READER_NOT_AVAIL);
    return FALSE;
  }
#endif

  /* Try to understand the pcsc_reader name */
  if (pcsc_reader == NULL)
  {
    reader_sel = 0;
  } else
  if ((strlen (pcsc_reader) == 2) && (pcsc_reader[0] == '#'))
  {
    reader_sel = atoi (&pcsc_reader[1]);
  }

  /* Create the PC/SC context */
  if (ctx->reader.pcsc.hcard)
  {
    SCardDisconnect (ctx->reader.pcsc.hcard, SCARD_LEAVE_CARD);
    ctx->reader.pcsc.hcard = 0;
  }

  if (ctx->reader.pcsc.hcontext)
  {
    SCardReleaseContext (ctx->reader.pcsc.hcontext);
    ctx->reader.pcsc.hcontext = 0;
  }

  rc = SCardEstablishContext (SCARD_SCOPE_USER, NULL, NULL, &ctx->reader.pcsc.hcontext);
  if (rc != SCARD_S_SUCCESS)
  {
    MrtdVerbose("PC/SC error %08lX", rc);
    MrtdSetLastError (ctx, MRTD_E_READER_NOT_FOUND);
    return FALSE;
  }

  /* Retrieve list of readers */
  reader_list_sz = SCARD_AUTOALLOCATE;

  rc = SCardListReaders (ctx->reader.pcsc.hcontext, NULL, (char *) &reader_list, &reader_list_sz);
  if (rc != SCARD_S_SUCCESS)
  {
    MrtdVerbose("SCardListReaders : PC/SC error %08lX", rc);
    MrtdSetLastError (ctx, MRTD_E_READER_NOT_FOUND);
    return FALSE;
  }

  /* Loop inside the list */
  if (reader_list != NULL)
  {
    char *p = reader_list;

    while (strlen (p))
    {
      if (reader_sel < 0)
      {
        /* We must compare the names */
        if (!strcmp (p, pcsc_reader))
        {
          /* This one is OK ! */
          reader_name = p;
          break;
        }
      } else if (reader_sel == 0)
      {
        /* We shall take this one */
        reader_name = p;
        break;
      } else
      {
        /* Decrement... */
        reader_sel--;
      }
      p += strlen (p) + 1;
    }
  }

  /* A reader has been selected ? */
  if (reader_name == NULL)
  {
    SCardFreeMemory (ctx->reader.pcsc.hcontext, reader_list);
    MrtdSetLastError (ctx, MRTD_E_READER_NOT_FOUND);
    return FALSE;
  }

  MrtdVerbose("Connected to PC/SC reader \"%s\"", reader_name);

  /* Try to connect to the card in the reader */
  rc = SCardConnect (ctx->reader.pcsc.hcontext, reader_name, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &ctx->reader.pcsc.hcard, &ctx->reader.pcsc.protocol);
  SCardFreeMemory (ctx->reader.pcsc.hcontext, reader_list);

  if (rc != SCARD_S_SUCCESS)
  {
    MrtdVerbose("SCardConnect : PC/SC error %08lX", rc);
    MrtdSetLastError (ctx, MRTD_E_NO_CARD);
    return FALSE;
  }

  if (ctx->reader.pcsc.protocol == SCARD_PROTOCOL_T0)
  {
    MrtdVerbose("Connected to a T=0 card");
  } else
  if (ctx->reader.pcsc.protocol == SCARD_PROTOCOL_T1)
  {
    MrtdVerbose("Connected to a T=1 card");
  }

  /* We are connected to the card */
  ctx->pcsc_reader = TRUE;
  ctx->sprox_reader = FALSE;
  return TRUE;
}
Exemple #17
0
void PCSCResourceManager::run()
{
    SCARDCONTEXT context;
    LONG rv;

    while (true)
    {
        rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &context);

        if (rv == SCARD_S_SUCCESS)
        {
            DWORD readerNum = SCARD_AUTOALLOCATE;
            LPSTR readerNames = NULL;

            do
            {
                rv = SCardListReaders(context, NULL, (LPSTR) &readerNames, &readerNum);

                if (rv == SCARD_S_SUCCESS)
                {
                    for (LPCSTR pch = readerNames; *pch != '\0'; pch += strlen(pch) + 1)
                    {
                        int i;
                        for (i = 0; i < m_availabeReaders.size(); i++)
                            if (0 == strcmp(m_availabeReaders[i]->name(), pch))
                                break;

                        if (i == m_availabeReaders.size())
                        {
                                SCardReader *reader = new SCardReader(pch);
                                m_availabeReaders.append(reader);
                                connect(reader, SIGNAL(unavailable(LPCSTR)), SLOT(clearUnavailabeReader(LPCSTR)));
                                reader->start();

                                emit readerPluged(reader);
                        }
                    }

                    (void) SCardFreeMemory(context, readerNames);
                }
                else
                    std::cout << pcsc_stringify_error(rv) << std::endl;

                if (rv == SCARD_S_SUCCESS || rv == SCARD_E_NO_READERS_AVAILABLE)
                {
                    SCARD_READERSTATE readerStates;

                    readerStates.szReader = "\\\\?PnP?\\Notification";
                    readerStates.dwCurrentState = SCARD_STATE_UNAWARE;

                    rv = SCardGetStatusChange(context, INFINITE, &readerStates, 1);

                    if (rv != SCARD_E_TIMEOUT || rv != SCARD_S_SUCCESS)
                    {
                        (void) SCardReleaseContext(context);
                        break;
                    }
                }
                else
                {
                    (void) SCardReleaseContext(context);
                    break;
                }
            } while (true);
        }
        else
        {
            std::cout << pcsc_stringify_error(rv) << std::endl;
            QThread::sleep(PCSC_ERROR_BREAK_TIME);
        }
    }
}
Exemple #18
0
						printf("response: ");
						for(i=0; i<dwRecvLength; i++){
							printf("%02X ", pbRecvBuffer[i]);
						}
						printf("\n");
					}
				}
			}
		}
	}
//						printf("j:%d",j);
}
rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
CHECK("SCardDisconnect", rv)

#ifdef SCARD_AUTOALLOCATE
 rv = SCardFreeMemory(hContext, mszReaders);
 CHECK("SCardFreeMemory", rv)

#else
 free(mszReaders);
#endif

 rv = SCardReleaseContext(hContext);

 CHECK("SCardReleaseContext", rv)

 return 0;
}

BOOL MonitorReaders(SCARDCONTEXT hContext)
{
  DWORD  dwReaders, dwReadersOld = 0;
  SCARD_READERSTATE *rgscState;
	LPSTR  szReaders = NULL;
  DWORD  dwReadersSz; 
  DWORD  maxReaders;
	BOOL   bFirstRun = TRUE;
  DWORD  i, j;
	LONG   rc;

  /* Constant MAXIMUM_SMARTCARD_READERS is only 10 in Windows SDK */
  /* This is not enough for most of our tests. 64 sounds good...  */
  maxReaders = MAXIMUM_SMARTCARD_READERS;
  if (maxReaders<64) maxReaders = 64;

  rgscState = calloc(maxReaders, sizeof(SCARD_READERSTATE));
  if (rgscState == NULL)
  {
    printf("Out of memory\n");
    return FALSE;
  }

	for (;;)
	{
  	/* Get the list of available readers */
    dwReadersSz = SCARD_AUTOALLOCATE;
		rc = SCardListReaders(hContext,
                          NULL,                /* Any group */
                          (LPTSTR) &szReaders, /* Diabolic cast for buffer auto-allocation */
                          &dwReadersSz);       /* Beg for auto-allocation */
	  
		if (rc == SCARD_E_NO_READERS_AVAILABLE)
		{
		  /* No reader at all */
			dwReaders = 0;
		} else
    if (rc != SCARD_S_SUCCESS)
		{
      printf("SCardListReaders error 0x%08lX (%lu).\n", rc, rc);
			break;
		} else
		{
			/* Track events on found readers. */
			LPTSTR pReader = szReaders;

			for (dwReaders=0; dwReaders<maxReaders; dwReaders++)
			{
        /* End of multi-string array */
				if (*pReader == '\0')
					break;

        /* Remember this reader's name */
				rgscState[dwReaders].szReader = pReader;

        /* Jump to next entry in multi-string array */
				pReader += strlen(pReader) + 1;
			}
		}

		if (bFirstRun)
    {
      /* Program startup, display the number of readers */
      if (dwReaders == 0)
      {
        printf("No PC/SC reader\n\n");
      } else
      {
        printf("%ld PC/SC reader%s found\n\n", dwReaders, dwReaders ? "s" : "");
      }
    }
      
		if (dwReadersOld != dwReaders)
		{
			/* Reader added, or reader removed           */
      /* (re)set the initial state for all readers */
			for (i=0; i<dwReaders; i++)
				rgscState[i].dwCurrentState = SCARD_STATE_UNAWARE;

      if (!bFirstRun)
      {
        int c;

        /* Not the program startup, explain the event */
				if (dwReadersOld > dwReaders)
				{
          c = (int) dwReadersOld-dwReaders;
					printf("%d reader%s ha%s been removed from the system\n\n", c, (c==1)?" ":"s", (c==1)?"s":"ve");
				}
				else
				{
          c = (int) dwReaders-dwReadersOld;
					printf("%d reader%s ha%s been added to the system\n\n", c, (c==1)?" ":"s", (c==1)?"s":"ve");
				}
			}

      dwReadersOld = dwReaders;
		}

    if (dwReaders == 0)
    {
      /* We must wait here, because the SCardGetStatusChange doesn't wait  */
      /* at all in case there's no reader in the system. Silly, isn't it ? */
      Sleep(1000);
    }

		/*
     * Interesting part of the job : call SCardGetStatusChange to monitor all changes
     * taking place in the PC/SC reader(s)
     */
		rc = SCardGetStatusChange(hContext,
			                        INFINITE,
			                        rgscState,
			                        dwReaders);	
		
		if (rc != SCARD_S_SUCCESS)
    {
      printf("SCardGetStatusChange error 0x%08lX (%lu).\n", rc, rc);

      if (rc == SCARD_F_INTERNAL_ERROR)
      {
        /* Oups ? Restard from scratch after 2500ms */
        if (szReaders != NULL)
        {
          SCardFreeMemory(hContext, szReaders);
          szReaders = NULL;
        }
        Sleep(2500);
        continue;
      }
      break;
    }

		for (i=0; i<dwReaders; i++)
		{
      BOOL just_inserted = FALSE;

      if (rgscState[i].dwEventState & SCARD_STATE_CHANGED)
      {
        /* Something changed since last loop        */
        if ( (rgscState[i].dwEventState & SCARD_STATE_PRESENT)
         && !(rgscState[i].dwCurrentState & SCARD_STATE_PRESENT) )
          just_inserted = TRUE;

        /* Remember new current state for next loop */
        rgscState[i].dwCurrentState = rgscState[i].dwEventState;
      } else
      {
        /* Nothing new, don't display anything for this reader */
        /* (unless we're in the first run)                     */
        if (!bFirstRun)
          continue;
      }

			if (just_inserted)
			{
				printf("Card inserted in %s\n", rgscState[i].szReader);

				if (rgscState[i].dwEventState & SCARD_STATE_MUTE)
				{
					printf("\tCard is mute\n");
				} else
				{
					printf("\tATR: ");
					for (j=0; j<rgscState[i].cbAtr; j++)
						printf("%02X", rgscState[i].rgbAtr[j]);
					printf("\n");

					if (!ProcessCardAtr(hContext, rgscState[i].rgbAtr, rgscState[i].cbAtr))
            return FALSE;

					printf("\n");
				}
			}
		}

    /* Free the list of readers  */
    if (szReaders != NULL)
    {
      SCardFreeMemory(hContext, szReaders);
      szReaders = NULL;
    }
      
    /* Not the first run anymore */
		bFirstRun = FALSE;
	}


  /* Never go here (Ctrl+C kill us before !) */
  free(rgscState);
  return TRUE;
}
Exemple #20
0
void listReaders() {
    LPTSTR          pmszReaders = NULL;
    LPTSTR          pReader;
    LONG            lReturn, lReturn2;
    DWORD           cch = SCARD_AUTOALLOCATE;

    int i = 0;

    SCardEstablishContext(
                   SCARD_SCOPE_USER, // Scope of the resource manager context.
                   NULL,             // r.f.u
                   NULL,             // r.f.u
                   &m_hContext);	 // Returns the resource manager handle.


    // Retrieve the list the readers.
    // hSC was set by a previous call to SCardEstablishContext.
    lReturn = SCardListReaders(m_hContext,
                               NULL,
                               (LPTSTR)&pmszReaders,
                               &cch);
    switch(lReturn) {
        case SCARD_E_NO_READERS_AVAILABLE:
            printf("Reader is not in groups.\n");
            // Take appropriate action.
            // ...
            break;

        case SCARD_S_SUCCESS:
            // Do something with the multi string of readers.
            // Output the values.
            // A double-null terminates the list of values.
            pReader = pmszReaders;
            while ('\0' != *pReader) {
                // Display the value.
                printf("Reader: %S\n", pReader);
                // Advance to the next value.
                pReader = pReader + wcslen((wchar_t*)pReader) + 1;
                ++i;
            }
            printf("number of readers = %d\n", i);
            // Free the memory.
            lReturn2 = SCardFreeMemory(m_hContext, pmszReaders);
            if (SCARD_S_SUCCESS != lReturn2)
                printf("Failed SCardFreeMemory\n");
            break;

        default:
            printf("Failed SCardListReaders 0x%X\n", lReturn);
            //break;
            if (lReturn == SCARD_E_SERVICE_STOPPED) {
                printf("service stopped\n");
            }
            // Take appropriate action.
            // ...
            break;
    }
    SCardReleaseContext(m_hContext);
    //SCardEstablishContext(
    //               SCARD_SCOPE_USER, // Scope of the resource manager context.
    //               NULL,             // r.f.u
    //               NULL,             // r.f.u
    //               &m_hContext);	 // Returns the resource manager handle.

}
PCSC::PCSC( std::string& a_stInputReaderName, u2& a_u2PortNumber, std::string& a_stURI, u4& a_NameSpaceHivecode, u2& a_TypeHivecode, u4& a_Index ) {

    Log::begin( "PCSC::PCSC" );

    m_bDoTransact = true;

    std::string stIdentifiedReaderName = "";

    LPTSTR pReaderList = NULL;

    if( a_stInputReaderName.empty( ) ) {

        a_stInputReaderName = "selfdiscover";
    }

    m_hContextPCSC = 0;

    m_hCardPCSC = 0;

    LONG lReturn = SCardEstablishContext( 0, NULL, NULL, &m_hContextPCSC );

    if( SCARD_S_SUCCESS != lReturn )
    {
        std::string msg = "";
        Log::toString( msg, "SCardEstablishContext <%#02x>", lReturn );
        Log::error( "PCSC::PCSC", msg.c_str( ) );

        throw RemotingException((lpCharPtr)"PCSC: SCardEstablishContext error",lReturn);
    }

    // self-discovery mechanism
#ifdef WIN32
    if (_stricmp("selfdiscover", a_stInputReaderName.c_str()) == 0) {
#else
    if (strncasecmp("selfdiscover", a_stInputReaderName.c_str(),a_stInputReaderName.length()) == 0) {
#endif
        // In Windows SCARD_AUTOALLOCATE (-1) as a value of readerListChatLength
        // would signal the SCardListReaders to determine the size of reader string
        // This is not available in Linux so we call the SCardListReaders twice. First
        // to get the length and then the reader names.
#ifdef WIN32
        DWORD readerListCharLength = SCARD_AUTOALLOCATE;
        lReturn = SCardListReaders( m_hContextPCSC, NULL, (LPTSTR)&pReaderList, &readerListCharLength);

#else
        DWORD readerListCharLength = 0;

        lReturn = SCardListReaders(m_hContextPCSC,NULL,NULL,&readerListCharLength);
        if(lReturn != SCARD_S_SUCCESS)
            throw RemotingException((lpCharPtr)"PCSC: SCardListReaders error",lReturn);

        pReaderList = (lpCharPtr)malloc(sizeof(char)*readerListCharLength);
        lReturn = SCardListReaders(m_hContextPCSC, NULL,pReaderList, &readerListCharLength);
#endif


        if(lReturn != SCARD_S_SUCCESS) {

            std::string msg = "";
            Log::toString( msg, "SCardListReaders <%#02x>", lReturn );
            Log::error( "PCSC::PCSC", msg.c_str( ) );
            throw RemotingException((lpCharPtr)"PCSC: SCardListReaders error",lReturn);

        } else {

            u4 count = 0;
            u1 foundReader = FALSE;
            SCARDHANDLE finalCardHandle = 0;

            try {

                lpTCharPtr pReader = pReaderList;

                while ('\0' != *pReader ) {

                    size_t readerNameLen = strlen((const char*)pReader);
                    SCARD_READERSTATE readerStates[1];
                    readerStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
                    readerStates[0].szReader = pReader;

                    if ( SCardGetStatusChange( m_hContextPCSC, 0, readerStates, 1) == SCARD_S_SUCCESS) {

                        if ((readerStates[0].dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT) {

                            // we found a card in this reader
                            stIdentifiedReaderName = pReader;

                            DWORD activeProtocol;

                            lReturn = SCardConnect( m_hContextPCSC, (LPTSTR)stIdentifiedReaderName.c_str(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &m_hCardPCSC, &activeProtocol);

                            if (lReturn == SCARD_S_SUCCESS) {

                                // try to identify if we're dealing with a .NetCard
                                u1 answerData[258];
                                DWORD answerLen = 258;

                                Log::log( "PCSC::PCSC SCardTransmit..." );
                                lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, isNetCardAPDU, sizeof(isNetCardAPDU), NULL, (LPBYTE)answerData, &answerLen);
                                Log::log( "PCSC::PCSC - SCardTransmit <%#02x>", lReturn );

                                if (lReturn == SCARD_S_SUCCESS)
                                {
                                    u1 rethrowException = FALSE;
                                    try {
                                        if (answerData[answerLen - 2] == 0x61)
                                        {
                                            if (answerData[answerLen - 1] > 10)
                                            {
                                                u1Array invokeAPDU(0);
                                                invokeAPDU += (u1)0xD8;
                                                invokeAPDU += (u2)CARDMANAGER_SERVICE_PORT;
                                                invokeAPDU += (u1)0x6F;
                                                invokeAPDU += (u4)HIVECODE_NAMESPACE_SMARTCARD;
                                                invokeAPDU += (u2)HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER;
                                                invokeAPDU += (u2)HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT;
                                                std::string* cmServicem_stURI = new std::string(CARDMANAGER_SERVICE_NAME);
                                                invokeAPDU.Append(cmServicem_stURI);
                                                delete cmServicem_stURI;
                                                invokeAPDU += (u4)a_NameSpaceHivecode;
                                                invokeAPDU += (u2)a_TypeHivecode;
                                                invokeAPDU.Append(&a_stURI);

                                                // construct call
                                                if(invokeAPDU.GetLength() <= (s4)APDU_TO_CARD_MAX_SIZE) {
                                                    u1Array apdu(5);
                                                    apdu.GetBuffer()[0] = 0x80;
                                                    apdu.GetBuffer()[1] = 0xC2;
                                                    apdu.GetBuffer()[2] = 0x00;
                                                    apdu.GetBuffer()[3] = 0x00;
                                                    apdu.GetBuffer()[4] = (u1)invokeAPDU.GetLength();
                                                    apdu += invokeAPDU;

                                                    u1Array answer(0);

                                                    Log::log( "PCSC::PCSC - ExchangeData..." );
                                                    exchangeData(apdu, answer);
                                                    Log::log( "PCSC::PCSC - ExchangeData ok" );

                                                    Log::log( "PCSC::PCSC - CheckForException..." );
                                                    u4 protocolOffset = m_MarshallerUtil.CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32);
                                                    Log::log( "PCSC::PCSC - CheckForException ok" );

                                                    u4 discoveredPortNumber = m_MarshallerUtil.ComReadU4At(answer, protocolOffset);
                                                    if ((a_u2PortNumber == 0) || (discoveredPortNumber == a_u2PortNumber))
                                                    {
                                                        a_u2PortNumber = (u2)discoveredPortNumber;

                                                        if (foundReader == TRUE)
                                                        {
                                                            if (a_Index == 0)
                                                            {
                                                                // this is the second reader/card/app that matches - we error at this point
                                                                rethrowException = TRUE;
                                                                std::string errorMessage( "At least 2 cards posses \"");
                                                                errorMessage += a_stURI.c_str( );
                                                                errorMessage += "\" service\r\nRemove conflicting cards from your system";
                                                                Log::error( "PCSC::PCSC", errorMessage.c_str( ) );

                                                                throw RemotingException(errorMessage);
                                                            }
                                                        }

                                                        foundReader = TRUE;
                                                        finalCardHandle = m_hCardPCSC;

                                                        // Advance to the next value.
                                                        count++;

                                                        if (count == a_Index)
                                                        {
                                                            // we enumerate one by one the valid readers - so stop here
                                                            break;
                                                        }

                                                        pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1);
                                                        continue;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    catch (...)
                                    {
                                        if (rethrowException == TRUE)
                                        {
                                            throw;
                                        }
                                        else
                                        {
                                            // swallow exception
                                        }
                                    }

                                    SCardDisconnect( m_hCardPCSC, SCARD_LEAVE_CARD);
                                    m_hCardPCSC = 0;
                                }
                                // this is not a .NetCard, or the service was not found - let's try another reader/card
                                else
                                {
                                    Log::error( "PCSC::PCSC", "SCardTransmit failed" );
                                }
                            }
                            else
                            {
                                Log::error( "PCSC::PCSC", "SCardConnect failed" );
                            }
                        }
                        else
                        {
                            Log::error( "PCSC::PCSC", "SCARD_STATE_PRESENT not present" );
                        }
                    }
                    else
                    {
                        Log::error( "PCSC::PCSC", "SCardGetStatusChange != SCARD_S_SUCCESS" );
                    }

                    // Advance to the next value.
                    pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1);
                }
            } catch (...) {

                stIdentifiedReaderName = "";

#ifdef WIN32
                /*lReturn = */SCardFreeMemory( m_hContextPCSC, pReaderList);
                /*if(lReturn != SCARD_S_SUCCESS) {
                throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn);
                }*/
#else
                if( pReaderList ) {

                    free(pReaderList);
                }
#endif
                throw;
            }

            // have we found anything ?
            if( !foundReader) {

                stIdentifiedReaderName = "";

#ifdef WIN32
                /*lReturn = */SCardFreeMemory( m_hContextPCSC, pReaderList);
                //if(lReturn != SCARD_S_SUCCESS) {
                //    throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn);
                //}
#else
                if(pReaderList ) {

                    free(pReaderList);
                }
#endif

                throw RemotingException((lpCharPtr)"Could not find any .NET smart card", SCARD_E_NO_SMARTCARD );
            }

            m_hCardPCSC = finalCardHandle;
        }

        m_stReaderName = stIdentifiedReaderName;

    } else {

        m_stReaderName = a_stInputReaderName;
    }

    Log::end( "PCSC::PCSC" );
}


/*
*/
void PCSC::exchangeData( u1Array &dataIn, u1Array &dataout ) {

    // check validity of handle
    if ( SCARD_S_SUCCESS != SCardIsValidContext( m_hContextPCSC ) ) {

        throw RemotingException( (lpCharPtr)"PCSC: Invalid handle", SCARD_E_INVALID_HANDLE );
    }

    try {

        if( m_bDoTransact ) { 

            beginTransaction( );
        }

        unsigned char ucRetry = 0;

        do {

            ucRetry++;

            unsigned char answerData[ 258 ];
            memset( answerData, 0, sizeof( answerData ) );

            DWORD answerLen = sizeof( answerData );

#ifdef __DEBUG_APDU__
            Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Command", dataIn.GetBuffer( ), dataIn.GetLength( ) );
            Timer t;
            t.start( );
#endif

            LONG lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, dataIn.GetBuffer( ), dataIn.GetLength( ), NULL, (lpByte)answerData, &answerLen );

            if( SCARD_S_SUCCESS != lReturn ) {

                std::string msg = "";
                Log::toString( msg, "SCardTransmit <%#02x>", lReturn );
                Log::error( "PCSC::ExchangeData", msg.c_str( ) );
            }

            if( ( SCARD_W_REMOVED_CARD == lReturn ) || ( SCARD_W_RESET_CARD == lReturn ) ) {

                DWORD dwActiveProtocol = SCARD_PROTOCOL_T0;

                lReturn = SCardReconnect( m_hCardPCSC, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &dwActiveProtocol );

                if( SCARD_S_SUCCESS != lReturn ) {

                    std::string msg = "";
                    Log::toString( msg, "SCardReconnect <%#02x>", lReturn );
                    Log::error( "PCSC::ExchangeData", msg.c_str( ) );

                    throw RemotingException( (lpCharPtr)"PCSC: SCardReconnect error", lReturn );
                }

                lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, dataIn.GetBuffer( ), dataIn.GetLength( ), NULL, (lpByte)answerData, &answerLen );

                if( SCARD_S_SUCCESS != lReturn ) {

                    Log::log( "PCSC::ExchangeData - SCardTransmit <%#02x>", lReturn );
                }

            } else if( SCARD_S_SUCCESS != lReturn ) {

                std::string s;
                Log::toString( s, "SCardTransmit failed <%#02x>", lReturn );
                Log::error( "PCSC::ExchangeData", s.c_str( ) );

                throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error", lReturn );
            }

            if (answerLen < 2) {

                Log::error( "PCSC::ExchangeData", "Incorrect length returned" );

                throw RemotingException((lpCharPtr)"PCSC: SCardTransmit error - Incorrect length returned",SCARD_F_COMM_ERROR);
            }

            if (answerLen > 2) {

                u1Array temp(answerLen - 2);

                temp.SetBuffer(answerData);

                dataout += temp;
            }

            u1 sw1 = answerData[answerLen - 2];

            u1 sw2 = answerData[answerLen - 1];

#ifdef __DEBUG_APDU__
            Log::log( "PCSC::ExchangeData - Status (1) <%02x%02x>", sw1, sw2 );
            Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Response", answerData, answerLen );
            t.stop( "PCSC::ExchangeData - Response" );
#endif

            while( (sw1 == 0x61 ) || ( sw1 == 0x9F ) ) {

                memset( answerData, 0, sizeof( answerData ) );

                unsigned char GetResponse[ 5 ];

                memset( GetResponse, 0, sizeof( GetResponse ) );

                if (sw1 == 0x9F) {

                    GetResponse[0] = 0xA0;

                } else {

                    GetResponse[0] = 0x00;
                }

                GetResponse[1] = 0xC0;

                GetResponse[2] = 0x00;

                GetResponse[3] = 0x00;

                GetResponse[4] = sw2;

                answerLen = 258;

#ifdef __DEBUG_APDU__
                Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Command", GetResponse, sizeof( GetResponse ) );
                t.start( );
#endif

                lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, (lpCByte)GetResponse, 5, NULL, (lpByte)answerData, &answerLen );

                if( ( SCARD_W_REMOVED_CARD == lReturn ) || ( SCARD_W_RESET_CARD == lReturn ) ) {

                    DWORD dwActiveProtocol = SCARD_PROTOCOL_T0;

                    lReturn = SCardReconnect( m_hCardPCSC, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &dwActiveProtocol );

                    lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, (lpCByte)GetResponse, 5, NULL, (lpByte)answerData, &answerLen );

                } else if( SCARD_S_SUCCESS != lReturn ) {

                    std::string s;
                    Log::toString( s, "SCardTransmit failed <%02x>", lReturn );
                    Log::error( "PCSC::ExchangeData", s.c_str( ) );

                    throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error", lReturn );
                }

                if( answerLen < 2 ) {

                    Log::error( "PCSC::ExchangeData", "Incorrect length returned" );

                    throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error - Incorrect length returned", SCARD_F_COMM_ERROR );
                }

                if( answerLen > 2 ) {

                    u1Array temp( answerLen - 2 );

                    temp.SetBuffer( answerData );

                    dataout += temp;
                }

                sw1 = answerData[ answerLen - 2 ];

                sw2 = answerData[ answerLen - 1 ];

#ifdef __DEBUG_APDU__
                Log::log( "PCSC::ExchangeData - Status (2) <%02x%02x>", sw1, sw2 );
                Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Response", answerData, answerLen );
                t.stop( "PCSC::ExchangeData - Response" );
#endif
            }

            // The response is not acceptable. We have to retry the data transmission
            if( ( 0x63 == sw1 ) || ( ( 0x69 == sw1 ) && ( 0x99 == sw2 ) ) ) {

                Log::log( "PCSC::ExchangeData - Invalid response. Retry" );

            } else {

                break;
            }

 /*               if( ( 0x90 == sw1 ) && ( 0x00 == sw2 ) ) {

                break;
            }*/

        } while ( 3 > ucRetry );

    } catch (...) {

        if( m_bDoTransact ) { 

            endTransaction( );
        }

        throw;
    }

    if( m_bDoTransact ) { 

        endTransaction( );
    }
}


/* Cleanup the context and card handle
*/
PCSC::~PCSC( ) {

    if( m_hCardPCSC ) {

        SCardDisconnect( m_hCardPCSC, SCARD_LEAVE_CARD );

        m_hCardPCSC = 0;
    }

    if( m_hContextPCSC ) {

        SCardReleaseContext( m_hContextPCSC );

        m_hContextPCSC = 0;
    }
}

MARSHALLER_NS_END
Exemple #22
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);
		}
	}
static uint32 handle_ListReaders(IRP* irp, tbool wide)
{
	uint32 len, rv;
	SCARDCONTEXT hContext;
	DWORD dwReaders;
	char *readerList = NULL, *walker;
	int elemLength, dataLength;
	int pos, poslen1, poslen2;

	stream_seek(irp->input, 8);
	stream_read_uint32(irp->input, len);

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

	if (len != 4)
		return SCARD_F_INTERNAL_ERROR;

	stream_read_uint32(irp->input, hContext);

	/* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */

	rv = SCARD_S_SUCCESS;
#ifdef SCARD_AUTOALLOCATE
	dwReaders = SCARD_AUTOALLOCATE;
	rv = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders);
#else
	rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);

	readerList = xmalloc(dwReaders);
	rv = SCardListReaders(hContext, NULL, readerList, &dwReaders);
#endif
	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
		return rv;
	}

/*	DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/

	poslen1 = stream_get_pos(irp->output);
	stream_seek_uint32(irp->output);

	stream_write_uint32(irp->output, 0x01760650);

	poslen2 = stream_get_pos(irp->output);
	stream_seek_uint32(irp->output);

	walker = readerList;
	dataLength = 0;

	while (1)
	{
		elemLength = strlen(walker);
		if (elemLength == 0)
			break;

		dataLength += sc_output_string(irp, walker, wide);
		walker += elemLength + 1;
		elemLength = strlen(walker);
	}

	dataLength += sc_output_string(irp, "\0", wide);

	pos = stream_get_pos(irp->output);

	stream_set_pos(irp->output, poslen1);
	stream_write_uint32(irp->output, dataLength);
	stream_set_pos(irp->output, poslen2);
	stream_write_uint32(irp->output, dataLength);

	stream_set_pos(irp->output, pos);

	sc_output_repos(irp, dataLength);
	sc_output_alignment(irp, 8);

#ifdef SCARD_AUTOALLOCATE
	SCardFreeMemory(hContext, readerList);
#else
	xfree(readerList);
#endif

	return rv;
}
Exemple #24
0
int _tmain(int argc, _TCHAR* argv[])
{
	//WCHAR*						pmszReaders = NULL;
	WCHAR*							pBmszReaders;
	WCHAR*							pfirstReader;
	WCHAR*							pnexttReader;
	LONG							retval = 0;
	SCARDCONTEXT  		hContext;
	DWORD							cchReaders = SCARD_AUTOALLOCATE;
	DWORD							dwTotalLen = 0;
	SCARDHANDLE						hCard;
	DWORD							dwActiveProtocol;
	//	BYTE              SW1, SW2;
	LPBYTE							pbAttr = NULL;
	DWORD							cByte = SCARD_AUTOALLOCATE;
	//	DWORD							i;
	DWORD							iSleep = 250;
	retval = SCardEstablishContext ( SCARD_SCOPE_USER,NULL,NULL,&hContext);
	if(retval == SCARD_S_SUCCESS)
	{
		retval = SCardListReaders(hContext,NULL,(LPWSTR)&pBmszReaders,&cchReaders);
		if(retval == SCARD_S_SUCCESS)
		{
			pfirstReader = pBmszReaders;
			pnexttReader = pfirstReader;

			while(cchReaders > dwTotalLen+1)
			{
				//testGetATR_3(&hContext, pnexttReader);
				/*			do
				{
				retval = SCardConnect(hContext,pnexttReader,
				SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0,&hCard,&dwActiveProtocol);
				}
				while (retval != SCARD_S_SUCCESS);
				wprintf(L"YAY, exclusive access, sleeping now for 10 minutes\n");
				Sleep(600000);
				SCardReleaseContext(hContext);
				wprintf(L"YAY, released access, waiting for keystroke\n");
				getchar();*/

				retval = SCardConnect(hContext,pnexttReader,
					SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0,&hCard,&dwActiveProtocol);

				if(retval == SCARD_S_SUCCESS)
				{                
					//BeidSelectCACApplets1(hCard);
					//SendMSCmd(hCard);
					//BeidSelectCACApplets2(hCard);
					BeidSelectBELPICApplets(hCard);
					GetCardData(hCard);
					//testMinidriverStartSequence(&hCard);
					//testMacNewcardIssue(&hCard);
					//testCardConfusedIssue(&hCard);
					//testIDAIDSelect(&hCard);
					//testBELPICAIDSelect(&hCard);
					//testGetATR(&hCard);
					//testGetATR_2(&hCard);
					//testFullPathSelect(&hCard);
					//testStatus(&hCard);
					//testPPDU_GetFeatureList(&hCard);

					SCardDisconnect(hCard,SCARD_RESET_CARD);
				}
				else
				{
					wprintf(L"SCardConnect to %s failed\n",pfirstReader);
				}

				dwTotalLen += wcslen(pnexttReader)+1;
				if(dwTotalLen < cchReaders)
					pnexttReader = pfirstReader + dwTotalLen;		
			}

			/*SCARD_LEAVE_CARD Do not do anything special.
			SCARD_RESET_CARD Reset the card.
			SCARD_UNPOWER_CARD Power down the card.
			SCARD_EJECT_CARD Eject the card.*/

			SCardFreeMemory(hContext, pBmszReaders);
		}
		else
		{
			printf("SCardListReaders failed\n");
		}
	}
	else
	{
		printf("SCardEstablishContext failed\n");
	}

	SCardReleaseContext(hContext);

	printf("retval = %d\n",retval);
	getchar();
	return 0;
}