1

I have problems to read out reader attributes (like SCARD_ATTR_VENDOR_IFD_SERIAL_NO), without a card present on the reader though setting the parameter dwShareMode of the function SCardConnect to SCARD_SHARE_DIRECT. What is going wrong?

This is the Code:

    NativeLong res;
    IntBuffer b = IntBuffer.allocate(1024);
    NativeLongByReference phContext = new NativeLongByReference();
    LongByReference phCard = new LongByReference();

    res = Winscard.INSTANCE.SCardEstablishContext(SCARD_SCOPE_USER, null, null, phContext);

    if (res.intValue() == SCARD_S_SUCCESS) {
      NativeLong hContext = phContext.getValue();   
      res = Winscard.INSTANCE.SCardConnect(hContext, cardReaderName, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_UNDEFINED, phCard, b);

      if (res.intValue() == SCARD_S_SUCCESS) {
        res = Winscard.INSTANCE.SCardGetAttrib(new NativeLong(phCard.getValue()), SCARD_ATTR_VENDOR_IFD_SERIAL_NO, null, b);

        if (res.intValue() == SCARD_S_SUCCESS) {
          int pbAttrLenInt = b.get();
          int[] intArray = { pbAttrLenInt };
          IntBuffer pcbAttrLen = IntBuffer.wrap(intArray);
          ByteBuffer pbAttr = ByteBuffer.allocate(pbAttrLenInt);

          res = Winscard.INSTANCE.SCardGetAttrib(new NativeLong(phCard.getValue()), SCARD_ATTR_VENDOR_IFD_SERIAL_NO, pbAttr, pcbAttrLen);

          byte[] result = pbAttr.array();
          try {
            String text = new String(result, 0, result.length, "ASCII");
            System.out.println(text);
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    }

These are the constants that I'm using:

final static int SCARD_S_SUCCESS = 0;
final static int SCARD_SCOPE_USER = 0;
final static int SCARD_SHARE_DIRECT = 3;
final static int SCARD_PROTOCOL_UNDEFINED = 0;
final static int SCARD_ATTR_VENDOR_IFD_SERIAL_NO = 65795;

This is the Interface:

public interface Winscard extends Library  {
  Winscard INSTANCE = (Winscard) Native.loadLibrary("winscard", Winscard.class, W32APIOptions.UNICODE_OPTIONS);

  NativeLong SCardEstablishContext(
    int dwScope, //SCARD_SCOPE_USER = 0
    Pointer pvReserved1, //must be null
    Pointer pvReserved2, //must be null
    NativeLongByReference phContext);

  NativeLong SCardConnect(
    NativeLong hContext,
    String szReader,
    int dwShareMode, //SCARD_SHARE_DIRECT = 3
    int dwPreferredProtocols,
    LongByReference phCard,
    IntBuffer pdwActiveProtocol);     

  NativeLong SCardGetAttrib(
    NativeLong hCard, 
    int dwAttrId, 
    ByteBuffer pbAttr, 
    IntBuffer pcbAttrLen);
}
alex
  • 143
  • 2
  • 15
  • `LongByReference` is probably incorrect. You don't often see an API ask for the address of a 64-bit element. `SCardConnectW` is incorrect in that it should use `WString` instead of `String` (although you should skip the `-W` and `-A` suffixes altogether and use the same methods for method name and type mapping that JNA does for the w32 API mappings when initializing your library). – technomage Aug 21 '13 at 14:14
  • I've found the mistake: The 4th parameter of SCardConnectA (dwPreferredProtocols) needs to be only SCARD_PROTOCOL_UNDEFINED. – alex Aug 22 '13 at 12:54
  • SCardConnect without suffix didn't work. – alex Aug 22 '13 at 12:57
  • Well, it won't work if you don't include an appropriate function name mapper, such as that in `com.sun.jna.win32.W32APIOptions`. – technomage Aug 22 '13 at 15:38
  • Ok, done, thanks for the hint. I'll change the code above and hope it's okay then. – alex Aug 23 '13 at 08:20

0 Answers0