Merge pull request #2266 from Vinche59/smartcard

SmartCard
This commit is contained in:
Marc-André Moreau 2014-12-14 11:56:01 -05:00
commit 544c2f3e45

View File

@ -23,6 +23,13 @@
#ifndef _WIN32 #ifndef _WIN32
#ifdef __APPLE__
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <string.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
@ -136,6 +143,9 @@ static int g_StartedEventRefCount = 0;
static BOOL g_SCardAutoAllocate = FALSE; static BOOL g_SCardAutoAllocate = FALSE;
static BOOL g_PnP_Notification = TRUE; static BOOL g_PnP_Notification = TRUE;
#ifdef __MACOSX__
static unsigned int OSXVersion = 0;
#endif
/** /**
* g_LockTransactions: enable pcsc-lite SCardBeginTransaction/SCardEndTransaction. * g_LockTransactions: enable pcsc-lite SCardBeginTransaction/SCardEndTransaction.
@ -644,6 +654,9 @@ char* PCSC_ConvertReaderNameToWinSCard(const char* name)
* the index is a two digit zero-padded integer * the index is a two digit zero-padded integer
* the slot is a two digit zero-padded integer * the slot is a two digit zero-padded integer
*/ */
if (!name)
return NULL;
length = strlen(name); length = strlen(name);
if (length < 10) if (length < 10)
@ -1476,8 +1489,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
rgReaderStates[i].cbAtr = states[j].cbAtr; rgReaderStates[i].cbAtr = states[j].cbAtr;
CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[j].rgbAtr), PCSC_MAX_ATR_SIZE); CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[j].rgbAtr), PCSC_MAX_ATR_SIZE);
/* pcsc-lite puts an event count in the higher bits of dwEventState */
states[j].dwEventState &= 0xFFFF;
dwEventState = states[j].dwEventState & ~SCARD_STATE_CHANGED; dwEventState = states[j].dwEventState & ~SCARD_STATE_CHANGED;
if (dwEventState != rgReaderStates[i].dwCurrentState) if (dwEventState != rgReaderStates[i].dwCurrentState)
@ -1876,6 +1887,13 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard,
{ {
if (pcchReaderLenAlloc) if (pcchReaderLenAlloc)
{ {
#ifdef __MAXOSX__
/**
* Workaround for SCardStatus Bug in MAC OS X Yosemite
*/
if (OSXVersion == 0x10100000)
pcsc_cchReaderLen++;
#endif
*pMszReaderNames = (LPSTR) calloc(1, pcsc_cchReaderLen); *pMszReaderNames = (LPSTR) calloc(1, pcsc_cchReaderLen);
if (!*pMszReaderNames) if (!*pMszReaderNames)
@ -2558,6 +2576,97 @@ WINSCARDAPI LONG WINAPI PCSC_SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent)
return 0; return 0;
} }
#ifdef __MACOSX__
unsigned int determineMacOSXVersion()
{
int mib[2];
size_t len = 0;
char *kernelVersion = NULL;
char *tok = NULL;
unsigned int version = 0;
int majorVersion = 0;
int minorVersion = 0;
int patchVersion = 0;
int count = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_OSRELEASE;
sysctl(mib, 2, NULL, &len, NULL, 0);
kernelVersion = calloc(len, sizeof(char));
sysctl(mib, 2, kernelVersion, &len, NULL, 0);
tok = strtok(kernelVersion,".");
while (tok)
{
switch(count)
{
case 0:
majorVersion = atoi(tok);
break;
case 1:
minorVersion = atoi(tok);
break;
case 2:
patchVersion = atoi(tok);
break;
}
tok = strtok(NULL, ".");
count++;
}
/**
* Source : http://en.wikipedia.org/wiki/Darwin_(operating_system)
**/
if (majorVersion < 5)
{
if (minorVersion < 4)
version = 0x10000000;
else
version = 0x10010000;
}
else
{
switch (majorVersion)
{
case 5:
version = 0x10010000;
break;
case 6:
version = 0x10020000;
break;
case 7:
version = 0x10030000;
break;
case 8:
version = 0x10040000;
break;
case 9:
version = 0x10050000;
break;
case 10:
version = 0x10060000;
break;
case 11:
version = 0x10070000;
break;
case 12:
version = 0x10080000;
break;
case 13:
version = 0x10090000;
break;
default:
version = 0x10100000;
break;
}
version |= (minorVersion << 8) | (patchVersion);
}
free(kernelVersion);
return version;
}
#endif
SCardApiFunctionTable PCSC_SCardApiFunctionTable = SCardApiFunctionTable PCSC_SCardApiFunctionTable =
{ {
0, /* dwVersion */ 0, /* dwVersion */
@ -2681,6 +2790,7 @@ int PCSC_InitializeSCardApi(void)
#endif #endif
#ifdef __MACOSX__ #ifdef __MACOSX__
g_PCSCModule = LoadLibraryA("/System/Library/Frameworks/PCSC.framework/PCSC"); g_PCSCModule = LoadLibraryA("/System/Library/Frameworks/PCSC.framework/PCSC");
OSXVersion = determineMacOSXVersion();
#else #else
g_PCSCModule = LoadLibraryA("libpcsclite.so.1"); g_PCSCModule = LoadLibraryA("libpcsclite.so.1");
@ -2702,7 +2812,14 @@ int PCSC_InitializeSCardApi(void)
g_PCSC.pfnSCardEndTransaction = (void*) GetProcAddress(g_PCSCModule, "SCardEndTransaction"); g_PCSC.pfnSCardEndTransaction = (void*) GetProcAddress(g_PCSCModule, "SCardEndTransaction");
g_PCSC.pfnSCardStatus = (void*) GetProcAddress(g_PCSCModule, "SCardStatus"); g_PCSC.pfnSCardStatus = (void*) GetProcAddress(g_PCSCModule, "SCardStatus");
g_PCSC.pfnSCardGetStatusChange = (void*) GetProcAddress(g_PCSCModule, "SCardGetStatusChange"); g_PCSC.pfnSCardGetStatusChange = (void*) GetProcAddress(g_PCSCModule, "SCardGetStatusChange");
#ifdef __MACOSX__
if (OSXVersion >= 0x10050600)
g_PCSC.pfnSCardControl = (void*) GetProcAddress(g_PCSCModule, "SCardControl132");
else
g_PCSC.pfnSCardControl = (void*) GetProcAddress(g_PCSCModule, "SCardControl");
#else
g_PCSC.pfnSCardControl = (void*) GetProcAddress(g_PCSCModule, "SCardControl"); g_PCSC.pfnSCardControl = (void*) GetProcAddress(g_PCSCModule, "SCardControl");
#endif
g_PCSC.pfnSCardTransmit = (void*) GetProcAddress(g_PCSCModule, "SCardTransmit"); g_PCSC.pfnSCardTransmit = (void*) GetProcAddress(g_PCSCModule, "SCardTransmit");
g_PCSC.pfnSCardListReaderGroups = (void*) GetProcAddress(g_PCSCModule, "SCardListReaderGroups"); g_PCSC.pfnSCardListReaderGroups = (void*) GetProcAddress(g_PCSCModule, "SCardListReaderGroups");
g_PCSC.pfnSCardListReaders = (void*) GetProcAddress(g_PCSCModule, "SCardListReaders"); g_PCSC.pfnSCardListReaders = (void*) GetProcAddress(g_PCSCModule, "SCardListReaders");
@ -2727,4 +2844,5 @@ int PCSC_InitializeSCardApi(void)
return 1; return 1;
} }
#endif #endif