Merge pull request #2195 from Vinche59/master
Implementation of SCARD_IOCTL_LOCATECARDSBYATRA & Modification to make Smartcard reader with PinPad work
This commit is contained in:
commit
b77a3bc1bc
@ -1032,6 +1032,108 @@ static UINT32 smartcard_AccessStartedEvent_Call(SMARTCARD_DEVICE* smartcard, SMA
|
||||
return status;
|
||||
}
|
||||
|
||||
static UINT32 smartcard_LocateCardsByATRA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, LocateCardsByATRA_Call* call)
|
||||
{
|
||||
LONG status;
|
||||
IRP* irp = operation->irp;
|
||||
|
||||
if (!call)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
status = smartcard_unpack_locate_cards_by_atr_a_call(smartcard, irp->input, call);
|
||||
smartcard_trace_locate_cards_by_atr_a_call(smartcard, call);
|
||||
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext));
|
||||
return status;
|
||||
}
|
||||
|
||||
static UINT32 smartcard_LocateCardsByATRA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, LocateCardsByATRA_Call* call)
|
||||
{
|
||||
LONG status;
|
||||
DWORD index, index2, index3;
|
||||
BOOL equal;
|
||||
GetStatusChange_Return ret;
|
||||
LPSCARD_READERSTATEA rgReaderState2 = NULL;
|
||||
LPSCARD_READERSTATEA states = NULL;
|
||||
IRP* irp = operation->irp;
|
||||
|
||||
states = calloc(call->cReaders, sizeof(SCARD_READERSTATEA));
|
||||
for (index = 0; index < call->cReaders; index++)
|
||||
{
|
||||
states[index].szReader = (LPCSTR) call->rgReaderStates[index].szReader;
|
||||
states[index].dwCurrentState = call->rgReaderStates[index].Common.dwCurrentState;
|
||||
states[index].dwEventState = call->rgReaderStates[index].Common.dwEventState;
|
||||
states[index].cbAtr = call->rgReaderStates[index].Common.cbAtr;
|
||||
CopyMemory(&(states[index].rgbAtr), &(call->rgReaderStates[index].Common.rgbAtr), 36);
|
||||
}
|
||||
|
||||
|
||||
status = ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, 0x000001F4, states, call->cReaders);
|
||||
|
||||
if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED))
|
||||
{
|
||||
call->cReaders=0;
|
||||
}
|
||||
|
||||
for (index = 0; index < call->cAtrs; index++)
|
||||
{
|
||||
for (index2 = 0; index2 < call->cReaders; index2++)
|
||||
{
|
||||
equal = TRUE;
|
||||
for (index3 = 0; index3 < call->rgAtrMasks[index].cbAtr; index3++)
|
||||
{
|
||||
if ((call->rgAtrMasks[index].rgbAtr[index3] & call->rgAtrMasks[index].rgbMask[index3]) !=
|
||||
(states[index2].rgbAtr[index3] & call->rgAtrMasks[index].rgbMask[index3]))
|
||||
{
|
||||
equal = FALSE;
|
||||
break;
|
||||
}
|
||||
if (equal)
|
||||
{
|
||||
states[index2].dwEventState |= SCARD_STATE_ATRMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret.cReaders = call->cReaders;
|
||||
ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return));
|
||||
|
||||
for (index = 0; index < ret.cReaders; index++)
|
||||
{
|
||||
rgReaderState2 = &states[index];
|
||||
ret.rgReaderStates[index].dwCurrentState = rgReaderState2->dwCurrentState;
|
||||
ret.rgReaderStates[index].dwEventState = rgReaderState2->dwEventState;
|
||||
ret.rgReaderStates[index].cbAtr = rgReaderState2->cbAtr;
|
||||
CopyMemory(&(ret.rgReaderStates[index].rgbAtr), &(rgReaderState2->rgbAtr), 32);
|
||||
}
|
||||
free(states);
|
||||
|
||||
smartcard_trace_get_status_change_return(smartcard, &ret, FALSE);
|
||||
status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (call->rgReaderStates)
|
||||
{
|
||||
for (index = 0; index < call->cReaders; index++)
|
||||
{
|
||||
rgReaderState2 = (LPSCARD_READERSTATEA) &call->rgReaderStates[index];
|
||||
|
||||
if (rgReaderState2->szReader) {
|
||||
free((void*) rgReaderState2->szReader);
|
||||
rgReaderState2->szReader = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(call->rgReaderStates);
|
||||
call->rgReaderStates = NULL;
|
||||
}
|
||||
|
||||
free(ret.rgReaderStates);
|
||||
return ret.ReturnCode;
|
||||
}
|
||||
|
||||
UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation)
|
||||
{
|
||||
UINT32 status;
|
||||
@ -1264,7 +1366,8 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCAR
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_LOCATECARDSBYATRA:
|
||||
status = SCARD_F_INTERNAL_ERROR;
|
||||
call = calloc(1, sizeof(LocateCardsByATRA_Call));
|
||||
status = smartcard_LocateCardsByATRA_Decode(smartcard, operation, (LocateCardsByATRA_Call*) call);
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_LOCATECARDSBYATRW:
|
||||
@ -1530,7 +1633,7 @@ UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_LOCATECARDSBYATRA:
|
||||
result = SCARD_F_INTERNAL_ERROR;
|
||||
result = smartcard_LocateCardsByATRA_Call(smartcard, operation, (LocateCardsByATRA_Call*) call);
|
||||
break;
|
||||
|
||||
case SCARD_IOCTL_LOCATECARDSBYATRW:
|
||||
|
@ -2471,3 +2471,240 @@ void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, Transmit_Retur
|
||||
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG, "}");
|
||||
}
|
||||
|
||||
UINT32 smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsByATRA_Call* call)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
UINT32 status;
|
||||
UINT32 offset;
|
||||
UINT32 maxCount;
|
||||
UINT32 szReaderNdrPtr;
|
||||
UINT32 rgReaderStatesNdrPtr;
|
||||
UINT32 rgAtrMasksNdrPtr;
|
||||
LPSCARD_READERSTATEA readerState;
|
||||
|
||||
call->rgReaderStates = NULL;
|
||||
|
||||
status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext));
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 16)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "LocateCardsByATRA_Call is too short: %d",
|
||||
(int) Stream_GetRemainingLength(s));
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, call->cAtrs);
|
||||
Stream_Read_UINT32(s, rgAtrMasksNdrPtr);
|
||||
Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */
|
||||
Stream_Read_UINT32(s, rgReaderStatesNdrPtr); /* rgReaderStatesNdrPtr (4 bytes) */
|
||||
|
||||
status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext));
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "LocateCardsByATRA_Call is too short: %d",
|
||||
(int) Stream_GetRemainingLength(s));
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs))
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN,
|
||||
"LocateCardsByATRA_Call rgAtrMasksNdrPtr (0x%08X) and cAtrs (0x%08X) inconsistency",
|
||||
(int) rgAtrMasksNdrPtr, (int) call->cAtrs);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (rgAtrMasksNdrPtr)
|
||||
{
|
||||
Stream_Read_UINT32(s, count);
|
||||
|
||||
if (count != call->cAtrs)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN,
|
||||
"LocateCardsByATRA_Call NdrCount (0x%08X) and cAtrs (0x%08X) inconsistency",
|
||||
(int) count, (int) call->cAtrs);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < call->cAtrs)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "LocateCardsByATRA_Call is too short: Actual: %d, Expected: %d",
|
||||
(int) Stream_GetRemainingLength(s), call->cAtrs);
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
call->rgAtrMasks = calloc(call->cAtrs, sizeof(SCARD_ATRMASK));
|
||||
if (!call->rgAtrMasks)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "LocateCardsByATRA_Call out of memory error (call->rgAtrMasks)");
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (index = 0; index < call->cAtrs; index++)
|
||||
{
|
||||
Stream_Read_UINT32(s, call->rgAtrMasks[index].cbAtr);
|
||||
Stream_Read(s, call->rgAtrMasks[index].rgbAtr, 36);
|
||||
Stream_Read(s, call->rgAtrMasks[index].rgbMask, 36);
|
||||
}
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, count);
|
||||
|
||||
if (count != call->cReaders)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN,
|
||||
"GetStatusChangeA_Call unexpected reader count: Actual: %d, Expected: %d",
|
||||
(int) count, call->cReaders);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (call->cReaders > 0)
|
||||
{
|
||||
call->rgReaderStates = calloc(call->cReaders, sizeof(SCARD_READERSTATEA));
|
||||
|
||||
if (!call->rgReaderStates)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "LocateCardsByATRA_Call out of memory error (call->rgReaderStates)");
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (index = 0; index < call->cReaders; index++)
|
||||
{
|
||||
readerState = (LPSCARD_READERSTATEA) &call->rgReaderStates[index];
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 52)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "LocateCardsByATRA_Call is too short: %d",
|
||||
(int) Stream_GetRemainingLength(s));
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, szReaderNdrPtr); /* szReaderNdrPtr (4 bytes) */
|
||||
Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */
|
||||
Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */
|
||||
Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */
|
||||
Stream_Read(s, readerState->rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */
|
||||
Stream_Seek(s, 4); /* rgbAtr [32..36] (4 bytes) */
|
||||
}
|
||||
|
||||
for (index = 0; index < call->cReaders; index++)
|
||||
{
|
||||
readerState = (LPSCARD_READERSTATEA) &call->rgReaderStates[index];
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 12)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "GetStatusChangeA_Call is too short: %d",
|
||||
(int) Stream_GetRemainingLength(s));
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, maxCount); /* NdrMaxCount (4 bytes) */
|
||||
Stream_Read_UINT32(s, offset); /* NdrOffset (4 bytes) */
|
||||
Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < count)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "GetStatusChangeA_Call is too short: %d",
|
||||
(int) Stream_GetRemainingLength(s));
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
readerState->szReader = (LPCSTR) malloc(count + 1);
|
||||
|
||||
if (!readerState->szReader)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN,
|
||||
"GetStatusChangeA_Call out of memory error (readerState->szReader)");
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
Stream_Read(s, (void*) readerState->szReader, count);
|
||||
smartcard_unpack_read_size_align(smartcard, s, count, 4);
|
||||
((char*) readerState->szReader)[count] = '\0';
|
||||
|
||||
if (!readerState->szReader)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_WARN, "GetStatusChangeA_Call null reader name");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, LocateCardsByATRA_Call* call)
|
||||
{
|
||||
BYTE* pb;
|
||||
UINT32 index;
|
||||
char* szEventState;
|
||||
char* szCurrentState;
|
||||
char* rgbAtr;
|
||||
LPSCARD_READERSTATEA readerState;
|
||||
|
||||
if (!WLog_IsLevelActive(smartcard->log, WLOG_DEBUG))
|
||||
return;
|
||||
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG, "LocateCardsByATRA_Call {");
|
||||
|
||||
pb = (BYTE*) &(call->hContext.pbContext);
|
||||
|
||||
if (call->hContext.cbContext > 4)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG, "hContext: 0x%02X%02X%02X%02X%02X%02X%02X%02X (%d)",
|
||||
pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG, "hContext: 0x%02X%02X%02X%02X (%d)",
|
||||
pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext);
|
||||
}
|
||||
|
||||
for (index = 0; index < call->cReaders; index++)
|
||||
{
|
||||
readerState = (LPSCARD_READERSTATEA) &call->rgReaderStates[index];
|
||||
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG,
|
||||
"\t[%d]: szReader: %s cbAtr: %d",
|
||||
index, readerState->szReader, readerState->cbAtr);
|
||||
|
||||
szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState);
|
||||
szEventState = SCardGetReaderStateString(readerState->dwEventState);
|
||||
rgbAtr = winpr_BinToHexString((BYTE*) &(readerState->rgbAtr), readerState->cbAtr, FALSE);
|
||||
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG,
|
||||
"\t[%d]: dwCurrentState: %s (0x%08X)",
|
||||
index, szCurrentState, readerState->dwCurrentState);
|
||||
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG,
|
||||
"\t[%d]: dwEventState: %s (0x%08X)",
|
||||
index, szEventState, readerState->dwEventState);
|
||||
|
||||
if (rgbAtr)
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG,
|
||||
"\t[%d]: cbAtr: %d rgbAtr: %s",
|
||||
index, readerState->cbAtr, rgbAtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG,
|
||||
"\t[%d]: cbAtr: %d rgbAtr: %s",
|
||||
index, 0, "");
|
||||
}
|
||||
|
||||
free(szCurrentState);
|
||||
free(szEventState);
|
||||
free(rgbAtr);
|
||||
}
|
||||
WLog_Print(smartcard->log, WLOG_DEBUG, "}");
|
||||
}
|
||||
|
@ -532,4 +532,8 @@ void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, Transmit_Call* c
|
||||
UINT32 smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Return* ret);
|
||||
void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, Transmit_Return* ret);
|
||||
|
||||
UINT32 smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsByATRA_Call* call);
|
||||
void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, LocateCardsByATRA_Call* call);
|
||||
|
||||
|
||||
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H */
|
||||
|
@ -1382,9 +1382,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
|
||||
{
|
||||
int i, j;
|
||||
int* map;
|
||||
DWORD dwEventState;
|
||||
PCSC_DWORD cMappedReaders;
|
||||
BOOL stateChanged = FALSE;
|
||||
PCSC_SCARD_READERSTATE* states;
|
||||
LONG status = SCARD_S_SUCCESS;
|
||||
PCSC_DWORD pcsc_dwTimeout = (PCSC_DWORD) dwTimeout;
|
||||
@ -1437,6 +1435,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
|
||||
states[j].szReader = rgReaderStates[i].szReader;
|
||||
|
||||
states[j].dwCurrentState = rgReaderStates[i].dwCurrentState;
|
||||
states[j].pvUserData = rgReaderStates[i].pvUserData;
|
||||
states[j].dwEventState = rgReaderStates[i].dwEventState;
|
||||
states[j].cbAtr = rgReaderStates[i].cbAtr;
|
||||
CopyMemory(&(states[j].rgbAtr), &(rgReaderStates[i].rgbAtr), PCSC_MAX_ATR_SIZE);
|
||||
@ -1470,6 +1469,11 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
|
||||
rgReaderStates[i].dwCurrentState = states[j].dwCurrentState;
|
||||
rgReaderStates[i].cbAtr = states[j].cbAtr;
|
||||
CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[j].rgbAtr), PCSC_MAX_ATR_SIZE);
|
||||
/**
|
||||
* Why we should interpret and modify the results of pcsc-lite ScardGetStatusChange ?
|
||||
* Should not we just act as a pass-through between the client and the remote smartcard subsystem ?
|
||||
*/
|
||||
#if 0
|
||||
/* pcsc-lite puts an event count in the higher bits of dwEventState */
|
||||
states[j].dwEventState &= 0xFFFF;
|
||||
dwEventState = states[j].dwEventState & ~SCARD_STATE_CHANGED;
|
||||
@ -1493,12 +1497,19 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext
|
||||
|
||||
if (rgReaderStates[i].dwCurrentState & SCARD_STATE_IGNORE)
|
||||
rgReaderStates[i].dwEventState = SCARD_STATE_IGNORE;
|
||||
#endif
|
||||
rgReaderStates[i].dwEventState = states[j].dwEventState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Why we should interpret and modify the results of pcsc-lite ScardGetStatusChange ?
|
||||
* Should not we just act as a pass-through between the client and the remote smartcard subsystem ?
|
||||
*/
|
||||
#if 0
|
||||
if ((status == SCARD_S_SUCCESS) && !stateChanged)
|
||||
status = SCARD_E_TIMEOUT;
|
||||
else if ((status == SCARD_E_TIMEOUT) && stateChanged)
|
||||
return SCARD_S_SUCCESS;
|
||||
#endif
|
||||
|
||||
free(states);
|
||||
free(map);
|
||||
@ -1610,7 +1621,15 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext,
|
||||
if (!szReaderPCSC)
|
||||
szReaderPCSC = (char*) szReader;
|
||||
|
||||
pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
|
||||
/**
|
||||
* As stated here : https://pcsclite.alioth.debian.org/api/group__API.html#ga4e515829752e0a8dbc4d630696a8d6a5
|
||||
* SCARD_PROTOCOL_UNDEFINED is valid for dwPreferredProtocols (only) if dwShareMode == SCARD_SHARE_DIRECT
|
||||
* and allows to send control commands to the reader (with SCardControl()) even if a card is not present in the reader
|
||||
*/
|
||||
if (pcsc_dwShareMode == SCARD_SHARE_DIRECT && dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED)
|
||||
pcsc_dwPreferredProtocols = SCARD_PROTOCOL_UNDEFINED;
|
||||
else
|
||||
pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
|
||||
status = (LONG) g_PCSC.pfnSCardConnect(hPrivateContext, szReaderPCSC,
|
||||
pcsc_dwShareMode, pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol);
|
||||
status = PCSC_MapErrorCodeToWinSCard(status);
|
||||
@ -2107,11 +2126,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard,
|
||||
{
|
||||
ioCtlValue = _byteswap_ulong(tlv->value);
|
||||
ioCtlValue -= 0x42000000; /* inverse of PCSC_SCARD_CTL_CODE() */
|
||||
IoCtlMethod = METHOD_FROM_CTL_CODE(ioCtlValue);
|
||||
IoCtlFunction = FUNCTION_FROM_CTL_CODE(ioCtlValue);
|
||||
IoCtlAccess = ACCESS_FROM_CTL_CODE(ioCtlValue);
|
||||
IoCtlDeviceType = DEVICE_TYPE_FROM_CTL_CODE(ioCtlValue);
|
||||
ioCtlValue = SCARD_CTL_CODE(IoCtlFunction);
|
||||
ioCtlValue = SCARD_CTL_CODE(ioCtlValue);
|
||||
tlv->value = _byteswap_ulong(ioCtlValue);
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,14 @@ typedef long PCSC_LONG;
|
||||
#define PCSC_SCARD_CTL_CODE(code) (0x42000000 + (code))
|
||||
#define PCSC_CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
|
||||
|
||||
/**
|
||||
* pcsc-lite defines SCARD_READERSTATE, SCARD_IO_REQUEST as packed
|
||||
* on Mac OS X only and uses default packing everywhere else.
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -97,6 +104,12 @@ typedef struct
|
||||
PCSC_DWORD cbPciLength;
|
||||
} PCSC_SCARD_IO_REQUEST;
|
||||
|
||||
#ifdef __APPLE__
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE tag;
|
||||
|
Loading…
Reference in New Issue
Block a user