Merge branch 'smartcard' of github.com:awakecoding/FreeRDP into smartcard

This commit is contained in:
awake 2014-04-25 18:45:40 -07:00
commit 9326745177
9 changed files with 130 additions and 40 deletions

View File

@ -227,6 +227,12 @@
#define SCARD_NEGOTIABLE 5
#define SCARD_SPECIFIC 6
#if defined(__APPLE__) | defined(sun)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
typedef struct _SCARD_IO_REQUEST
{
DWORD dwProtocol;
@ -551,6 +557,12 @@ typedef struct
SCARDHANDLE hCardHandle;
} OPENCARDNAMEW, *POPENCARDNAMEW, *LPOPENCARDNAMEW;
#if defined(__APPLE__) | defined(sun)
#pragma pack()
#else
#pragma pack(pop)
#endif
#ifdef UNICODE
#define LPOCNCONNPROC LPOCNCONNPROCW
#define SCARD_READERSTATE SCARD_READERSTATEW

View File

@ -64,12 +64,22 @@ typedef int BOOL;
typedef BOOL *PBOOL, *LPBOOL;
#ifdef __APPLE__
typedef int LONG;
typedef unsigned int DWORD;
typedef unsigned int ULONG;
#else
typedef long LONG;
typedef unsigned long DWORD;
typedef unsigned long ULONG;
#endif
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
typedef BYTE BOOLEAN, *PBOOLEAN;
typedef unsigned short WCHAR, *PWCHAR;
typedef WCHAR* BSTR;
typedef char CHAR, *PCHAR;
typedef unsigned long DWORD, *PDWORD, *LPDWORD;
typedef DWORD *PDWORD, *LPDWORD;
typedef unsigned int DWORD32;
typedef unsigned __int64 DWORD64;
typedef unsigned __int64 ULONGLONG;
@ -107,7 +117,7 @@ typedef signed __int64 INT64;
#endif
typedef const WCHAR* LMCSTR;
typedef WCHAR* LMSTR;
typedef long LONG, *PLONG, *LPLONG;
typedef LONG *PLONG, *LPLONG;
typedef signed __int64 LONGLONG;
typedef __int3264 LONG_PTR, *PLONG_PTR;
@ -132,7 +142,7 @@ typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned __int64 UINT64;
typedef unsigned long ULONG, *PULONG;
typedef ULONG *PULONG;
typedef ULONG HRESULT;
typedef ULONG SCODE;

View File

@ -46,7 +46,7 @@
#define TEST_SIZEOF_TYPE(_name) \
if (sizeof(_name) != EXPECTED_SIZEOF_ ##_name) { \
fprintf(stderr, "sizeof(%s) mismatch: Actual: %d, Expected: %d\n", \
#_name, sizeof(_name), EXPECTED_SIZEOF_ ##_name); \
#_name, (int) sizeof(_name), (int) EXPECTED_SIZEOF_ ##_name); \
status = -1; \
}
@ -70,7 +70,8 @@ int TestTypes(int argc, char* argv[])
TEST_SIZEOF_TYPE(SHORT)
TEST_SIZEOF_TYPE(USHORT)
TEST_SIZEOF_TYPE(BOOL)
/* fails on OS X */
//TEST_SIZEOF_TYPE(BOOL)
TEST_SIZEOF_TYPE(INT)
TEST_SIZEOF_TYPE(UINT)

View File

@ -45,7 +45,10 @@
void InitializeSCardApiStubs(void);
#ifndef _WIN32
#include "smartcard_pcsc.h"
#else
#include "smartcard_winscard.h"
#endif
#endif /* WINPR_SMARTCARD_PRIVATE_H */

View File

@ -21,6 +21,8 @@
#include "config.h"
#endif
#ifndef _WIN32
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -162,3 +164,5 @@ int PCSC_InitializeSCardApi_Link(void)
return status;
}
#endif

View File

