More robust detection of removal/insertion events

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1044 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
sth 2003-04-17 14:35:58 +00:00
parent aa4c60c4bd
commit b531527169
1 changed files with 24 additions and 18 deletions

View File

@ -234,41 +234,47 @@ static int refresh_slot_attributes(struct sc_reader *reader, struct sc_slot_info
}
if (pslot->readerState.dwEventState & SCARD_STATE_PRESENT) {
int old_flags = slot->flags;
int maybe_changed = 0;
slot->flags |= SC_SLOT_CARD_PRESENT;
slot->atr_len = pslot->readerState.cbAtr;
if (slot->atr_len > SC_MAX_ATR_SIZE)
slot->atr_len = SC_MAX_ATR_SIZE;
memcpy(slot->atr, pslot->readerState.rgbAtr, slot->atr_len);
#ifndef _WIN32
/* If there was a card in the slot previously, and the
* PCSC driver reports a state change, we assume the
* user removed the old card and inserted a new one in the
* meantime. */
if ((pslot->readerState.dwEventState & SCARD_STATE_CHANGED)
&& (old_flags & SC_SLOT_CARD_PRESENT))
slot->flags |= SC_SLOT_CARD_CHANGED;
/* On Linux, SCARD_STATE_CHANGED always means there was an
* insert or removal. But we may miss events that way. */
if (pslot->readerState.dwEventState & SCARD_STATE_CHANGED) {
slot->flags |= SC_SLOT_CARD_CHANGED;
} else {
maybe_changed = 1;
}
#else
/* The above doesn't work on Win32 because there are other events,
* so this code will set the SC_SLOT_CARD_CHANGED most of the time,
* resulting in a complete re-read of the card.
* So we give the card handle to a function (SCardStatus) and see
* if it returns SCARD_W_REMOVED_CARD.
*/
if ((pslot->readerState.dwEventState & SCARD_STATE_CHANGED)
&& (old_flags & SC_SLOT_CARD_PRESENT)) {
/* On windows, SCARD_STATE_CHANGED is turned on by lots of
* other events, so it gives us a lot of false positives.
* But if it's off, there really no change */
if (pslot->readerState.dwEventState & SCARD_STATE_CHANGED) {
maybe_changed = 1;
}
#endif
/* If we aren't sure if the card state changed, check if
* the card handle is still valid. If the card changed,
* the handle will be invalid. */
if (maybe_changed && (old_flags & SC_SLOT_CARD_PRESENT)) {
DWORD readers_len = 0, state, prot, atr_len = 32;
byte atr[32];
unsigned char atr[32];
int rv = SCardStatus(pslot->pcsc_card, NULL, &readers_len,
&state, &prot, atr, &atr_len);
if (rv == SCARD_W_REMOVED_CARD)
slot->flags |= SC_SLOT_CARD_CHANGED;
else
slot->flags &= ~SC_SLOT_CARD_CHANGED;
}
#endif
} else {
slot->flags &= ~(SC_SLOT_CARD_PRESENT|SC_SLOT_CARD_CHANGED);
}
return 0;
}