CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Apr 2013
    Posts
    7

    [RESOLVED] ScardTransmit returning junk value

    Hi,

    I am trying to read data from a smartcard using scardTransmit.
    But the data read is always 6D 00 CC CC (Be it for name, expiry date or any other data, always the same.)
    This is probably some junk data? Am I missing something or have I done something incorrectly? Please help me.

    My code would read as below :



    Code:
    #include "stdafx.h"
    #include <winscard.h>
    #include <stdio.h>
    
    #pragma comment(lib, "winscard.lib")
    
    bool transmitFunction(SCARDHANDLE hCard, LPCBYTE pbSend)
    {
    	bool rv = false;
    	int i =	0;
    	long Return;
    	BYTE pbRead[2];	
    
    	DWORD dwLenR = sizeof(pbRead);
    		
    	lReturn = SCardTransmit(hCard,
    		SCARD_PCI_T0,
    		pbSend,
    		sizeof(pbSend),
    		NULL,
    		(LPBYTE)pbRead,
    		&dwLenR );
    	if ( SCARD_S_SUCCESS != lReturn ){
    	rv = false;
    	}
    	else{
    		while (i < sizeof(pbRead)){
    			printf("\n pbRecv %02X",pbRead[i]);
    			i++;
    		}
    		rv = true;
    	}
    	return rv;
    }
    bool selectCPRDFEF(SCARDHANDLE	hCard)
    {
    	bool  rv = FALSE;
    
    	BYTE pbSlctBidAp[] = {*********}; //Select BID Applet
    	rv = transmitFunction(hCard,pbSlctBidAp);
    
    	BYTE pbSlctBidDF[] = { *****8}; //Select BID DF
    	rv = transmitFunction(hCard,pbSlctBidAp);
    
    	BYTE pbSlctCPR1EF[] = { ******}; //Select card # 1 EF
    	rv = transmitFunction(hCard,pbSlctCPR1EF);
    	
    	return rv;
    }
    bool getCPRFirstNameEn(SCARDHANDLE	hCard)
    {
    	bool		rv			=		FALSE;
    	int		i			=		0;
    
    	BYTE pbGetFirstNameEn[] = { *******}; // Get English First Name
    	BYTE pbRead[34] ;
    	DWORD dwLenR = sizeof(pbRead);
    
    	long lReturn = SCardTransmit(hCard,	SCARD_PCI_T0,pbGetFirstNameEn,
    		sizeof(pbGetFirstNameEn),NULL,pbRead,&dwLenR );
    
    	if ( SCARD_S_SUCCESS != lReturn )
    	{
    		rv = false;
    	}
    	else
    	{
    		while (i < sizeof(pbRead))
    		{
    			printf("B pbRecv %02X ",pbRead[i]);
    			i++;
    		}
    		rv = true;
    	}
    	return rv;
    }
    bool status(SCARDHANDLE	hCard,SCARDCONTEXT	hSC)
    {
    	long  lReturn;
    	BYTE  bAttr[32];
    	DWORD  dwState, dwProtocol;
    	bool  rv =	TRUE;
            LPCTSTR  szReaderOut =	NULL;
    
    	/*Determine the Status of the smart card*/
    	lReturn = SCardStatus(hCard,
    		(LPWSTR)szReaderOut,
    		NULL,
    		&dwState,
    		&dwProtocol,
    		(LPBYTE)&bAttr,
    		NULL); 
    
    	if ( SCARD_S_SUCCESS != lReturn ){
    		rv = FALSE;
    	}
    	else
    	{
    		// Examine retrieved status elements.
    		switch ( dwState ){
    		case SCARD_ABSENT:
    		case SCARD_POWERED:
    		case SCARD_PRESENT:
    		case SCARD_SWALLOWED:
    			printf("Card can't be used. Releasing context.");
    			lReturn = SCardReleaseContext(hSC);	
    			rv = FALSE;
    			break;
    		case SCARD_SPECIFIC:
    			printf("Card has specific communication protocols set");
    			break;
    		default:
    			printf("Unknown or unexpected card state");
    			rv = FALSE;
    			break;
    		}}
    	return rv;
    }
    DWORD WINAPI ReaderUSBThread(LPVOID lpParameter) {
    
    	SCARDCONTEXT	hSC	=	NULL;
            SCARDHANDLE		hCard=	NULL;
    	bool				fret	=	true;
    	LPCTSTR			szReader=L"CASTLES EZ100PU 0";
    	LONG				lReturn;
    	DWORD			dwAP;
    
    	HRESULT hr = CoInitialize(NULL);
    	try
    	{
    		/*Establishes the Context*/
    		lReturn = SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hSC );
    
    		if ( SCARD_S_SUCCESS != lReturn )
    			printf("\nNOT  SCARD_S_SUCCESS");
    
    		/*Establish connection with Smart Card*/
    		lReturn = SCardConnect( hSC, 
    			(LPCTSTR)szReader,
    			SCARD_SHARE_SHARED,
    			SCARD_PROTOCOL_T0 ,
    			&hCard,
    			&dwAP );
    
    		if ( SCARD_S_SUCCESS != lReturn ){
    			if (lReturn == SCARD_W_REMOVED_CARD || lReturn == SCARD_E_NO_SMARTCARD) {
    				printf("\nSmart Card not inserted or it has been removed.");
    				lReturn = SCardDisconnect(hCard,SCARD_RESET_CARD);	
    				return false;
    			}
    		}
    		bool rv = status(hCard,hSC);
    		if(TRUE != rv){
    			return rv;
    		}
    		selectCPRDFEF(hCard);
    		getCPRFirstNameEn(hCard);
    
    		// Terminates the connection
    		lReturn = SCardDisconnect(hCard,SCARD_RESET_CARD);	
    		if (lReturn != SCARD_S_SUCCESS)  
    		{ 	// do some error handling
    		}
    
    	} catch(...) {
    		printf("\nStream ends with error");
    	}
    	lReturn = SCardReleaseContext(hSC);		
    	if (lReturn != SCARD_S_SUCCESS)   {
    		printf("\nRelease Context Failure- %ld ",lReturn);
    	}
    	return 0;
    }
    int main()
    {
    	DWORD				dwThreadId		=		0;
    	CreateThread(NULL, NULL, ReaderUSBThread,NULL ,NULL,&dwThreadId );
    	return 0;
    }
    SCardEstablishContext and SCardConnect are succesful.
    Prints for pbRead in getCPRFirstNameEn() is : 6D 00 CC CC
    Note : I have edited the above to include actual code.
    I have also tried sending different APDU commands (for getting second name, expiry date etc) , but the print for all is the same.
    Last edited by RomP; January 14th, 2014 at 09:24 AM.

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: ScardTransmit returning junk value

    Before posting code, please format it properly for readability. Also use code tags (Go Advanced, select code, click '#')
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: ScardTransmit returning junk value

    Quote Originally Posted by RomP View Post
    Code:
    else
    {
    	int i=0;
    
    	while (i < sizeof(pbRead))
    	{
    		_app->__debug(IEEE_DEBUG_CARDREADER, 0, L"B pbRecv %02X ",pbRead[i]);
    		i++;
    	}
    }
    What is _app?
    What is __debug(...)?
    What is IEEE_DEBUG_CARDREADER?
    Victor Nijegorodov

  4. #4
    Join Date
    Apr 2013
    Posts
    7

    Re: ScardTransmit returning junk value

    I'm sorry. You can read that whole statement as:
    printf ("\npbRecv %02X ",pbRead[i]);

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: ScardTransmit returning junk value

    Code:
    lReturn = SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hSC );
    lReturn = SCardConnect( hSC,(LPCTSTR)szReader,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0 ,&hCard,&dwAP );
    You aren't checking iReturn for errors after you call each function. How do you know that SCardEstablishContext and SCardConnect have worked OK if you don't check for errors?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: ScardTransmit returning junk value

    Quote Originally Posted by RomP View Post
    I'm sorry. You can read that whole statement as:
    printf ("\npbRecv %02X ",pbRead[i]);
    Well, It's time to post your actual code (with Code tags, of course) with all needed declarations and definitions.
    What you have posted so far has nothing to do with what could and should be executed.
    Victor Nijegorodov

  7. #7
    Join Date
    Apr 2013
    Posts
    7

    Re: ScardTransmit returning junk value

    Quote Originally Posted by VictorN View Post
    Well, It's time to post your actual code (with Code tags, of course) with all needed declarations and definitions.
    What you have posted so far has nothing to do with what could and should be executed.
    I have edited my original post with the actual code.

  8. #8
    Join Date
    Apr 2013
    Posts
    7

    Re: ScardTransmit returning junk value

    Quote Originally Posted by 2kaud View Post
    Code:
    lReturn = SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hSC );
    lReturn = SCardConnect( hSC,(LPCTSTR)szReader,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0 ,&hCard,&dwAP );
    You aren't checking iReturn for errors after you call each function. How do you know that SCardEstablishContext and SCardConnect have worked OK if you don't check for errors?
    In my actual code, I was checking for iReturn values. Both SCardEstablishContext and SCardConnect have worked.
    Thanks for the feedback, I have included code tags.

  9. #9
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: ScardTransmit returning junk value

    Quote Originally Posted by RomP View Post
    Code:
    	BYTE pbGetFirstNameEn[] = { 0x00,0xB0,0x00,0x09}; // Get English First Name
    	BYTE pbRead[34] ;
    	DWORD dwLenR = sizeof(pbRead);
    
    	long lReturn = SCardTransmit(hCard,	SCARD_PCI_T0,pbGetFirstNameEn,
    		sizeof(pbGetFirstNameEn),NULL,pbRead,&dwLenR );
    What is this SCardTransmit function? Is it what MSDN describes in http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx?
    It it is the same then why is your pbGetFirstNameEn buffer only 4-byte long? According to docs:
    Retrieving data from the card
    To receive n>0 bytes of data from the card, the send and receive buffers must be formatted as follows.
    The first four bytes of the pbSendBuffer buffer contain the CLA, INS, P1, and P2 values for the T=0 operation. The fifth byte must be set to n: the size, in bytes, of the data to be transferred from the card. If 256 bytes are to be transferred from the card, then this byte must be set to zero.
    The cbSendLength parameter must be set to five, the size of the T=0 header information.
    The pbRecvBuffer will receive the data returned from the card, immediately followed by the SW1 and SW2 status codes from the operation.
    The pcbRecvLength should be at least n+2 and will be set to n+2 upon return.
    Victor Nijegorodov

  10. #10
    Join Date
    Apr 2013
    Posts
    7

    Re: ScardTransmit returning junk value

    Quote Originally Posted by VictorN View Post
    What is this SCardTransmit function? Is it what MSDN describes in http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx?
    It it is the same then why is your pbGetFirstNameEn buffer only 4-byte long? According to docs:
    Yes, it is the same SCardTransmit that MSDN describes.
    I had missed out the size of data in the send buffer. I am expecting it to return 32 bytes of first name, so i have replaced it with :
    Code:
    BYTE pbGetFirstNameEn[] = { 0x00,0xB0,0x00,0x09,0x32}; // Get English First Name
    But it still returns the same data.
    Also, the number of CC in the pbRead buffer depends on the size assigned to it. If I declare it as pbRead[34] , then it prints as :
    6D 00 CC CC CC CC ... {CC 32 times}.

  11. #11
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: ScardTransmit returning junk value

    Well, I have no udea what these first 4 bytes you are trying to send:
    0x00,0xB0,0x00,0x09
    mean, but what I do know is your fitth byte (0x32) is wrong!
    0x32 is exactly decimal 50 while your buffer size for received data is 34.
    Victor Nijegorodov

  12. #12
    Join Date
    Apr 2013
    Posts
    7

    Re: ScardTransmit returning junk value

    Quote Originally Posted by VictorN View Post
    Well, I have no udea what these first 4 bytes you are trying to send:mean, but what I do know is your fitth byte (0x32) is wrong!
    0x32 is exactly decimal 50 while your buffer size for received data is 34.
    Oh, then it shud be :
    Code:
    BYTE pbGetFirstNameEn[] = { 0x00,0xB0,0x00,0x09,0x22}; // Get English First Name
    However, this returns the same output. The first 4 bytes are part of the APDU commands provided in the documentation of the card reader. So, i am sure that it is correct.
    But I am wondering if there is anything i have missed . For connecting to a smart card, would i have missed something other than sCardEstablish,sCardConnect and sCardTransmit.

  13. #13
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: ScardTransmit returning junk value

    Could you post a link to "the documentation of the card reader"?
    Did you debug your code? What is the value of dwLenR after SCardTransmit returned?

    BTW, your transmitFunction implementation is wrong. The sizeof(pbSend) is always the size of LPCBYTE pointer, not of the array that is passed in to this function.
    Victor Nijegorodov

  14. #14
    Join Date
    Apr 2013
    Posts
    7

    Re: ScardTransmit returning junk value

    Quote Originally Posted by VictorN View Post
    Could you post a link to "the documentation of the card reader"?
    Did you debug your code? What is the value of dwLenR after SCardTransmit returned?

    BTW, your transmitFunction implementation is wrong. The sizeof(pbSend) is always the size of LPCBYTE pointer, not of the array that is passed in to this function.
    Sorry for the delay in responding. Yes, the whole issue was because of my sizeof(pbSend) being wrong . Its working perfect when I pass cbSendLength as 5 .
    Thanks a lot .

  15. #15
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: [RESOLVED] ScardTransmit returning junk value

    You are welcome!
    Victor Nijegorodov

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured