macOS HighSierra bug: SCardStatus() returns SCARD_W_RESET_CARD instead of SCARD_W_REMOVED_CARD
This is part of the series: "macOS High Sierra and smart cards: known bugs"
SCardStatus() returns different error codes than on GNU/Linux and Windows
SCardStatus()
on High Sierra returns error codes that are different than on GNU/Linux and Windows.SCardStatus() returns SCARD_W_RESET_CARD after a card change
On High SierraSCardStatus()
returns SCARD_W_RESET_CARD
if the card has been removed and inserted again in the reader.On GNU/Linux and Windows
SCardStatus()
returns SCARD_W_REMOVED_CARD
instead.See also
Apple bug report #44672224 "PC/SC SCardStatus() returns SCARD_W_RESET_CARD instead of SCARD_W_REMOVED_CARD". Marked as duplicate of #23900844.This bug is very similar to previous bugs about
SCardTransmit()
("macOS HighSierra bug: SCardTransmit() returns different error codes than on GNU/Linux and Windows") and SCardBeginTransaction()
("OS X El Capitan bug: SCardBeginTransaction() returns different error codes than on GNU/Linux and Windows").Sample code
#include <stdio.h> #include <string.h> #include <unistd.h> #ifdef __APPLE__ #include <PCSC/winscard.h> #include <PCSC/wintypes.h> #else #include <winscard.h> #endif #define CHECK_RV(fct) if (SCARD_S_SUCCESS != rv) { printf(fct"() failed: %s (0x%08X)\n", pcsc_stringify_error(rv), rv); ret = 0; goto error; } else { printf(fct"(): OK\n"); } int main(void) { int ret = 1; SCARDCONTEXT hContext; SCARDHANDLE hCard; DWORD dwActiveProtocol; LONG rv; char mszReaders[1024]; DWORD dwReaders = sizeof(mszReaders); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); CHECK_RV("SCardEstablishContext"); rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders); CHECK_RV("SCardListReaders"); rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); CHECK_RV("SCardConnect"); printf("Remove and insert the card. Then press Enter"); getchar(); DWORD chReaderLen = 100; DWORD dwState; DWORD dwProtocol; BYTE bAtr[33]; DWORD cbAtrLen = sizeof bAtr; rv = SCardStatus(hCard, mszReaders, &chReaderLen, &dwState, &dwProtocol, bAtr, &cbAtrLen); CHECK_RV("SCardStatus"); rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD); CHECK_RV("SCardDisconnect") rv = SCardReleaseContext(hContext); CHECK_RV("SCardReleaseContext") error: return ret; }
Result (on High Sierra)
$ ./main_Mac
SCardEstablishContext(): OK
SCardListReaders(): OK
SCardConnect(): OK
Remove and insert the card. Then press Enter
SCardStatus() failed: Card was reset. (0x80100068)
Expected result (on Debian)
$ ./main_Linux
SCardEstablishContext(): OK
SCardListReaders(): OK
SCardConnect(): OK
Remove and insert the card. Then press Enter
SCardStatus() failed: Card was removed. (0x80100069)