channels/smartcard: cleanup SCardControl
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 22 Dec 2014 21:25:59 +0000 (16:25 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 22 Dec 2014 21:25:59 +0000 (16:25 -0500)
channels/smartcard/client/smartcard_main.c
channels/smartcard/client/smartcard_operations.c
winpr/include/winpr/smartcard.h
winpr/libwinpr/smartcard/smartcard_pcsc.c
winpr/libwinpr/smartcard/smartcard_pcsc.h

index f501d77..131802a 100644 (file)
@@ -508,8 +508,6 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
 
        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);
index 6133d5c..6e923c3 100644 (file)
@@ -550,7 +550,8 @@ 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);
+                                               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);
@@ -580,6 +581,7 @@ static UINT32 smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_O
        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;
 }
 
@@ -597,7 +599,8 @@ 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);
+                                                       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);
index fa6cbfc..482e3b2 100644 (file)
 
 #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)
index bc55279..5b7d0c3 100644 (file)
@@ -180,9 +180,8 @@ static wListDictionary* g_MemoryBlocks = NULL;
 
 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) };
@@ -745,7 +744,8 @@ char* PCSC_ConvertReaderNameToWinSCard(const char* name)
 
 char* PCSC_GetReaderAliasFromName(char* namePCSC)
 {
-       char* nameWinSCard;
+       char* nameWinSCard = NULL;
+
        nameWinSCard = PCSC_ConvertReaderNameToWinSCard(namePCSC);
 
        if (nameWinSCard)
@@ -1636,8 +1636,10 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext,
                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)
@@ -1663,7 +1665,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnectA(SCARDCONTEXT hContext,
                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;
@@ -1685,7 +1687,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnectW(SCARDCONTEXT hContext,
                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))
@@ -2115,36 +2117,52 @@ WINSCARDAPI LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard,
        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;
                }
        }
 
index a25dd64..af3ec9d 100644 (file)
@@ -53,30 +53,30 @@ typedef PCSC_ULONG *PCSC_PULONG;
 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