channels/smartcard: experiment with multiple card contexts
This commit is contained in:
parent
1359d7c27e
commit
f5bfb98aca
@ -553,14 +553,14 @@ static UINT32 smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
|
||||
status = ret.ReturnCode = SCardConnectA(operation->hContext, (char*) call->szReader, call->Common.dwShareMode,
|
||||
call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), operation->hContext);
|
||||
smartcard_scard_handle_native_to_redir(smartcard, &(ret.hCard), hCard);
|
||||
|
||||
smartcard_trace_connect_return(smartcard, &ret);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = smartcard_pack_connect_return(smartcard, irp->output, &ret);
|
||||
|
||||
if (status)
|
||||
@ -605,14 +605,14 @@ static UINT32 smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE
|
||||
status = ret.ReturnCode = SCardConnectW(operation->hContext, (WCHAR*) call->szReader, call->Common.dwShareMode,
|
||||
call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), operation->hContext);
|
||||
smartcard_scard_handle_native_to_redir(smartcard, &(ret.hCard), hCard);
|
||||
|
||||
smartcard_trace_connect_return(smartcard, &ret);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = smartcard_pack_connect_return(smartcard, irp->output, &ret);
|
||||
|
||||
if (status)
|
||||
|
@ -1890,6 +1890,12 @@ void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, GetAttrib_Re
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG, "pbAttr: %.*s", ret->cbAttrLen, (char*) ret->pbAttr);
|
||||
}
|
||||
else if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE)
|
||||
{
|
||||
UINT32 dwProtocolType = *((UINT32*) ret->pbAttr);
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG, "dwProtocolType: %s (0x%04X)",
|
||||
SCardGetProtocolString(dwProtocolType), dwProtocolType);
|
||||
}
|
||||
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG, "}");
|
||||
}
|
||||
|
@ -103,16 +103,17 @@
|
||||
|
||||
struct _PCSC_SCARDCONTEXT
|
||||
{
|
||||
SCARDCONTEXT hContext;
|
||||
SCARDHANDLE hCard;
|
||||
CRITICAL_SECTION lock;
|
||||
SCARDCONTEXT hContext;
|
||||
DWORD dwCardHandleCount;
|
||||
};
|
||||
typedef struct _PCSC_SCARDCONTEXT PCSC_SCARDCONTEXT;
|
||||
|
||||
struct _PCSC_SCARDHANDLE
|
||||
{
|
||||
SCARDCONTEXT hContext;
|
||||
CRITICAL_SECTION lock;
|
||||
SCARDCONTEXT hSharedContext;
|
||||
SCARDCONTEXT hPrivateContext;
|
||||
};
|
||||
typedef struct _PCSC_SCARDHANDLE PCSC_SCARDHANDLE;
|
||||
|
||||
@ -147,6 +148,9 @@ const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(PC
|
||||
const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardRawPci = { PCSC_SCARD_PROTOCOL_RAW, sizeof(PCSC_SCARD_IO_REQUEST) };
|
||||
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPCVOID pvMem);
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope,
|
||||
LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext);
|
||||
|
||||
LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode)
|
||||
{
|
||||
@ -313,10 +317,15 @@ void PCSC_ReleaseCardContext(SCARDCONTEXT hContext)
|
||||
pContext = PCSC_GetCardContextData(hContext);
|
||||
|
||||
if (!pContext)
|
||||
{
|
||||
printf("PCSC_ReleaseCardContext: null pContext!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&(pContext->lock));
|
||||
|
||||
printf("PCSC_ReleaseCardContext: %d\n", pContext->dwCardHandleCount);
|
||||
|
||||
free(pContext);
|
||||
|
||||
if (!g_CardContexts)
|
||||
@ -383,38 +392,35 @@ SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard)
|
||||
if (!pCard)
|
||||
return 0;
|
||||
|
||||
return pCard->hContext;
|
||||
return pCard->hPrivateContext;
|
||||
}
|
||||
|
||||
BOOL PCSC_IsCardHandleConnected(SCARDCONTEXT hContext)
|
||||
{
|
||||
PCSC_SCARDCONTEXT* pContext;
|
||||
|
||||
pContext = PCSC_GetCardContextData(hContext);
|
||||
|
||||
if (!pContext)
|
||||
return FALSE;
|
||||
|
||||
return pContext->hCard ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard)
|
||||
PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hSharedContext, SCARDCONTEXT hPrivateContext, SCARDHANDLE hCard)
|
||||
{
|
||||
PCSC_SCARDHANDLE* pCard;
|
||||
PCSC_SCARDCONTEXT* pContext;
|
||||
|
||||
pContext = PCSC_GetCardContextData(hSharedContext);
|
||||
|
||||
if (!pContext)
|
||||
{
|
||||
printf("PCSC_ConnectCardHandle: null pContext!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pCard = (PCSC_SCARDHANDLE*) calloc(1, sizeof(PCSC_SCARDHANDLE));
|
||||
|
||||
if (!pCard)
|
||||
return NULL;
|
||||
|
||||
pCard->hContext = hContext;
|
||||
pCard->hSharedContext = hSharedContext;
|
||||
pCard->hPrivateContext = hPrivateContext;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&(pCard->lock), 4000);
|
||||
|
||||
pContext = PCSC_GetCardContextData(hContext);
|
||||
pContext->dwCardHandleCount++;
|
||||
|
||||
pContext->hCard = hCard;
|
||||
printf("PCSC_ConnectCardHandle: %d\n", pContext->dwCardHandleCount);
|
||||
|
||||
if (!g_CardHandles)
|
||||
g_CardHandles = ListDictionary_New(TRUE);
|
||||
@ -436,9 +442,9 @@ void PCSC_DisconnectCardHandle(SCARDHANDLE hCard)
|
||||
|
||||
DeleteCriticalSection(&(pCard->lock));
|
||||
|
||||
pContext = PCSC_GetCardContextData(pCard->hContext);
|
||||
pContext = PCSC_GetCardContextData(pCard->hSharedContext);
|
||||
|
||||
pContext->hCard = 0;
|
||||
PCSC_SCardReleaseContext_Internal(pCard->hPrivateContext);
|
||||
|
||||
free(pCard);
|
||||
|
||||
@ -446,6 +452,16 @@ void PCSC_DisconnectCardHandle(SCARDHANDLE hCard)
|
||||
return;
|
||||
|
||||
ListDictionary_Remove(g_CardHandles, (void*) hCard);
|
||||
|
||||
if (!pContext)
|
||||
{
|
||||
printf("PCSC_DisconnectCardHandle: null pContext!");
|
||||
return;
|
||||
}
|
||||
|
||||
pContext->dwCardHandleCount--;
|
||||
|
||||
printf("PCSC_DisconnectCardHandle: %d\n", pContext->dwCardHandleCount);
|
||||
}
|
||||
|
||||
BOOL PCSC_LockCardHandle(SCARDHANDLE hCard)
|
||||
@ -869,7 +885,7 @@ void* PCSC_SCardAllocMemory(SCARDCONTEXT hContext, size_t size)
|
||||
* Standard Windows Smart Card API (PCSC)
|
||||
*/
|
||||
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope,
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope,
|
||||
LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
|
||||
{
|
||||
LONG status = SCARD_S_SUCCESS;
|
||||
@ -883,13 +899,23 @@ WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope,
|
||||
status = (LONG) g_PCSC.pfnSCardEstablishContext(pcsc_dwScope, pvReserved1, pvReserved2, phContext);
|
||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope,
|
||||
LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
|
||||
{
|
||||
LONG status = SCARD_S_SUCCESS;
|
||||
|
||||
status = PCSC_SCardEstablishContext_Internal(dwScope, pvReserved1, pvReserved2, phContext);
|
||||
|
||||
if (status == SCARD_S_SUCCESS)
|
||||
PCSC_EstablishCardContext(*phContext);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardReleaseContext(SCARDCONTEXT hContext)
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext)
|
||||
{
|
||||
LONG status = SCARD_S_SUCCESS;
|
||||
|
||||
@ -905,7 +931,16 @@ WINSCARDAPI LONG WINAPI PCSC_SCardReleaseContext(SCARDCONTEXT hContext)
|
||||
status = (LONG) g_PCSC.pfnSCardReleaseContext(hContext);
|
||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||
|
||||
if (!status)
|
||||
return status;
|
||||
}
|
||||
|
||||
WINSCARDAPI LONG WINAPI PCSC_SCardReleaseContext(SCARDCONTEXT hContext)
|
||||
{
|
||||
LONG status = SCARD_S_SUCCESS;
|
||||
|
||||
status = PCSC_SCardReleaseContext_Internal(hContext);
|
||||
|
||||
if (status != SCARD_S_SUCCESS)
|
||||
PCSC_ReleaseCardContext(hContext);
|
||||
|
||||
return status;
|
||||
@ -1612,6 +1647,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext,
|
||||
{
|
||||
char* szReaderPCSC;
|
||||
LONG status = SCARD_S_SUCCESS;
|
||||
SCARDCONTEXT hPrivateContext = 0;
|
||||
PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD) dwShareMode;
|
||||
PCSC_DWORD pcsc_dwPreferredProtocols = 0;
|
||||
PCSC_DWORD pcsc_dwActiveProtocol = 0;
|
||||
@ -1619,8 +1655,10 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext,
|
||||
if (!g_PCSC.pfnSCardConnect)
|
||||
return SCARD_E_NO_SERVICE;
|
||||
|
||||
if (PCSC_IsCardHandleConnected(hContext))
|
||||
return SCARD_E_SHARING_VIOLATION;
|
||||
status = PCSC_SCardEstablishContext_Internal(SCARD_SCOPE_SYSTEM, NULL, NULL, &hPrivateContext);
|
||||
|
||||
if (status != SCARD_S_SUCCESS)
|
||||
return status;
|
||||
|
||||
szReaderPCSC = PCSC_GetReaderNameFromAlias((char*) szReader);
|
||||
|
||||
@ -1629,15 +1667,19 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext,
|
||||
|
||||
pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
|
||||
|
||||
status = (LONG) g_PCSC.pfnSCardConnect(hContext, szReaderPCSC,
|
||||
status = (LONG) g_PCSC.pfnSCardConnect(hPrivateContext, szReaderPCSC,
|
||||
pcsc_dwShareMode, pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol);
|
||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||
|
||||
if (status == SCARD_S_SUCCESS)
|
||||
{
|
||||
PCSC_ConnectCardHandle(hContext, *phCard);
|
||||
PCSC_ConnectCardHandle(hContext, hPrivateContext, *phCard);
|
||||
*pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwActiveProtocol);
|
||||
}
|
||||
else
|
||||
{
|
||||
PCSC_SCardReleaseContext(hPrivateContext);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -2673,7 +2715,7 @@ extern int PCSC_InitializeSCardApi_Link(void);
|
||||
int PCSC_InitializeSCardApi(void)
|
||||
{
|
||||
/* Disable pcsc-lite's (poor) blocking so we can handle it ourselves */
|
||||
//SetEnvironmentVariableA("PCSCLITE_NO_BLOCKING", "1");
|
||||
SetEnvironmentVariableA("PCSCLITE_NO_BLOCKING", "1");
|
||||
|
||||
#ifndef DISABLE_PCSC_LINK
|
||||
if (PCSC_InitializeSCardApi_Link() >= 0)
|
||||
|
Loading…
Reference in New Issue
Block a user