smartcard->log = WLog_Get("com.freerdp.channel.smartcard.client");
- //WLog_SetLogLevel(smartcard->log, WLOG_DEBUG);
-
smartcard->IrpQueue = MessageQueue_New(NULL);
smartcard->rgSCardContextList = ListDictionary_New(TRUE);
smartcard->rgOutstandingMessages = ListDictionary_New(TRUE);
}
status = ret.ReturnCode = SCardConnectA(operation->hContext, (char*) call->szReader, call->Common.dwShareMode,
- call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
+ call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
+
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);
status = smartcard_unpack_connect_w_call(smartcard, irp->input, call);
smartcard_trace_connect_w_call(smartcard, call);
operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext));
+
return status;
}
}
status = ret.ReturnCode = SCardConnectW(operation->hContext, (WCHAR*) call->szReader, call->Common.dwShareMode,
- call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
+ call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol);
+
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);
#endif
-#define SCARD_ATR_LENGTH 33
-
-#define SCARD_PROTOCOL_UNDEFINED 0x00000000
-#define SCARD_PROTOCOL_T0 0x00000001
-#define SCARD_PROTOCOL_T1 0x00000002
-#define SCARD_PROTOCOL_RAW 0x00010000
-
-#define SCARD_PROTOCOL_Tx (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
-#define SCARD_PROTOCOL_DEFAULT 0x80000000
-#define SCARD_PROTOCOL_OPTIMAL 0x00000000
-
-#define SCARD_POWER_DOWN 0
-#define SCARD_COLD_RESET 1
-#define SCARD_WARM_RESET 2
-
-#define SCARD_CTL_CODE(code) CTL_CODE(FILE_DEVICE_SMARTCARD, (code), METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define IOCTL_SMARTCARD_POWER SCARD_CTL_CODE(1)
-#define IOCTL_SMARTCARD_GET_ATTRIBUTE SCARD_CTL_CODE(2)
-#define IOCTL_SMARTCARD_SET_ATTRIBUTE SCARD_CTL_CODE(3)
-#define IOCTL_SMARTCARD_CONFISCATE SCARD_CTL_CODE(4)
-#define IOCTL_SMARTCARD_TRANSMIT SCARD_CTL_CODE(5)
-#define IOCTL_SMARTCARD_EJECT SCARD_CTL_CODE(6)
-#define IOCTL_SMARTCARD_SWALLOW SCARD_CTL_CODE(7)
-#define IOCTL_SMARTCARD_IS_PRESENT SCARD_CTL_CODE(10)
-#define IOCTL_SMARTCARD_IS_ABSENT SCARD_CTL_CODE(11)
-#define IOCTL_SMARTCARD_SET_PROTOCOL SCARD_CTL_CODE(12)
-#define IOCTL_SMARTCARD_GET_STATE SCARD_CTL_CODE(14)
-#define IOCTL_SMARTCARD_GET_LAST_ERROR SCARD_CTL_CODE(15)
-#define IOCTL_SMARTCARD_GET_PERF_CNTR SCARD_CTL_CODE(16)
-
-#define MAXIMUM_ATTR_STRING_LENGTH 32
-#define MAXIMUM_SMARTCARD_READERS 10
-
-#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag)))
-
-#define SCARD_CLASS_VENDOR_INFO 1
-#define SCARD_CLASS_COMMUNICATIONS 2
-#define SCARD_CLASS_PROTOCOL 3
-#define SCARD_CLASS_POWER_MGMT 4
-#define SCARD_CLASS_SECURITY 5
-#define SCARD_CLASS_MECHANICAL 6
-#define SCARD_CLASS_VENDOR_DEFINED 7
-#define SCARD_CLASS_IFD_PROTOCOL 8
-#define SCARD_CLASS_ICC_STATE 9
-#define SCARD_CLASS_PERF 0x7FFE
-#define SCARD_CLASS_SYSTEM 0x7FFF
+#define SCARD_ATR_LENGTH 33
+
+#define SCARD_PROTOCOL_UNDEFINED 0x00000000
+#define SCARD_PROTOCOL_T0 0x00000001
+#define SCARD_PROTOCOL_T1 0x00000002
+#define SCARD_PROTOCOL_RAW 0x00010000
+
+#define SCARD_PROTOCOL_Tx (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
+#define SCARD_PROTOCOL_DEFAULT 0x80000000
+#define SCARD_PROTOCOL_OPTIMAL 0x00000000
+
+#define SCARD_POWER_DOWN 0
+#define SCARD_COLD_RESET 1
+#define SCARD_WARM_RESET 2
+
+#define SCARD_CTL_CODE(code) CTL_CODE(FILE_DEVICE_SMARTCARD, (code), METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_SMARTCARD_POWER SCARD_CTL_CODE(1)
+#define IOCTL_SMARTCARD_GET_ATTRIBUTE SCARD_CTL_CODE(2)
+#define IOCTL_SMARTCARD_SET_ATTRIBUTE SCARD_CTL_CODE(3)
+#define IOCTL_SMARTCARD_CONFISCATE SCARD_CTL_CODE(4)
+#define IOCTL_SMARTCARD_TRANSMIT SCARD_CTL_CODE(5)
+#define IOCTL_SMARTCARD_EJECT SCARD_CTL_CODE(6)
+#define IOCTL_SMARTCARD_SWALLOW SCARD_CTL_CODE(7)
+#define IOCTL_SMARTCARD_IS_PRESENT SCARD_CTL_CODE(10)
+#define IOCTL_SMARTCARD_IS_ABSENT SCARD_CTL_CODE(11)
+#define IOCTL_SMARTCARD_SET_PROTOCOL SCARD_CTL_CODE(12)
+#define IOCTL_SMARTCARD_GET_STATE SCARD_CTL_CODE(14)
+#define IOCTL_SMARTCARD_GET_LAST_ERROR SCARD_CTL_CODE(15)
+#define IOCTL_SMARTCARD_GET_PERF_CNTR SCARD_CTL_CODE(16)
+
+#define IOCTL_SMARTCARD_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
+
+#define MAXIMUM_ATTR_STRING_LENGTH 32
+#define MAXIMUM_SMARTCARD_READERS 10
+
+#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag)))
+
+#define SCARD_CLASS_VENDOR_INFO 1
+#define SCARD_CLASS_COMMUNICATIONS 2
+#define SCARD_CLASS_PROTOCOL 3
+#define SCARD_CLASS_POWER_MGMT 4
+#define SCARD_CLASS_SECURITY 5
+#define SCARD_CLASS_MECHANICAL 6
+#define SCARD_CLASS_VENDOR_DEFINED 7
+#define SCARD_CLASS_IFD_PROTOCOL 8
+#define SCARD_CLASS_ICC_STATE 9
+#define SCARD_CLASS_PERF 0x7FFE
+#define SCARD_CLASS_SYSTEM 0x7FFF
#define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0100)
#define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0101)
char SMARTCARD_PNP_NOTIFICATION_A[] = "\\\\?PnP?\\Notification";
-WCHAR SMARTCARD_PNP_NOTIFICATION_W[] = { '\\','\\','?','P','n','P','?',
- '\\','N','o','t','i','f','i','c','a','t','i','o','n','\0'
- };
+WCHAR SMARTCARD_PNP_NOTIFICATION_W[] =
+{ '\\','\\','?','P','n','P','?','\\','N','o','t','i','f','i','c','a','t','i','o','n','\0' };
const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(PCSC_SCARD_IO_REQUEST) };
const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(PCSC_SCARD_IO_REQUEST) };
char* PCSC_GetReaderAliasFromName(char* namePCSC)
{
- char* nameWinSCard;
+ char* nameWinSCard = NULL;
+
nameWinSCard = PCSC_ConvertReaderNameToWinSCard(namePCSC);
if (nameWinSCard)
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);
+ pcsc_dwShareMode, pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol);
+
status = PCSC_MapErrorCodeToWinSCard(status);
if (status == SCARD_S_SUCCESS)
return SCARD_E_INVALID_HANDLE;
status = PCSC_SCardConnect_Internal(hContext, szReader, dwShareMode,
- dwPreferredProtocols, phCard, pdwActiveProtocol);
+ dwPreferredProtocols, phCard, pdwActiveProtocol);
if (!PCSC_UnlockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
ConvertFromUnicode(CP_UTF8, 0, szReader, -1, &szReaderA, 0, NULL, NULL);
status = PCSC_SCardConnect_Internal(hContext, szReaderA, dwShareMode,
- dwPreferredProtocols, phCard, pdwActiveProtocol);
+ dwPreferredProtocols, phCard, pdwActiveProtocol);
free(szReaderA);
if (!PCSC_UnlockCardContext(hContext))
if (!g_PCSC.pfnSCardControl)
return SCARD_E_NO_SERVICE;
+ /**
+ * PCSCv2 Part 10:
+ * http://www.pcscworkgroup.com/specifications/files/pcsc10_v2.02.09.pdf
+ *
+ * Smart Card Driver IOCTLs:
+ * http://msdn.microsoft.com/en-us/library/windows/hardware/ff548988/
+ *
+ * Converting Windows Feature Request IOCTL code to the pcsc-lite control code:
+ * http://musclecard.996296.n3.nabble.com/Converting-Windows-Feature-Request-IOCTL-code-to-the-pcsc-lite-control-code-td4906.html
+ */
+
IoCtlMethod = METHOD_FROM_CTL_CODE(dwControlCode);
IoCtlFunction = FUNCTION_FROM_CTL_CODE(dwControlCode);
IoCtlAccess = ACCESS_FROM_CTL_CODE(dwControlCode);
IoCtlDeviceType = DEVICE_TYPE_FROM_CTL_CODE(dwControlCode);
- if (dwControlCode == PCSC_CM_IOCTL_GET_FEATURE_REQUEST)
+ if (dwControlCode == IOCTL_SMARTCARD_GET_FEATURE_REQUEST)
getFeatureRequest = TRUE;
if (IoCtlDeviceType == FILE_DEVICE_SMARTCARD)
dwControlCode = PCSC_SCARD_CTL_CODE(IoCtlFunction);
pcsc_dwControlCode = (PCSC_DWORD) dwControlCode;
+
status = (LONG) g_PCSC.pfnSCardControl(hCard,
- pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize,
- lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned);
+ pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize,
+ lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned);
+
status = PCSC_MapErrorCodeToWinSCard(status);
*lpBytesReturned = (DWORD) pcsc_BytesReturned;
if (getFeatureRequest)
{
- UINT32 ioCtlValue;
+ UINT32 index;
+ UINT32 count;
PCSC_TLV_STRUCTURE* tlv = (PCSC_TLV_STRUCTURE*) lpOutBuffer;
- void* lpOutBufferEnd = (void*) &((BYTE*) lpOutBuffer)[*lpBytesReturned];
- for (; ((void*) tlv) < lpOutBufferEnd; tlv++)
+ if ((*lpBytesReturned % sizeof(PCSC_TLV_STRUCTURE)) != 0)
+ return SCARD_E_UNEXPECTED;
+
+ count = *lpBytesReturned / sizeof(PCSC_TLV_STRUCTURE);
+
+ for (index = 0; index < count; index++)
{
- ioCtlValue = _byteswap_ulong(tlv->value);
- ioCtlValue -= 0x42000000; /* inverse of PCSC_SCARD_CTL_CODE() */
- ioCtlValue = SCARD_CTL_CODE(ioCtlValue);
- tlv->value = _byteswap_ulong(ioCtlValue);
+ if (tlv[index].length != 4)
+ return SCARD_E_UNEXPECTED;
}
}
typedef long PCSC_LONG;
#endif
-#define PCSC_SCARD_UNKNOWN 0x0001
-#define PCSC_SCARD_ABSENT 0x0002
-#define PCSC_SCARD_PRESENT 0x0004
-#define PCSC_SCARD_SWALLOWED 0x0008
-#define PCSC_SCARD_POWERED 0x0010
-#define PCSC_SCARD_NEGOTIABLE 0x0020
-#define PCSC_SCARD_SPECIFIC 0x0040
+#define PCSC_SCARD_UNKNOWN 0x0001
+#define PCSC_SCARD_ABSENT 0x0002
+#define PCSC_SCARD_PRESENT 0x0004
+#define PCSC_SCARD_SWALLOWED 0x0008
+#define PCSC_SCARD_POWERED 0x0010
+#define PCSC_SCARD_NEGOTIABLE 0x0020
+#define PCSC_SCARD_SPECIFIC 0x0040
-#define PCSC_SCARD_PROTOCOL_RAW 0x00000004
-#define PCSC_SCARD_PROTOCOL_T15 0x00000008
+#define PCSC_SCARD_PROTOCOL_RAW 0x00000004
+#define PCSC_SCARD_PROTOCOL_T15 0x00000008
-#define PCSC_MAX_BUFFER_SIZE 264
-#define PCSC_MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1 << 16) + 3 + 2)
+#define PCSC_MAX_BUFFER_SIZE 264
+#define PCSC_MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1 << 16) + 3 + 2)
-#define PCSC_MAX_ATR_SIZE 33
+#define PCSC_MAX_ATR_SIZE 33
-#define PCSC_SCARD_AUTOALLOCATE (PCSC_DWORD)(-1)
+#define PCSC_SCARD_AUTOALLOCATE (PCSC_DWORD)(-1)
-#define PCSC_SCARD_PCI_T0 (&g_PCSC_rgSCardT0Pci)
-#define PCSC_SCARD_PCI_T1 (&g_PCSC_rgSCardT1Pci)
-#define PCSC_SCARD_PCI_RAW (&g_PCSC_rgSCardRawPci)
+#define PCSC_SCARD_PCI_T0 (&g_PCSC_rgSCardT0Pci)
+#define PCSC_SCARD_PCI_T1 (&g_PCSC_rgSCardT1Pci)
+#define PCSC_SCARD_PCI_RAW (&g_PCSC_rgSCardRawPci)
#define PCSC_SCARD_CTL_CODE(code) (0x42000000 + (code))
-#define PCSC_CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
+#define PCSC_CM_IOCTL_GET_FEATURE_REQUEST PCSC_SCARD_CTL_CODE(3400)
/**
* pcsc-lite defines SCARD_READERSTATE, SCARD_IO_REQUEST as packed