6

I have a problem with getting PCSC reader serial number if card is not present in the reader. I am using winscard.dll and c++.

The following code will work only for the case if card is present in the reader. Otherwise the SCardHandle is not retrieved. I haven't found any other way to get SCardHandle.

SCARDHANDLE hCardHandle;
SCARDCONTEXT    hSC;
WCHAR   pCardReaderName[256];
LONG lReturn;

lReturn = SCardEstablishContext(SCARD_SCOPE_USER, 0, 0, &hSC);

if (lReturn != SCARD_S_SUCCESS)
{
    Console::WriteLine("SCardEstablishContext() failed\n");
    return;
}

my_select_reader(hSC, pCardReaderName); // just shows reader names in console and requires you to pick one

// connect to smart card
DWORD   dwAP;

lReturn = SCardConnect( hSC,
                (LPCWSTR)pCardReaderName,
                SCARD_SHARE_SHARED,
                SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_RAW,
                &hCardHandle,
                &dwAP );

if ( SCARD_S_SUCCESS != lReturn )
{
    Console::WriteLine("Failed SCardConnect\n");
    exit(1);  // Or other appropriate action.
}

// get reader serial no
LPBYTE   pbAtr = NULL;
DWORD    cByte = SCARD_AUTOALLOCATE;

lReturn = SCardGetAttrib(hCardHandle,
                SCARD_ATTR_VENDOR_IFD_SERIAL_NO,
                (LPBYTE)&pbAtr,
                &cByte);

if ( SCARD_S_SUCCESS != lReturn )
{
    Console::WriteLine("Failed to retrieve Reader Serial\n");
    exit(1);  // Or other appropriate action.
}

printf("serial no: %s", pbAtr);

SCardFreeMemory(hCardHandle, pbAtr); 

Is there a way to get readers serial number without connecting to card?

jww
  • 97,681
  • 90
  • 411
  • 885
vellotis
  • 829
  • 1
  • 12
  • 26
  • I think also a solution for me could be some other way to retrieve PCSC reader serial number. – vellotis Aug 05 '11 at 14:11
  • Have you tried passing `NULL` for hCardHandle? It seems `SCardGetAttrib` can return a `SCARD_ATTR_ICC_PRESENCE` value, which wouldn't make much sense if you had to have a card present first... (btw I don't know anything about this hardware or API, just browsed the docs a bit) – Merlyn Morgan-Graham Aug 08 '11 at 07:37
  • I examined a bit more this SCardGetAttrib, doc and source on the web. It still seems that for SCardGetAttrib I have to get hCardHandle. It doesn't make sense to pass NULL to SCardGetAttrib as hCardHandle. You somehow have to define which cardreaders attributes you want to get. By using SCardGetAtrrib this reader is accessed through CardHandle. I also tried to find IFD handle for win, but without success. In PCSC-Lite these attributes are accessed by using IFDHGetCapabilities. – vellotis Aug 08 '11 at 08:59
  • 1
    Browsed the API a bit more. It appears that, unless you can figure out a way to get a dummy card to pass in, you're going to have to have a card present to get the device name. Their API basically tries to cram too much into one function call. Maybe you could restructure your program to require this during an initialization routine. Some CD ripping software does similar things (requires a CD to be placed in the drive during setup to determine capabilities of the drive). Or if you can use PCSC-Lite on your platform... – Merlyn Morgan-Graham Aug 08 '11 at 18:54

2 Answers2

5

Maybe i'm a bit late - but anyway...

You can connect directly to the card reader using the SCARD_SHARE_DIRECT flag with SCardConnect. At least with us this works fine.. (we use a protocol flag of "0x00")

mtraut
  • 4,720
  • 3
  • 24
  • 33
  • It did help, but if we put a card on the card reader before calling SCardConnect to get reader's serial number, it cannot get serial number :( – Gintama Aug 08 '14 at 04:04
4

You should be using:

lReturn = SCardConnect(hResManager,szAvailRdr,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T1,
                            &hCardHandle,
                            &dwActProtocol);

Instead, try using:

lReturn = SCardConnect(hResManager,szAvailRdr,SCARD_SHARE_DIRECT,
                      NULL,
                      &hCardHandle,
                      NULL);

where szAvailRdr refers to the reader name (smartcard readername) and hCardHandle is a handle obtained before using scardconnect.

This should keep you going!

Druid
  • 6,423
  • 4
  • 41
  • 56