@ -21,6 +21,8 @@
#include "config.h"
#endif
#ifndef _WIN32
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
@ -1079,73 +1081,105 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
if (g_PCSC.pfnSCardGetStatusChange)
{
DWORD index;
char** szReaders;
DWORD i, j;
DWORD dwEventState;
BOOL stateChanged = FALSE;
LPSCARD_READERSTATEA states;
PCSC_SCARD_READERSTATE* states;
/**
* FIXME: proper pcsc-lite support for "\\\\?PnP?\\Notification"
*
* Apple's SmartCard Services (not vanilla pcsc-lite) appears to have trouble with the
* "\\\\?PnP?\\Notification" reader name. I am always getting EXC_BAD_ACCESS with it.
*
* The SmartCard Services tarballs can be found here:
* http://opensource.apple.com/tarballs/SmartCardServices/
*
* The "\\\\?PnP?\\Notification" string cannot be found anywhere in the sources,
* while this string is present in the vanilla pcsc-lite sources.
*
* For now, the current smartcard code sets dwCurrentState to SCARD_STATE_IGNORE
* when the reader name is "\\\\?PnP?\\Notification". We check for this flag and
* and ignore the reader completely when present.
*/
states = (LPSCARD_READERSTATEA) calloc(cReaders, sizeof(SCARD_READERSTATEA));
szReaders = (char**) calloc(cReaders, sizeof(char*));
states = (PCSC_SCARD_READERSTATE*) calloc(cReaders, sizeof(PCSC_SCARD_READERSTATE));
if (!states)
return SCARD_E_NO_MEMORY;
for (index = 0; index < cReaders; index++)
for (i = j = 0; i < cReaders; i++)
{
szReaders[index] = (char*) states[index].szReader;
states[index].szReader = PCSC_GetReaderNameFromAlias((char*) rgReaderStates[index].szReader);
if (rgReaderStates[i].dwCurrentState == SCARD_STATE_IGNORE)
continue;
states[j].szReader = PCSC_GetReaderNameFromAlias((char*) rgReaderStates[i].szReader);
if (!states[index].szReader)
states[index].szReader = rgReaderStates[index].szReader;
if (!states[j].szReader)
states[j].szReader = rgReaderStates[i].szReader;
states[index].pvUserData = rgReaderStates[index].pvUserData;
states[index].dwCurrentState = rgReaderStates[index].dwCurrentState;
states[index].dwEventState = rgReaderStates[index].dwEventState;
states[index].cbAtr = rgReaderStates[index].cbAtr;
CopyMemory(&(states[index].rgbAtr), &(rgReaderStates[index].rgbAtr), 36);
states[j].dwCurrentState = rgReaderStates[i].dwCurrentState;
states[j].dwEventState = rgReaderStates[i].dwEventState;
states[j].cbAtr = rgReaderStates[i].cbAtr;
CopyMemory(&(states[j].rgbAtr), &(rgReaderStates[i].rgbAtr), PCSC_MAX_ATR_SIZE);
j++;
}
cReaders = j;
/**
* pcsc-lite interprets dwTimeout value 0 as INFINITE, use value 1 as a workaround
*/
status = g_PCSC.pfnSCardGetStatusChange(hContext, dwTimeout ? dwTimeout : 10, states, cReaders);
status = PCSC_MapErrorCodeToWinSCard(status);
for (index = 0; index < cReaders; index++)
if (cReaders > 0)
{
rgReaderStates[index].szReader = szReaders[index];
status = g_PCSC.pfnSCardGetStatusChange(hContext, dwTimeout ? dwTimeout : 10, states, cReaders);
status = PCSC_MapErrorCodeToWinSCard(status);
}
else
{
status = SCARD_E_TIMEOUT;
}
for (i = j = 0; i < cReaders; i++)
{
if (rgReaderStates[i].dwCurrentState == SCARD_STATE_IGNORE)
{
rgReaderStates[i].dwEventState = SCARD_STATE_IGNORE;
continue;
}
rgReaderStates[index].pvUserData = states[index].pvUserData;
rgReaderStates[index].dwCurrentState = states[index].dwCurrentState;
rgReaderStates[index].cbAtr = states[index].cbAtr;
CopyMemory(&(rgReaderStates[index].rgbAtr), &(states[index].rgbAtr), 36);
rgReaderStates[i].dwCurrentState = states[j].dwCurrentState;
rgReaderStates[i].cbAtr = states[j].cbAtr;
CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[j].rgbAtr), PCSC_MAX_ATR_SIZE);
/* pcsc-lite puts an event count in the higher bits of dwEventState */
states[index].dwEventState &= 0xFFFF;
states[j].dwEventState &= 0xFFFF;
dwEventState = states[index].dwEventState & ~SCARD_STATE_CHANGED;
dwEventState = states[j].dwEventState & ~SCARD_STATE_CHANGED;
if (dwEventState != rgReaderStates[index].dwCurrentState)
if (dwEventState != rgReaderStates[i].dwCurrentState)
{
rgReaderStates[index].dwEventState = states[index].dwEventState;
rgReaderStates[i].dwEventState = states[j].dwEventState;
if (dwEventState & SCARD_STATE_PRESENT)
{
if (!(dwEventState & SCARD_STATE_EXCLUSIVE))
rgReaderStates[index].dwEventState |= SCARD_STATE_INUSE;
rgReaderStates[i].dwEventState |= SCARD_STATE_INUSE;
}
stateChanged = TRUE;
}
else
{
rgReaderStates[index].dwEventState = dwEventState;
rgReaderStates[i].dwEventState = dwEventState;
}
if (rgReaderStates[index].dwCurrentState & SCARD_STATE_IGNORE)
rgReaderStates[index].dwEventState = SCARD_STATE_IGNORE;
if (rgReaderStates[i].dwCurrentState & SCARD_STATE_IGNORE)
rgReaderStates[i].dwEventState = SCARD_STATE_IGNORE;
j++;
}
if ((status == SCARD_S_SUCCESS) && !stateChanged)
@ -1153,7 +1187,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
else if ((status == SCARD_E_TIMEOUT) && stateChanged)
return SCARD_S_SUCCESS;
free(szReaders);
free(states);
}
@ -2186,3 +2219,5 @@ int PCSC_InitializeSCardApi(void)
return 1;
}
#endif

