ProLiant Servers (ML,DL,SL)
cancel
Showing results for 
Search instead for 
Did you mean: 

ICA client on Windows CE 5.0 using PC/SC issue

Val Antonova
Occasional Visitor

ICA client on Windows CE 5.0 using PC/SC issue

Hello,

I am a security software developer and I encounter a problem using HP Thin Client t5520, Windows CE 5.0 version 5.03.588 Rev. A 29 Jan 2007, AddOn ICA 9.18 (build 95), PC/SC, Windows 2003 Server and Citrix Metaframe Server 4.0 with HotFix PSF400W2K3R01 and HotFix PSF400W2K3R03.

I test the connections to a smart card under the following conditions :

I test using readers SCM SCR3310 and Omnikey CardMan 3121. The smart cards that I am using are PayFlex 4K.
I have a Windows 2003 Server PC with a Citrix Metaframe Server 4.0.
I connect manually (not a smart card logon) to this PC through the ICA client on the HP thin client t5520.

Then I insert a smart card on the reader SCR3310 for example and I launch a little program that tests the different smart card functions :

SCardEstablishContext
SCardGetStatusChange
SCardListReaders
SCardConnect
SCardReconnect
SCardDisconnect
SCardReleaseContext

This program have a loop that make a Reconnect to the smart card after a successful Connect.
This loop is the following :

while (nb < 100)
{
if (hCard)
{
printf("Testing SCardReconnect\n");
rv = SCardReconnect(hCard,
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
SCARD_RESET_CARD,
&dwPref);
}
else
{
printf("Testing SCardConnect\n");
rv = SCardConnect(hContext,
&mszReaders[iList[iReader]],
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
&hCard,
&dwPref);
printf("After SCardConnect rv = 0x%x, hCard = %d\n", rv, hCard);
}

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);

if (hCard)
{
SCardDisconnect(hCard,SCARD_RESET_CARD);
hCard=NULL;
}

if(rv != SCARD_W_REMOVED_CARD && rv != SCARD_E_NO_SMARTCARD)
{
printf("Calling SCardReleaseContext\n");
SCardReleaseContext(hContext);
hContext = NULL;

printf("Calling SCardEstablishContext\n");
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);

if (rv != SCARD_S_SUCCESS)
{
printf("Error SCardEstablishContext : 0x%x\n", rv);
return -1;
}
}
}

Sleep(1000);

nb++;
}

When the program is running I remove and insert the smart card several times to test the SCardConnect and SCardReconnect functions. Occasionally there are some warnings or errors like :
0x80100066 (SCARD_W_UNRESPONSIVE_CARD)
0x80100001 (SCARD_F_INTERNAL_ERROR)

and not documented errors :
0x6f9
0x458
0x45d
0x16

The problem is that a random number of insert/remove card there is an Invalid hCard Handle error (0x80100003 SCARD_E_INVALID_HANDLE) when try to reconnect to the card.

And from that moment on it is impossible to obtain a valid hCard Handle even if I try to reestablish the context first.

When I stop the program and launch it one more time I have the 0x80100003 error immediately.

If I disconnect or close the session and I come back that works correctly (of course until it fails once again after several remove/insert card with error 0x80100003).

I don't think the problem comes from my samlpe code because when testing the same scenario with TestResMan utility (http://www.scmmicro.com/support/pcs_utilities.html) I've got exactly the same error - SCARD_E_INVALID_HANDLE.

When using an RDP connection there is no problem.

When testing through a ICA client (version 9.00.32649) on Windows XP and the RDP client on XP, there is no problem either.

Have you seen this problem before? Do you have an idea how to solve it? Are there some well known hotfixes for this kind of issue for ICA client (or Server) as well as Windows CE Operating System (PC/SC layer)?

Thank you.


P.S. : Following is the complete code of the PCSC test program :


int main(int argc, char **argv)
{
SCARDHANDLE hCard;
SCARDCONTEXT hContext;
SCARD_READERSTATE rgReaderStates[1];
unsigned long dwReaderLen, dwState, dwProt, dwAtrLen;
unsigned long dwPref, dwReaders;
char *pcReaders, *mszReaders;
unsigned char pbAtr[MAX_ATR_SIZE];
char *mszGroups;
long rv;
int i, p, iReader;
int iList[16];
int nb = 0;

printf("Testing SCardEstablishContext\n");
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);
return -1;
}

