On 23/02/07, Paul Klissner <[EMAIL PROTECTED]> wrote:
 Hello,

Hello Paul,

 I'm curious about the differences in the implementation of

PC/SC Lite SCardStatus vs. Windows PC/SC.  Hopefully the answer
 isn't too obvious due to documentation I missed or a previous
 discussion on this list.

 We've noticed a discrepancy between the SCARD_* constants
 to define SCardStatus() values returned from WinSCard.lib
 (a library provided for SmartCard development with MicroSoft SDK)
 and the values from pcsclite.h:

 pcsclite:
   #define SCARD_PRESENT                   0x0004
   #define SCARD_ABSENT                    0x0002
   #define SCARD_SPECIFIC                  0x0040

 Windows SDK,(include/WinSmcrd.h)
   #define SCARD_PRESENT                   0x0002
   #define SCARD_ABSENT                    0x0001
   #define SCARD_SPECIFIC                  0x0006


 pcsclite constants have the values expressed as bit masks.
 The SDK defines them as bit offsets.  (ie. they have
 a simple algebraic relationship to one another).

 The Windows documentation indicates that SCardStatus()
 will return <i>one</i> among several values:
 http://msdn2.microsoft.com/en-gb/library/aa379803.aspx
 which implies a hierarchy wherein one state implies other
 states.

 A windows app. linked against WinSCard.lib from the SDK bears
 out the Windows documentation.  For example, SCardStatus()
 returns 0x0006 when a card is inserted in the reader, corresponding
 to SCARD_SPECIFIC.

 The PC/SC lite documentation is different:
 http://pcsclite.alioth.debian.org/pcsc-lite/node19.html
 It indicates the card state values are logically ORed, and I confirmed
 wthat by running testpcsc on Solaris, using the same SmartCard inserted
 in the reader as in the test above, where the value 0x34 was returned,
 which as a combination of the following states:

   SCARD_PRESENT
   SCARD_NEGOTIABLE
   SCARD_POWERED

 Why did PC/SC lite decide to go this route?

I have no idea. It was already like that before I start working on
pcsc-lite in 2001. Maybe David Corcoran knows?

 It does seem in some ways
 more useful or intuitive, but  doesn't it work against  application
portability?

Exact. But I don't know if SCardStatus() is often used.
I searched for the different SCARD_* constants in all the projects
hosted by opensc.org and could not find any occurrence.

Also note that pcsc-lite never set the state to SCARD_SPECIFIC. So an
application waiting for the card to be in state SCARD_SPECIFIC would
work on Windows but not with pcsc-lite. And I never received a bug
report about this.

 Should the difference be documented?

Yes.

 I wonder how many developers
 have had confusion or problems with this?  Can anyone offer some insights
 or background on this?

I have never seen a bug report about this. So I imagine the impact is
low or non-existent.

 I'm not familiar enough with the differences between PCSClite and PC/SC to
 know how compatible and portable they were intended to be.

Maybe we could change pcsc-lite to correct this API bug?

The code would even be smaller and easier to understand. For example
in winscard.c we have:
               if (rv == SCARD_S_SUCCESS)
               {
                   rContext->readerState->readerState |= SCARD_PRESENT;
                   rContext->readerState->readerState &= ~SCARD_ABSENT;
                   rContext->readerState->readerState |= SCARD_POWERED;
                   rContext->readerState->readerState |= SCARD_NEGOTIABLE;
                   rContext->readerState->readerState &= ~SCARD_SPECIFIC;
                   rContext->readerState->readerState &= ~SCARD_SWALLOWED;
                   rContext->readerState->readerState &= ~SCARD_UNKNOWN;
               }
               else
               {
                   rContext->readerState->readerState |= SCARD_PRESENT;
                   rContext->readerState->readerState &= ~SCARD_ABSENT;
                   rContext->readerState->readerState |= SCARD_SWALLOWED;
                   rContext->readerState->readerState &= ~SCARD_POWERED;
                   rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
                   rContext->readerState->readerState &= ~SCARD_SPECIFIC;
                   rContext->readerState->readerState &= ~SCARD_UNKNOWN;
                   rContext->readerState->cardAtrLength = 0;
               }


--
 Dr. Ludovic Rousseau
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle

Reply via email to