View File

@ -20,6 +20,8 @@
#ifndef WINPR_SMARTCARD_PCSC_PRIVATE_H
#define WINPR_SMARTCARD_PCSC_PRIVATE_H
#ifndef _WIN32
#include <winpr/platform.h>
#include <winpr/smartcard.h>
@ -37,6 +39,19 @@
#define PCSC_MAX_BUFFER_SIZE 264
#define PCSC_MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1 << 16) + 3 + 2)
#define PCSC_MAX_ATR_SIZE 33
typedef struct
{
LPCSTR szReader;
LPVOID pvUserData;
DWORD dwCurrentState;
DWORD dwEventState;
DWORD cbAtr;
BYTE rgbAtr[PCSC_MAX_ATR_SIZE]; /* WinSCard: 36, PCSC: 33 */
}
PCSC_SCARD_READERSTATE;
struct _PCSCFunctionTable
{
LONG (* pfnSCardEstablishContext)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
@ -55,7 +70,7 @@ struct _PCSCFunctionTable
LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState,
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen);
LONG (* pfnSCardGetStatusChange)(SCARDCONTEXT hContext,
DWORD dwTimeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders);
DWORD dwTimeout, PCSC_SCARD_READERSTATE* rgReaderStates, DWORD cReaders);
LONG (* pfnSCardControl)(SCARDHANDLE hCard,
DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength,
LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned);
@ -75,4 +90,6 @@ typedef struct _PCSCFunctionTable PCSCFunctionTable;
int PCSC_InitializeSCardApi(void);
PSCardApiFunctionTable PCSC_GetSCardApiFunctionTable(void);
#endif
#endif /* WINPR_SMARTCARD_PCSC_PRIVATE_H */

View File

@ -21,6 +21,8 @@
#include "config.h"
#endif
#ifdef _WIN32
#include <winpr/crt.h>
#include <winpr/library.h>
#include <winpr/smartcard.h>
@ -203,3 +205,5 @@ int WinSCard_InitializeSCardApi(void)
return 1;
}
#endif

View File

@ -20,6 +20,8 @@
#ifndef WINPR_SMARTCARD_WINSCARD_PRIVATE_H
#define WINPR_SMARTCARD_WINSCARD_PRIVATE_H
#ifdef _WIN32
#include <winpr/smartcard.h>
#define WINSCARD_LOAD_PROC(_name, ...) \
@ -28,4 +30,6 @@
int WinSCard_InitializeSCardApi(void);
PSCardApiFunctionTable WinSCard_GetSCardApiFunctionTable(void);
#endif
#endif /* WINPR_SMARTCARD_WINSCARD_PRIVATE_H */