On 23/03/07, matheus ribeiro <[EMAIL PROTECTED]> wrote:
Thanks Doc Ludovic. If you need any helping testing a new version let me know.
I think I found the problem. You are using SCardGetStatusChange() to
find changes between two consecutive calls to SCardGetStatusChange().
But this function is used to detect changes _during_ its execution,
not between two calls.
You do:
SCardGetStatusChange(timeout=0s)
sleep(2 seconds)
SCardGetStatusChange(timeout=0s)
sleep(2 seconds)
SCardGetStatusChange(timeout=0s)
sleep(2 seconds)
...
but you should do:
SCardGetStatusChange(timeout=2s)
SCardGetStatusChange(timeout=2s)
SCardGetStatusChange(timeout=2s)
...
A modified version of your test program is attached. Try it and report back.
Under Linux SCardGetStatusChange() will return immediately if no card
is present. This occurs because the card is in SCARD_SHARE_EXCLUSIVE
mode. I am not sure it is a bug in pcsc-lite but it looks like so. But
nobody reported it yet.
Bye,
--
Dr. Ludovic Rousseau
#include <stdio.h>
#include <stdlib.h>
#include <winscard.h>
#ifndef WIN32
#include <unistd.h>
#endif
/** max ATR size */
#define TAM_ATR 32
/** Handle stuff */
typedef struct _PCSC_HANDLE
{
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
DWORD dwProtocol;
} PCSC_HANDLE;
/** card stuff */
typedef struct _CARDS
{
LPSTR name;
PCSC_HANDLE handle_card;
SCARD_READERSTATE_A rgReaderStates;
} CARDS;
// function declarations
LONG Connect(CARDS * array_cards);
LONG Verify_State(CARDS * array_cards);
LONG Disconnect(CARDS * array_cards);
// function definitions
LONG Connect(CARDS * array_cards)
{
LONG rv;
LPSTR mszReaders = NULL; //!< Lista de Grupos para lista de Leitores
DWORD LBufReaders; //!< Tamanho do buffer da lista de leitores
DWORD ActiveProtocol;
DWORD dwState; //!< Status do cartao
BYTE ATR[TAM_ATR]; //!< ATR
DWORD lATR = TAM_ATR; //!< Tamanho ATR
printf("connecting\n");
fflush(stdout);
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL,
&array_cards->handle_card.hContext);
if (rv != SCARD_S_SUCCESS)
{
goto end;
}
// Recebendo o tamanho do buffer de leitura
rv = SCardListReaders(array_cards->handle_card.hContext, NULL,
NULL, &LBufReaders);
if (rv != SCARD_S_SUCCESS)
{
goto end;
}
// Recebendo a Lista dos Leitores encontrados no sistema
mszReaders = (LPSTR) malloc(sizeof(char) * LBufReaders);
rv = SCardListReaders(array_cards->handle_card.hContext, NULL,
mszReaders, &LBufReaders);
if (rv != SCARD_S_SUCCESS)
{
goto end;
}
else
{
printf("reader selected: %s\n", mszReaders);
fflush(stdout);
}
array_cards->name = mszReaders;
array_cards->rgReaderStates.dwCurrentState = SCARD_STATE_UNAWARE;
array_cards->rgReaderStates.dwEventState = SCARD_STATE_EMPTY;
// Conexao com o card
rv = SCardConnect(array_cards->handle_card.hContext, mszReaders,
SCARD_SHARE_EXCLUSIVE,
SCARD_PROTOCOL_T0, &(array_cards->handle_card.hCard),
&ActiveProtocol);
if (rv != SCARD_S_SUCCESS)
{
goto end;
}
rv = SCardStatus(array_cards->handle_card.hCard, mszReaders, &LBufReaders,
&dwState, &array_cards->handle_card.dwProtocol, ATR, &lATR);
if (rv != SCARD_S_SUCCESS)
{
goto end;
}
return rv;
end:
if (mszReaders)
{
free(mszReaders);
}
return rv;
}
LONG Verify_State(CARDS * array_cards)
{
LONG rv;
array_cards->rgReaderStates.szReader = array_cards->name;
printf("reader state : 0x%04lx\n",
array_cards->rgReaderStates.dwCurrentState);
fflush(stdout);
rv = SCardGetStatusChange(array_cards->handle_card.hContext, 2000,
&(array_cards->rgReaderStates), 1);
switch (rv)
{
case SCARD_E_TIMEOUT:
printf("NO changes\n");
fflush(stdout);
break;
case SCARD_S_SUCCESS:
if (array_cards->rgReaderStates.dwEventState & SCARD_STATE_CHANGED)
{
printf("reader CHANGED state : 0x%04lx 0x%04lX\n",
array_cards->rgReaderStates.dwEventState,
array_cards->rgReaderStates.dwCurrentState);
fflush(stdout);
}
if (array_cards->rgReaderStates.dwEventState & SCARD_STATE_EMPTY)
{
printf("reader EMPTY state : 0x%04lx\n",
array_cards->rgReaderStates.dwEventState);
fflush(stdout);
}
if (array_cards->rgReaderStates.dwEventState & SCARD_STATE_PRESENT)
{
printf("reader PRESENT state: 0x%04lx\n",
array_cards->rgReaderStates.dwEventState);
fflush(stdout);
}
array_cards->rgReaderStates.dwCurrentState =
array_cards->rgReaderStates.dwEventState;
break;
default:
printf("Error: 0x%lx\n", rv);
}
return rv;
}
LONG Disconnect(CARDS * array_cards)
{
LONG rv;
// Desconecta o cartao
printf("Desconectando o Cartao\n");
rv = SCardDisconnect(array_cards->handle_card.hCard, SCARD_UNPOWER_CARD);
if (rv != SCARD_S_SUCCESS)
{
goto end;
}
// Encerra o contexto
rv = SCardReleaseContext(array_cards->handle_card.hContext);
if (rv != SCARD_S_SUCCESS)
{
goto end;
}
return 0;
end:
return 1;
}
/** loops, every 2 secs report events */
int main()
{
CARDS cartoes[1];
LONG rv;
rv = Connect(&cartoes[0]);
if (rv != SCARD_S_SUCCESS)
{
printf("Nao foi possivel conectar com o cartao\n");
goto end;
}
while ((SCARD_S_SUCCESS == rv) || (SCARD_E_TIMEOUT == rv))
{
rv = Verify_State(&cartoes[0]);
}
rv = Disconnect(&cartoes[0]);
if (rv != SCARD_S_SUCCESS)
{
printf("Nao foi possivel disconectar com o cartao\n");
goto end;
}
return 0;
end:
return 1;
}
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle