OS X El Capitan missing feature: SCardGetStatusChange() and "\\?PnP?\Notification"
This is part of the series: "OS X El Capitan and smart cards: known bugs".
SCardGetStatusChange() does not support "\\?PnP?\Notification"
SCardGetStatusChange() does not support the special reader name"\\?PnP?\Notification"
.This is not a bug since this feature was never present in any PC/SC from Apple.
From the Doxygen documentation of pcsc-lite:
To wait for a reader event (reader added or removed) you may use the special reader nameWith this feature it is possible to detect that a smart card reader has been added or removed to the system without polling with calls to SCardListReaders() in a loop."\\?PnP?\Notification"
.
If a reader event occurs the state of this reader will change and the bit SCARD_STATE_CHANGED will be set.
This is used by my tools pcsc_scan from the pcsc-tools package.
See also
Apple bug report #23966225 "PC/SC SCardGetStatusChange() and "\\?PnP?\Notification""Sample code
#include <stdio.h> #ifdef __APPLE__ #include <PCSC/winscard.h> #include <PCSC/wintypes.h> #else #include <winscard.h> #endif int main(void) { SCARDCONTEXT hContext; LPSTR mszReaders; DWORD err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if (err != SCARD_S_SUCCESS) { printf("ScardEstablishedContext: 0x%08x\n",err); return -1; } SCARD_READERSTATE rgReaderStates[1]; rgReaderStates[0].szReader = "\\\\?PnP?\\Notification"; rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE; rgReaderStates[0].dwEventState = SCARD_STATE_UNKNOWN; err = SCardGetStatusChange(hContext, 10, rgReaderStates, 1); printf("SCardGetStatusChange: %s (0x%08X)\n", pcsc_stringify_error(err), err); printf("dwEventState: %X\n", rgReaderStates[0].dwEventState); if (rgReaderStates[0].dwEventState & SCARD_STATE_UNKNOWN) printf("\\\\?PnP?\\Notification is NOT supported\n"); else printf("\\\\?PnP?\\Notification IS supported\n"); SCardReleaseContext(hContext); return 0; }
Result (on El Capitan)
$ CFLAGS="-framework PCSC" make main cc -framework PCSC main.c -o main
$ ./main SCardGetStatusChange: Command successful. (0x00000000) dwEventState: 6 \\?PnP?\Notification is NOT supportedThe returned value for dwEventState is 6 and correspond to SCARD_STATE_CHANGED (2) + SCARD_STATE_UNKNOWN (4). PC/SC indicates that the reader
"\\?PnP?\Notification"
is unknown.Note that
SCardGetStatusChange()
returns SCARD_S_SUCCESS
and also waited for the indicated time, here 10 ms but you can increase the value to make the test more explicit.The command should have returned immediately (or have returned
SCARD_E_TIMEOUT
). Yes, it is a bug in the PC/SC layer.Expected result (on Debian)
$ CFLAGS=`pkg-config --cflags libpcsclite` LDFLAGS=`pkg-config --libs libpcsclite` make main cc -pthread -I/usr/include/PCSC -lpcsclite main.c -o main
$ ./main SCardGetStatusChange: Command timeout. (0x8010000A) dwEventState: 0 \\?PnP?\Notification IS supportedHere the command returns after the delay has expired because no reader has been connected or removed. The returned value is
SCARD_E_TIMEOUT
.If a reader is connected or removed during the delay (here 10 ms) the command would have indicated
SCARD_STATE_CHANGED
for this reader.Known workaround
None known.Maybe Apple will add support of
"\\?PnP?\Notification"
one day.