OS X Yosemite PCSC SCardStatus Problem
| Originator: | vincent.sourin | ||
| Number: | rdar://19085605 | Date Originated: | 26-Nov-2014 04:30 PM |
| Status: | Open | Resolved: | |
| Product: | OS X | Product Version: | 10.10 |
| Classification: | Serious Bug | Reproducible: | Always |
Summary:
ScardStatus calls return bad length for reader (first call with NULL buffer) and then failed with SCARD_E_INSUFFICIENT_BUFFER (0x80100008)
Steps to Reproduce:
1. Install Xcode 6.1
2. Create a new Command-Line Project
3. Add main.c into Project
4. Plug an USB smartcard reader and insert a smartcard
5. Compile & Run project
Expected Results:
Program should print information about the card
Actual Results:
When allocating a buffer of size specified by the first SCardStatus call, the second call to SCardStatus failed with SCARD_E_INSUFFICIENT_BUFFER (0x80100008)
file : main.c
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <PCSC/wintypes.h>
#include <PCSC/winscard.h>
int main(int argc, const char * argv[]) {
SCARDCONTEXT hContext;
char *szChosenReader;
char *mszReaders;
DWORD err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
if (err != 0) {
printf("SCardEstablishContext : %08x\n", err);
} else {
DWORD cchReaders = 0;
err = SCardListReaders(hContext, "SCard$AllReaders", NULL, &cchReaders);
if (err != 0) {
printf("SCardListReaders : %08x\n", err);
} else {
mszReaders = calloc(cchReaders, sizeof(char));
if (mszReaders == NULL) {
perror("calloc for SCardListReaders");
} else {
err = SCardListReaders(hContext, "SCard$AllReaders", mszReaders, &cchReaders);
if (err != 0) {
printf("SCardListReaders : %08x\n", err);
} else if ('\0' == *mszReaders) {
printf("There are no smart card readers. Please plug one in.\n");
} else {
DWORD cReaders = 0;
for (char *readerName = mszReaders; *readerName != '\0'; readerName += strlen(readerName) + 1) {
printf("Found reader %s\n", readerName);
cReaders++;
}
szChosenReader = mszReaders;
SCARD_READERSTATE readerState;
memset(&readerState, 0, sizeof(SCARD_READERSTATE));
readerState.szReader = szChosenReader;
readerState.dwCurrentState = SCARD_STATE_UNAWARE;
err = SCardGetStatusChange(hContext, 0, &readerState, 1);
if (err != 0) {
printf("SCardGetStatusChange : %08x\n", err);
} else if (! (SCARD_STATE_PRESENT & readerState.dwEventState)) {
printf("Card is not present in %s. Please insert smart card.\n", szChosenReader);
} else {
SCARDHANDLE hCard;
DWORD dwActiveProtocol;
err = SCardConnect(hContext, szChosenReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY, &hCard, &dwActiveProtocol);
if (err != 0) {
printf("SCardConnect: %08x\n", err);
} else {
DWORD chReaderLen;
err = SCardStatus(hCard, NULL, &chReaderLen, NULL, NULL, NULL, NULL);
if (err != 0) {
printf("SCardStatus without buf: %08x\n", err);
} else {
LPTSTR mszReaderNames = calloc(chReaderLen, sizeof(char));
if (NULL == mszReaderNames) {
perror("calloc for SCardStatus");
} else {
DWORD dwState;
DWORD dwProtocol;
BYTE atr[32];
DWORD cbAtrLen = 32;
err = SCardStatus(hCard, mszReaderNames, &chReaderLen, &dwState, &dwProtocol, atr, &cbAtrLen);
if (err != 0) {
printf("SCardStatus with buf: %08x\n", err);
} else {
printf("State: %d, protocol: %d, ATR length: %d\n", dwState, dwProtocol, cbAtrLen);
BOOL gotMultiStringEnd = 0;
for (DWORD i = 0; i < chReaderLen; i += strlen(mszReaderNames + i) + 1) {
char *readerName = mszReaderNames + i;
if ('\0' == *readerName) {
gotMultiStringEnd = 1;
break;
}
printf("Name of reader: %s\n", readerName);
}
if (! gotMultiStringEnd) {
fprintf(stderr, "SCardStatus reader names multistring did not end with empty string!\n");
}
}
free(mszReaderNames);
}
}
err = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
if (err != 0) {
printf("SCardDisconnect: %08x\n", err);
}
}
}
}
free(mszReaders);
}
}
}
err = SCardReleaseContext(hContext);
if (err != 0) printf("SCardReleaseContext: %08x\n", err);
return 0;
}
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!