printf("Testing SCardGetStatusChange \n");
printf("Please insert a working reader\n");
fflush(stdout);
rv = SCardGetStatusChange(hContext, INFINITE, 0, 0);

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);
SCardReleaseContext(hContext);
return -1;
}

printf("Testing SCardListReaders\n");

mszGroups = 0;
rv = SCardListReaders(hContext, mszGroups, 0, &dwReaders);

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);
SCardReleaseContext(hContext);
return -1;
}

mszReaders = (char *) malloc(sizeof(char) * dwReaders);
rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders);

if (rv != SCARD_S_SUCCESS)
{
SCardReleaseContext(hContext);
return -1;
}


p = 0;
for (i = 0; i < dwReaders - 1; i++)
{
++p;
printf("Reader %02d: %s\n", p, &mszReaders[i]);
iList[p] = i;
while (mszReaders[++i] != 0) ;
}

if (p > 1)
{
do
{
printf("Enter the reader number : ");
scanf("%d", &iReader);
printf("\n");

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\n");
fflush(stdout);
rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);
SCardReleaseContext(hContext);
return -1;
}

printf("Testing SCardConnect\n");
rv = SCardConnect(hContext,
&mszReaders[iList[iReader]],
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
&hCard,
&dwPref);

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);
SCardReleaseContext(hContext);
return -1;
}

printf("Testing SCardGetAttrib\n");
dwAtrLen = sizeof(pbAtr);
rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAtr, &dwAtrLen);
printf("result rv = 0x%x\n", rv);
if (rv == SCARD_S_SUCCESS)
{
for (i = 0; i < dwAtrLen; i++)
printf("%02X ", pbAtr[i]);
printf("\n");
}

printf("Testing SCardStatus\n");

dwReaderLen = 50;
pcReaders = (char *) malloc(sizeof(char) * 50);
dwAtrLen = MAX_ATR_SIZE;

rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt, pbAtr, &dwAtrLen);

printf("result rv = 0x%x\n", rv);

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

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

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

printf("\nPress enter!\n");
getchar();

while (nb < 100)
{
if (hCard)
{
printf("Testing SCardReconnect\n");
rv = SCardReconnect(hCard,
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
SCARD_RESET_CARD,
&dwPref);
}
else
{
printf("Testing SCardConnect\n");
rv = SCardConnect(hContext,
&mszReaders[iList[iReader]],
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
&hCard,
&dwPref);
printf("After SCardConnect rv = 0x%x, hCard = %d\n", rv, hCard);
}

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);

if (hCard)
{
SCardDisconnect(hCard,SCARD_RESET_CARD);
hCard=NULL;
}

if(rv != SCARD_W_REMOVED_CARD && rv != SCARD_E_NO_SMARTCARD)
{
printf("Calling SCardReleaseContext\n");
SCardReleaseContext(hContext);
hContext = NULL;

printf("Calling SCardEstablishContext\n");
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);

if (rv != SCARD_S_SUCCESS)
{
printf("Error SCardEstablishContext : 0x%x\n", rv);
return -1;
}
}

}

Sleep(1000);

nb++;
}

printf("Testing SCardDisconnect\n");
rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);
SCardReleaseContext(hContext);
return -1;
}

printf("Testing SCardReleaseContext\n");
rv = SCardReleaseContext(hContext);

if (rv != SCARD_S_SUCCESS)
{
printf("Error : 0x%x\n", rv);
return -1;
}

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

return 0;
}

1 REPLY
Val Antonova
Occasional Visitor

Re: ICA client on Windows CE 5.0 using PC/SC issue

Hello,

There is some additional information:

After a successful SCardConnect the hcard handle = 1.
This value seems to me suspicious even if it seems work in the SCardReconnect function several times before having the hcard INVALID HANDLE error.

Do you know if 1 is a valid hcard handle value ?

Thank you.