[Pcsclite-muscle] Windows PC/SC and SCARD_E_SERVICE_STOPPED

Michael StJohns mstjohns at comcast.net
Tue Dec 28 11:54:35 PST 2021


Resent - first was rejected due to HTML??

On 12/27/2021 12:06 PM, Ludovic Rousseau wrote:
> Hello,
>
> Thanks to all for your answers.
>
> Le dim. 26 déc. 2021 à 20:09, Stephan Brunner
> <s.brunner at stephan-brunner.net>  a écrit :
>> Hi,
>>
>> A quick and dirty solution is to establish a new context when getting
>> SCARD_E_SERVICE_STOPPED. I had this situation myself when dealing with
>> this stuff. This method forces the service to start again and stay
>> alive, until the next time the last reader disconnects...
> Exact. This solves the problem.
> Seehttps://ludovicrousseau.blogspot.com/2021/12/windows-pcsc-and-scardeservicestopped_27.html
>
> Now I have to implement a fix for PySCard.
>
> Bye
>
I think your fix is correct, but using SCardListReaders is non-optimal.  
Instead:

On windows,

 1. Establish a context using SCardEstablishContext
 2. Use SCardGetStatusChange on an array of terminals of length 1, with
    \\?PnP?\Notification as the sole terminal name.  Set all the values
    to 0, and call this with a timeout of zero to fill in the array
    properly.
     1. If there are no terminals, you will get a timeout error
        (0x8010000a),
     2. otherwise you'll get an SCARD_S_SUCCESS return , and the upper
        nibble of dwEventState will be set to the count of existing
        terminals.
 3. Copy dwEventState to dwCurrentState, set dwCurrentState to 0 to set
    up for the next round.
 4. Call SCardGetStatusChange again with an infinite wait and the
    updated structure.  If you add or remove a terminal, the call will
    return with an updated dwStatus.
 5. If you now have 0 terminals, you can either assume the service has
    stopped or check for sure using the Windows Service Manager API
    (https://docs.microsoft.com/en-us/windows/win32/services/service-functions).

 6. If the service has stopped, dispose of the handle
    (SCardReleaseContext) and get a new handle (SCardEstablishContext)
    and reenter the loop at 2.
 7. Otherwise reenter the loop at 3.

I tested this using Java JNA on Windows 10 and it works like a charm and 
tracks both additions and removals of readers.    The special casing for 
the services stopping is annoying, but seems to have minimal impact.

Mike






More information about the pcsclite-muscle mailing list