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