[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.
Re: ScardTransmit returning junk value
Before posting code, please format it properly for readability. Also use code tags (Go Advanced, select code, click '#')
Re: ScardTransmit returning junk value
Quote:
Originally Posted by
RomP
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?
Re: ScardTransmit returning junk value
I'm sorry. You can read that whole statement as:
printf ("\npbRecv %02X ",pbRead[i]);
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?
Re: ScardTransmit returning junk value
Quote:
Originally Posted by
RomP
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.
Re: ScardTransmit returning junk value
Quote:
Originally Posted by
VictorN
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.
Re: ScardTransmit returning junk value
Quote:
Originally Posted by
2kaud
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.
Re: ScardTransmit returning junk value
Quote:
Originally Posted by
RomP
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:
Quote:
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.
Re: ScardTransmit returning junk value
Quote:
Originally Posted by
VictorN
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}.
Re: ScardTransmit returning junk value
Well, I have no udea what these first 4 bytes you are trying to send:
Quote:
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.
Re: ScardTransmit returning junk value
Quote:
Originally Posted by
VictorN
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.
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.
Re: ScardTransmit returning junk value
Quote:
Originally Posted by
VictorN
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 :) .
Re: [RESOLVED] ScardTransmit returning junk value