From 99c69cde2710a31a156b944ea9e02dd542063976 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 4 Dec 2017 12:17:57 +0100 Subject: [PATCH 01/15] fix channel/smartcard: error handling According to MS-RDPESC the smart card channel must set the IoStatus to an NTSTATUS in case a encoding or decoding error happens. The smart card channel did this correctly but the output stream was modified incorrectly causing the smart card remote manager to stop in error cases. --- channels/smartcard/client/smartcard_operations.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index a34cc0b20..b6d5a7d3f 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -2022,13 +2022,12 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP SCardGetErrorString(result), result); } - irp->IoStatus = 0; + irp->IoStatus = STATUS_SUCCESS; if ((result & 0xC0000000) == 0xC0000000) { /* NTSTATUS error */ irp->IoStatus = (UINT32)result; - Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH); WLog_WARN(TAG, "IRP failure: %s (0x%08"PRIX32"), ntstatus: 0x%08"PRIX32"", smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result); } From 3dc4e283dbcf296cbd2648c9277e015ad4a74e71 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 4 Dec 2017 12:31:10 +0100 Subject: [PATCH 02/15] fix channel/smartcard: return value handling Device control calls always returned SCARD_S_SUCCESS even if an error occurred. This caused server side software (including the card manager) to behave incorrectly. --- channels/smartcard/client/smartcard_operations.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index b6d5a7d3f..0bbf44d7f 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -2039,19 +2039,8 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP /* Device Control Response */ Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */ - if ((result = smartcard_pack_common_type_header(smartcard, - irp->output))) /* CommonTypeHeader (8 bytes) */ - { - WLog_ERR(TAG, "smartcard_pack_common_type_header failed with error %"PRId32"", result); - return result; - } - - if ((result = smartcard_pack_private_type_header(smartcard, irp->output, - objectBufferLength))) /* PrivateTypeHeader (8 bytes) */ - { - WLog_ERR(TAG, "smartcard_pack_private_type_header failed with error %"PRId32"", result); - return result; - } + smartcard_pack_common_type_header(smartcard, irp->output); /* CommonTypeHeader (8 bytes) */ + smartcard_pack_private_type_header(smartcard, irp->output, objectBufferLength); /* PrivateTypeHeader (8 bytes) */ Stream_Write_UINT32(irp->output, result); /* Result (4 bytes) */ Stream_SetPosition(irp->output, Stream_Length(irp->output)); From 46a7538322e1e02f6fb61f20d4a900756f673184 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 4 Dec 2017 15:22:07 +0100 Subject: [PATCH 03/15] fix channel/smartcard: async request handling The smart card channel tried to mimic mstsc's behavior on if an IRP was processed synchronously or asynchronously. As the channel uses one thread per context it could happen, especially with PCSC, that the main channel thread was blocked waiting for an smart card operation to complete. To prevent that behavior only call known safe functions in the main thread (like CreateContext) and call the rest asynchronously. For example the channel would block if a ListReaders is invoked on the same context where a GetStatusChange (infinite timeout) was already pending. Only when a status change happened the channel would continue. Note: Due to the one context per thread design it's important that cancel isn't queued an alway run synchronously. Otherwise a specific context might lock. --- channels/smartcard/client/smartcard_main.c | 24 ++++++---------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 0945206ec..f21f0f2fa 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -385,17 +385,17 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) asyncIrp = TRUE; - /** - * The following matches mstsc's behavior of processing - * only certain requests asynchronously while processing - * those expected to return fast synchronously. - */ - switch (operation->ioControlCode) { case SCARD_IOCTL_ESTABLISHCONTEXT: case SCARD_IOCTL_RELEASECONTEXT: case SCARD_IOCTL_ISVALIDCONTEXT: + case SCARD_IOCTL_CANCEL: + case SCARD_IOCTL_ACCESSSTARTEDEVENT: + case SCARD_IOCTL_RELEASESTARTEDEVENT: + asyncIrp = FALSE; + break; + case SCARD_IOCTL_LISTREADERGROUPSA: case SCARD_IOCTL_LISTREADERGROUPSW: case SCARD_IOCTL_LISTREADERSA: @@ -416,21 +416,14 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) case SCARD_IOCTL_LOCATECARDSW: case SCARD_IOCTL_LOCATECARDSBYATRA: case SCARD_IOCTL_LOCATECARDSBYATRW: - case SCARD_IOCTL_CANCEL: case SCARD_IOCTL_READCACHEA: case SCARD_IOCTL_READCACHEW: case SCARD_IOCTL_WRITECACHEA: case SCARD_IOCTL_WRITECACHEW: case SCARD_IOCTL_GETREADERICON: case SCARD_IOCTL_GETDEVICETYPEID: - asyncIrp = FALSE; - break; - case SCARD_IOCTL_GETSTATUSCHANGEA: case SCARD_IOCTL_GETSTATUSCHANGEW: - asyncIrp = TRUE; - break; - case SCARD_IOCTL_CONNECTA: case SCARD_IOCTL_CONNECTW: case SCARD_IOCTL_RECONNECT: @@ -447,11 +440,6 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) case SCARD_IOCTL_GETTRANSMITCOUNT: asyncIrp = TRUE; break; - - case SCARD_IOCTL_ACCESSSTARTEDEVENT: - case SCARD_IOCTL_RELEASESTARTEDEVENT: - asyncIrp = FALSE; - break; } pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList, From f8a3e7acd4d5f9e0a9e26293f7dca6110d756943 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 4 Dec 2017 16:16:59 +0100 Subject: [PATCH 04/15] fix channel/smartcard: GetStatusChange return code In case SCardGetStatusChange returned an error the call didn't return any data but STATUS_NO_MEMORY as the calloc failed. This caused problems with multiple applications server side (hangs and incorrect behavior). Now the case when no readers are returned is handed correctly and the data is also filled and send if the call fails. --- .../smartcard/client/smartcard_operations.c | 48 ++++++------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 0bbf44d7f..3070ab33d 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -587,22 +587,17 @@ static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, LPSCARD_READERSTATEA rgReaderState = NULL; IRP* irp = operation->irp; GetStatusChangeA_Call* call = operation->call; - status = ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, - call->dwTimeOut, call->rgReaderStates, call->cReaders); - - if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED)) - { - call->cReaders = 0; - } + ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, call->dwTimeOut, call->rgReaderStates, call->cReaders); ret.cReaders = call->cReaders; ret.rgReaderStates = NULL; - if (ret.cReaders > 0) - ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); + if (ret.cReaders > 0) { + ret.rgReaderStates = (ReaderState_Return *) calloc(ret.cReaders, sizeof(ReaderState_Return)); - if (!ret.rgReaderStates) - return STATUS_NO_MEMORY; + if (!ret.rgReaderStates) + return STATUS_NO_MEMORY; + } for (index = 0; index < ret.cReaders; index++) { @@ -613,12 +608,7 @@ static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, } smartcard_trace_get_status_change_return(smartcard, &ret, FALSE); - - if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret))) - { - WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %"PRId32"", status); - return status; - } + smartcard_pack_get_status_change_return(smartcard, irp->output, &ret); if (call->rgReaderStates) { @@ -657,28 +647,23 @@ static LONG smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard, static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { - LONG status; UINT32 index; GetStatusChange_Return ret; LPSCARD_READERSTATEW rgReaderState = NULL; IRP* irp = operation->irp; GetStatusChangeW_Call* call = operation->call; - status = ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut, + ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut, call->rgReaderStates, call->cReaders); - if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED)) - { - call->cReaders = 0; - } - ret.cReaders = call->cReaders; ret.rgReaderStates = NULL; - if (ret.cReaders > 0) - ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); + if (ret.cReaders > 0) { + ret.rgReaderStates = (ReaderState_Return *) calloc(ret.cReaders, sizeof(ReaderState_Return)); - if (!ret.rgReaderStates) - return STATUS_NO_MEMORY; + if (!ret.rgReaderStates) + return STATUS_NO_MEMORY; + } for (index = 0; index < ret.cReaders; index++) { @@ -689,12 +674,7 @@ static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, } smartcard_trace_get_status_change_return(smartcard, &ret, TRUE); - - if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret))) - { - WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %"PRId32"", status); - return status; - } + smartcard_pack_get_status_change_return(smartcard, irp->output, &ret); if (call->rgReaderStates) { From 6e63c6afd909be1872677700d6bfea435b2cf309 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 11 Dec 2017 10:33:28 +0100 Subject: [PATCH 05/15] fix channel/smartcard: remove status mappings The state tracking/modifications (presumably thought as optimization?!) in PCSC_SCardGetStatusChange_Internal cause a lot of applications to behave incorrectly and/or hang. Ideally no modifications of the states should be necessary as PCSC implements the same API as passed over the channel. --- winpr/libwinpr/smartcard/smartcard_pcsc.c | 28 +---------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 88910ba10..dddfe301f 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -1623,37 +1623,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); - dwEventState = states[j].dwEventState & ~SCARD_STATE_CHANGED; - - if (dwEventState != rgReaderStates[i].dwCurrentState) - { - rgReaderStates[i].dwEventState = states[j].dwEventState; - - if (dwEventState & SCARD_STATE_PRESENT) - { - if (!(dwEventState & SCARD_STATE_EXCLUSIVE)) - rgReaderStates[i].dwEventState |= SCARD_STATE_INUSE; - } - - stateChanged = TRUE; - } - else - { - rgReaderStates[i].dwEventState = dwEventState; - } - - if (rgReaderStates[i].dwCurrentState & SCARD_STATE_IGNORE) - rgReaderStates[i].dwEventState = SCARD_STATE_IGNORE; + rgReaderStates[i].dwEventState = states[j].dwEventState; } free(map); free(states); - - if ((status == SCARD_S_SUCCESS) && !stateChanged) - status = SCARD_E_TIMEOUT; - else if ((status == SCARD_E_TIMEOUT) && stateChanged) - return SCARD_S_SUCCESS; - return status; } From 1e6fea7fa79b28ba262241f1d6f7820dc3daa494 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 11 Dec 2017 14:00:09 +0100 Subject: [PATCH 06/15] fix channel/smartcard: simplify channel variables Path was not really used and name was duplicated. Use the device->Name directly. --- channels/smartcard/client/smartcard_main.c | 22 +---------- channels/smartcard/client/smartcard_main.h | 3 -- channels/smartcard/client/smartcard_pack.c | 2 +- client/common/cmdline.c | 46 ++++++++-------------- include/freerdp/settings.h | 1 - libfreerdp/common/settings.c | 9 +---- 6 files changed, 19 insertions(+), 64 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index f21f0f2fa..9fe2c3614 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -677,17 +677,12 @@ static UINT smartcard_irp_request(DEVICE* device, IRP* irp) */ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { - char* name; - char* path; size_t length; - int ck; RDPDR_SMARTCARD* device; SMARTCARD_DEVICE* smartcard; LONG status; UINT error = CHANNEL_RC_NO_MEMORY; device = (RDPDR_SMARTCARD*) pEntryPoints->device; - name = device->Name; - path = device->Path; smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE)); if (!smartcard) @@ -712,23 +707,8 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } Stream_Write(smartcard->device.data, "SCARD", 6); - smartcard->name = NULL; - smartcard->path = NULL; - if (path) - { - smartcard->path = path; - smartcard->name = name; - } - else if (name) - { - if (1 == sscanf(name, "%d", &ck)) - smartcard->path = name; - else - smartcard->name = name; - } - - status = SCardAddReaderName(&smartcard->thread, (LPSTR) name); + status = SCardAddReaderName(&smartcard->thread, (LPSTR) device->Name); if (status != SCARD_S_SUCCESS) { diff --git a/channels/smartcard/client/smartcard_main.h b/channels/smartcard/client/smartcard_main.h index 10cdb5038..845123458 100644 --- a/channels/smartcard/client/smartcard_main.h +++ b/channels/smartcard/client/smartcard_main.h @@ -110,9 +110,6 @@ struct _SMARTCARD_DEVICE { DEVICE device; - char* name; - char* path; - HANDLE thread; HANDLE StartedEvent; wMessageQueue* IrpQueue; diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 1f89d5431..373064e67 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -850,7 +850,7 @@ void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, ListReader CopyMemory(mszA, ret->msz, ret->cBytes); } - for (index = 0; index < length - 2; index++) + for (index = 0; index < length - 1; index++) { if (mszA[index] == '\0') mszA[index] = ','; diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 6db75b97f..17c3c16c2 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -476,43 +476,29 @@ BOOL freerdp_client_add_device_channel(rdpSettings* settings, int count, settings->RedirectSmartCards = TRUE; settings->DeviceRedirection = TRUE; - if (count > 1) + smartcard = (RDPDR_SMARTCARD*) calloc(1, sizeof(RDPDR_SMARTCARD)); + + if (!smartcard) + return FALSE; + + smartcard->Type = RDPDR_DTYP_SMARTCARD; + + if (count > 1 && strlen(params[1])) { - smartcard = (RDPDR_SMARTCARD*) calloc(1, sizeof(RDPDR_SMARTCARD)); - - if (!smartcard) - return FALSE; - - smartcard->Type = RDPDR_DTYP_SMARTCARD; - - if (count > 1) + if (!(smartcard->Name = _strdup(params[1]))) { - if (!(smartcard->Name = _strdup(params[1]))) - { - free(smartcard); - return FALSE; - } - } - - if (count > 2) - { - if (!(smartcard->Path = _strdup(params[2]))) - { - free(smartcard->Name); - free(smartcard); - return FALSE; - } - } - - if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard)) - { - free(smartcard->Path); - free(smartcard->Name); free(smartcard); return FALSE; } } + if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard)) + { + free(smartcard->Name); + free(smartcard); + return FALSE; + } + return TRUE; } else if (strcmp(params[0], "serial") == 0) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 2e1f79668..3bbf536d2 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -446,7 +446,6 @@ struct _RDPDR_SMARTCARD UINT32 Id; UINT32 Type; char* Name; - char* Path; }; typedef struct _RDPDR_SMARTCARD RDPDR_SMARTCARD; diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 76d2439f4..fd4b008f7 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -307,13 +307,6 @@ out_print_name_error: goto out_smartc_name_error; } - if (smartcard->Path) - { - _smartcard->Path = _strdup(smartcard->Path); - if (!_smartcard->Path) - goto out_smartc_path_error; - } - return (RDPDR_DEVICE*) _smartcard; out_smartc_path_error: @@ -428,7 +421,7 @@ void freerdp_device_collection_free(rdpSettings* settings) } else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SMARTCARD) { - free(((RDPDR_SMARTCARD*) device)->Path); + } else if (settings->DeviceArray[index]->Type == RDPDR_DTYP_SERIAL) { From e3d45c458057910a2409626858492a9de33728be Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 11 Dec 2017 14:31:19 +0100 Subject: [PATCH 07/15] fix channel/smartcard: remove SCardAddReaderName SCardAddReaderName isn't part of the SCard API. Note: removing this also removes the possibility to redirect single smartcard readers with /smartcard:READERNAME. However this features wasn't implemented in a general way and will be re-added as part of the smart card channel directly. --- channels/smartcard/client/smartcard_main.c | 8 --- winpr/include/winpr/smartcard.h | 5 -- winpr/libwinpr/smartcard/smartcard.c | 5 -- winpr/libwinpr/smartcard/smartcard_pcsc.c | 71 +------------------ winpr/libwinpr/smartcard/smartcard_pcsc.h | 1 - winpr/libwinpr/smartcard/smartcard_winscard.c | 3 +- 6 files changed, 4 insertions(+), 89 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 9fe2c3614..d3555f91c 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -708,14 +708,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) Stream_Write(smartcard->device.data, "SCARD", 6); - status = SCardAddReaderName(&smartcard->thread, (LPSTR) device->Name); - - if (status != SCARD_S_SUCCESS) - { - WLog_ERR(TAG, "Failed to add reader name!"); - goto error_device_data; - } - smartcard->IrpQueue = MessageQueue_New(NULL); if (!smartcard->IrpQueue) diff --git a/winpr/include/winpr/smartcard.h b/winpr/include/winpr/smartcard.h index 8b52beb77..d168f2d90 100644 --- a/winpr/include/winpr/smartcard.h +++ b/winpr/include/winpr/smartcard.h @@ -789,8 +789,6 @@ WINSCARDAPI LONG WINAPI SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hCont WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent); -WINSCARDAPI LONG WINAPI SCardAddReaderName(HANDLE* key, LPSTR readerName); - #ifdef UNICODE #define SCardListReaderGroups SCardListReaderGroupsW #define SCardListReaders SCardListReadersW @@ -1045,8 +1043,6 @@ typedef LONG(WINAPI* fnSCardListReadersWithDeviceInstanceIdW)(SCARDCONTEXT hCont typedef LONG(WINAPI* fnSCardAudit)(SCARDCONTEXT hContext, DWORD dwEvent); -typedef LONG(WINAPI* fnSCardAddReaderName)(HANDLE* key, LPSTR readerName); - struct _SCardApiFunctionTable { DWORD dwVersion; @@ -1128,7 +1124,6 @@ struct _SCardApiFunctionTable fnSCardListReadersWithDeviceInstanceIdA pfnSCardListReadersWithDeviceInstanceIdA; fnSCardListReadersWithDeviceInstanceIdW pfnSCardListReadersWithDeviceInstanceIdW; fnSCardAudit pfnSCardAudit; - fnSCardAddReaderName pfnSCardAddReaderName; }; typedef struct _SCardApiFunctionTable SCardApiFunctionTable; diff --git a/winpr/libwinpr/smartcard/smartcard.c b/winpr/libwinpr/smartcard/smartcard.c index 2d2a8e55f..96ecc6f90 100644 --- a/winpr/libwinpr/smartcard/smartcard.c +++ b/winpr/libwinpr/smartcard/smartcard.c @@ -507,11 +507,6 @@ WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent) SCARDAPI_STUB_CALL_LONG(SCardAudit, hContext, dwEvent); } -WINSCARDAPI LONG WINAPI SCardAddReaderName(HANDLE* key, LPSTR readerName) -{ - SCARDAPI_STUB_CALL_LONG(SCardAddReaderName, key, readerName); -} - /** * Extended API */ diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index dddfe301f..997d1eb35 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -156,7 +156,6 @@ static wArrayList* g_Readers = NULL; static wListDictionary* g_CardHandles = NULL; static wListDictionary* g_CardContexts = NULL; static wListDictionary* g_MemoryBlocks = NULL; -static wListDictionary* g_ReadersNames = NULL; char SMARTCARD_PNP_NOTIFICATION_A[] = "\\\\?PnP?\\Notification"; @@ -754,38 +753,6 @@ char* PCSC_GetReaderAliasFromName(char* namePCSC) return nameWinSCard; } -int PCSC_RedirectReader(char* readerName) -{ - char* name; - ULONG_PTR* readers; - int i, nbReaders; - nbReaders = ListDictionary_GetKeys(g_ReadersNames, &readers); - - for (i = 0; i < nbReaders; i++) - { - name = ListDictionary_GetItemValue(g_ReadersNames, (void*) readers[i]); - - if (name) - { - if (strcmp(name, "") == 0) - { - return 1; - } - - if (strncmp(readerName, name, strlen(readerName)) == 0) - { - return 1; - } - } - else - { - return 2; - } - } - - return 0; -} - char* PCSC_ConvertReaderNamesToWinSCard(const char* names, LPDWORD pcchReaders) { int ret = 0; @@ -813,18 +780,8 @@ char* PCSC_ConvertReaderNamesToWinSCard(const char* names, LPDWORD pcchReaders) if (nameWinSCard) { length = strlen(nameWinSCard); - ret = PCSC_RedirectReader(nameWinSCard); - - if (ret == 1) - { - CopyMemory(q, nameWinSCard, length); - endReaderName = TRUE; - } - else if (ret == 2) - { - CopyMemory(q, nameWinSCard, length); - allReaders = TRUE; - } + CopyMemory(q, nameWinSCard, length); + allReaders = TRUE; free(nameWinSCard); } @@ -2808,27 +2765,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent) return 0; } -WINSCARDAPI LONG WINAPI PCSC_SCardAddReaderName(HANDLE* key, LPSTR readerName) -{ - LONG status = SCARD_S_SUCCESS; - int count = 0; - - if (!g_ReadersNames) - { - g_ReadersNames = ListDictionary_New(TRUE); - - if (!g_ReadersNames) - return SCARD_E_NO_SERVICE; - } - - count = ListDictionary_Count(g_ReadersNames); - - if (!ListDictionary_Add(g_ReadersNames, key, readerName)) - return SCARD_E_NO_SERVICE; - - return status; -} - #ifdef __MACOSX__ unsigned int determineMacOSXVersion(void) { @@ -3038,8 +2974,7 @@ SCardApiFunctionTable PCSC_SCardApiFunctionTable = PCSC_SCardGetReaderDeviceInstanceIdW, /* SCardGetReaderDeviceInstanceIdW */ PCSC_SCardListReadersWithDeviceInstanceIdA, /* SCardListReadersWithDeviceInstanceIdA */ PCSC_SCardListReadersWithDeviceInstanceIdW, /* SCardListReadersWithDeviceInstanceIdW */ - PCSC_SCardAudit, /* SCardAudit */ - PCSC_SCardAddReaderName /* SCardAddReaderName */ + PCSC_SCardAudit /* SCardAudit */ }; PSCardApiFunctionTable PCSC_GetSCardApiFunctionTable(void) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.h b/winpr/libwinpr/smartcard/smartcard_pcsc.h index 85d1c32fe..1d85d2567 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.h +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.h @@ -155,7 +155,6 @@ struct _PCSCFunctionTable PCSC_LPDWORD pcbAttrLen); PCSC_LONG(* pfnSCardSetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPCBYTE pbAttr, PCSC_DWORD cbAttrLen); - PCSC_LONG(* pfnSCardAddReaderName)(HANDLE* key, LPSTR readerName); }; typedef struct _PCSCFunctionTable PCSCFunctionTable; diff --git a/winpr/libwinpr/smartcard/smartcard_winscard.c b/winpr/libwinpr/smartcard/smartcard_winscard.c index c4b3b6f2c..29f1002aa 100644 --- a/winpr/libwinpr/smartcard/smartcard_winscard.c +++ b/winpr/libwinpr/smartcard/smartcard_winscard.c @@ -111,8 +111,7 @@ SCardApiFunctionTable WinSCard_SCardApiFunctionTable = NULL, /* SCardGetReaderDeviceInstanceIdW */ NULL, /* SCardListReadersWithDeviceInstanceIdA */ NULL, /* SCardListReadersWithDeviceInstanceIdW */ - NULL, /* SCardAudit */ - NULL /* SCardAddReaderName */ + NULL /* SCardAudit */ }; PSCardApiFunctionTable WinSCard_GetSCardApiFunctionTable(void) From 389b7f218b2806580cf8f70c67669b97b23d429f Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 11 Dec 2017 15:15:02 +0100 Subject: [PATCH 08/15] feat winpr: add WINPR_UNUSED macro WINPR_UNUSED can be used to mark intentionally unused function parameters. --- winpr/include/winpr/winpr.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/winpr/include/winpr/winpr.h b/winpr/include/winpr/winpr.h index cafd692a9..9961e985e 100644 --- a/winpr/include/winpr/winpr.h +++ b/winpr/include/winpr/winpr.h @@ -71,4 +71,6 @@ WINPR_API const char* winpr_get_build_date(void); WINPR_API const char* winpr_get_build_revision(void); WINPR_API const char* winpr_get_build_config(void); +#define WINPR_UNUSED(x) (void)(x) + #endif /* WINPR_H */ From 6b691948cf76c8fd91b7e364ececbfe27991b602 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 11 Dec 2017 15:49:03 +0100 Subject: [PATCH 09/15] refactor winpr/smartcard/pcsc: reader/group naming The PCSC SCard implementation in winpr tried to rename reader and group names received from PCSC to something similar to what the windows smart card service would return. Because of the following reasons this mapping was removed: * reader names are not standardized * no mapping of reader name should be required at all * the mapping added extra complexity * the mapping didn't produce the same names as if the reader was directly connected on windows (or redirected from a windows host) In case there are situations where this is nevertheless required this feature can simple be (re-)implemented a part of the smart card channel. Also the formatting was fixed. --- winpr/libwinpr/smartcard/smartcard_pcsc.c | 630 +++++----------------- 1 file changed, 136 insertions(+), 494 deletions(-) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 997d1eb35..a0bc34453 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -28,15 +28,14 @@ #include #include #include +#include +#include #endif #include #include -#include -#include #include -#include #include #include #include @@ -130,13 +129,6 @@ struct _PCSC_SCARDHANDLE SCARDCONTEXT hSharedContext; }; -struct _PCSC_READER -{ - char* namePCSC; - char* nameWinSCard; -}; -typedef struct _PCSC_READER PCSC_READER; - static HMODULE g_PCSCModule = NULL; static PCSCFunctionTable g_PCSC = { 0 }; @@ -152,16 +144,12 @@ static unsigned int OSXVersion = 0; -static wArrayList* g_Readers = NULL; static wListDictionary* g_CardHandles = NULL; static wListDictionary* g_CardContexts = NULL; 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' }; - 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) }; const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardRawPci = { PCSC_SCARD_PROTOCOL_RAW, sizeof(PCSC_SCARD_IO_REQUEST) }; @@ -171,7 +159,7 @@ 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) +static LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) { /** * pcsc-lite returns SCARD_E_UNEXPECTED when it @@ -187,7 +175,7 @@ LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) return errorCode; } -DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, LONG status) +static DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, LONG status) { /** * pcsc-lite's SCardStatus returns a bit-field, not an enumerated value. @@ -235,7 +223,7 @@ DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, LONG status) return SCARD_UNKNOWN; } -DWORD PCSC_ConvertProtocolsToWinSCard(DWORD dwProtocols) +static DWORD PCSC_ConvertProtocolsToWinSCard(DWORD dwProtocols) { /** * pcsc-lite uses a different value for SCARD_PROTOCOL_RAW, @@ -255,7 +243,7 @@ DWORD PCSC_ConvertProtocolsToWinSCard(DWORD dwProtocols) return dwProtocols; } -DWORD PCSC_ConvertProtocolsFromWinSCard(DWORD dwProtocols) +static DWORD PCSC_ConvertProtocolsFromWinSCard(DWORD dwProtocols) { /** * pcsc-lite uses a different value for SCARD_PROTOCOL_RAW, @@ -280,16 +268,7 @@ DWORD PCSC_ConvertProtocolsFromWinSCard(DWORD dwProtocols) return dwProtocols; } -void PCSC_ReaderAliasFree(PCSC_READER* reader) -{ - if (!reader) - return; - - free(reader->namePCSC); - free(reader->nameWinSCard); -} - -PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext) +static PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; @@ -304,7 +283,7 @@ PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext) return pContext; } -PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext) +static PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; pContext = (PCSC_SCARDCONTEXT*) calloc(1, sizeof(PCSC_SCARDCONTEXT)); @@ -325,16 +304,6 @@ PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext) goto errors; } - if (!g_Readers) - { - g_Readers = ArrayList_New(TRUE); - - if (!g_Readers) - goto errors; - - ArrayList_Object(g_Readers)->fnObjectFree = (OBJECT_FREE_FN) PCSC_ReaderAliasFree; - } - if (!ListDictionary_Add(g_CardContexts, (void*) hContext, (void*) pContext)) goto errors; @@ -346,7 +315,7 @@ error_spinlock: return NULL; } -void PCSC_ReleaseCardContext(SCARDCONTEXT hContext) +static void PCSC_ReleaseCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; pContext = PCSC_GetCardContextData(hContext); @@ -366,7 +335,7 @@ void PCSC_ReleaseCardContext(SCARDCONTEXT hContext) ListDictionary_Remove(g_CardContexts, (void*) hContext); } -BOOL PCSC_LockCardContext(SCARDCONTEXT hContext) +static BOOL PCSC_LockCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; pContext = PCSC_GetCardContextData(hContext); @@ -381,7 +350,7 @@ BOOL PCSC_LockCardContext(SCARDCONTEXT hContext) return TRUE; } -BOOL PCSC_UnlockCardContext(SCARDCONTEXT hContext) +static BOOL PCSC_UnlockCardContext(SCARDCONTEXT hContext) { PCSC_SCARDCONTEXT* pContext; pContext = PCSC_GetCardContextData(hContext); @@ -396,7 +365,7 @@ BOOL PCSC_UnlockCardContext(SCARDCONTEXT hContext) return TRUE; } -PCSC_SCARDHANDLE* PCSC_GetCardHandleData(SCARDHANDLE hCard) +static PCSC_SCARDHANDLE* PCSC_GetCardHandleData(SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; @@ -411,7 +380,7 @@ PCSC_SCARDHANDLE* PCSC_GetCardHandleData(SCARDHANDLE hCard) return pCard; } -SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard) +static SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; pCard = PCSC_GetCardHandleData(hCard); @@ -422,7 +391,7 @@ SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard) return pCard->hSharedContext; } -BOOL PCSC_WaitForCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard, BOOL shared) +static BOOL PCSC_WaitForCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard, BOOL shared) { BOOL status = TRUE; PCSC_SCARDHANDLE* pCard = NULL; @@ -476,7 +445,7 @@ BOOL PCSC_WaitForCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard, BOOL share return status; } -BOOL PCSC_ReleaseCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard) +static BOOL PCSC_ReleaseCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard = NULL; PCSC_SCARDCONTEXT* pContext = NULL; @@ -524,7 +493,7 @@ BOOL PCSC_ReleaseCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard) return TRUE; } -PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hSharedContext, SCARDHANDLE hCard) +static PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hSharedContext, SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; PCSC_SCARDCONTEXT* pContext; @@ -561,7 +530,7 @@ error: return NULL; } -void PCSC_DisconnectCardHandle(SCARDHANDLE hCard) +static void PCSC_DisconnectCardHandle(SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; PCSC_SCARDCONTEXT* pContext; @@ -587,272 +556,7 @@ void PCSC_DisconnectCardHandle(SCARDHANDLE hCard) pContext->dwCardHandleCount--; } -char* PCSC_GetReaderNameFromAlias(char* nameWinSCard) -{ - int index; - int count; - PCSC_READER* reader; - char* namePCSC = NULL; - ArrayList_Lock(g_Readers); - count = ArrayList_Count(g_Readers); - - for (index = 0; index < count; index++) - { - reader = ArrayList_GetItem(g_Readers, index); - - if (strcmp(nameWinSCard, reader->nameWinSCard) == 0) - { - namePCSC = reader->namePCSC; - break; - } - } - - ArrayList_Unlock(g_Readers); - return namePCSC; -} - -BOOL PCSC_AddReaderNameAlias(char* namePCSC, char* nameWinSCard) -{ - PCSC_READER* reader; - - if (PCSC_GetReaderNameFromAlias(nameWinSCard)) - return TRUE; - - reader = (PCSC_READER*) calloc(1, sizeof(PCSC_READER)); - - if (!reader) - return FALSE; - - reader->namePCSC = _strdup(namePCSC); - - if (!reader->namePCSC) - goto error_namePSC; - - reader->nameWinSCard = _strdup(nameWinSCard); - - if (!reader->nameWinSCard) - goto error_nameWinSCard; - - if (ArrayList_Add(g_Readers, reader) < 0) - goto error_add; - - return TRUE; -error_add: - free(reader->nameWinSCard); -error_nameWinSCard: - free(reader->namePCSC); -error_namePSC: - free(reader); - return FALSE; -} - -char* PCSC_ConvertReaderNameToWinSCard(const char* name) -{ - int size; - int length; - int ctoken; - int ntokens; - char* p, *q; - char* tokens[64][2]; - char* nameWinSCard; - - /** - * pcsc-lite reader name format: - * name [interface] (serial) index slot - * - * Athena IDProtect Key v2 [Main Interface] 00 00 - * - * name: Athena IDProtect Key v2 - * interface: Main Interface - * serial: N/A - * index: 00 - * slot: 00 - * - * Athena ASE IIIe 00 00 - * - * name: Athena ASE IIIe - * interface: N/A - * serial: N/A - * index: 00 - * slot: 00 - * - * Athena ASE IIIe [CCID Bulk Interface] 00 00 - * - * name: Athena ASE IIIe - * interface: CCID Bulk Interface - * serial: N/A - * index: 00 - * slot: 00 - * - * Gemalto PC Twin Reader (944B4BF1) 00 00 - * - * name: Gemalto PC Twin Reader - * interface: N/A - * serial: 944B4BF1 - * index: 00 - * slot: 00 - * - * the serial component is optional - * the index is a two digit zero-padded integer - * the slot is a two digit zero-padded integer - */ - if (!name) - return NULL; - - memset(tokens, 0, sizeof(tokens)); - length = strlen(name); - - if (length < 10) - return NULL; - - ntokens = 0; - p = q = (char*) name; - - while (*p) - { - if (*p == ' ') - { - tokens[ntokens][0] = q; - tokens[ntokens][1] = p; - q = p + 1; - ntokens++; - } - - p++; - } - - tokens[ntokens][0] = q; - tokens[ntokens][1] = p; - ntokens++; - - if (ntokens < 2) - return NULL; - - ctoken = ntokens - 1; - p = tokens[0][0]; - q = tokens[ctoken][1]; - length = (q - p); - size = length + 16; - nameWinSCard = (char*) malloc(size); - - if (!nameWinSCard) - return NULL; - - sprintf_s(nameWinSCard, size, "%.*s", length, p); - return nameWinSCard; -} - -char* PCSC_GetReaderAliasFromName(char* namePCSC) -{ - char* nameWinSCard = NULL; - nameWinSCard = PCSC_ConvertReaderNameToWinSCard(namePCSC); - - if (nameWinSCard) - PCSC_AddReaderNameAlias(namePCSC, nameWinSCard); - - return nameWinSCard; -} - -char* PCSC_ConvertReaderNamesToWinSCard(const char* names, LPDWORD pcchReaders) -{ - int ret = 0; - int length; - char* p, *q; - DWORD cchReaders; - char* nameWinSCard; - char* namesWinSCard; - BOOL endReaderName = FALSE; - BOOL allReaders = FALSE; - p = (char*) names; - cchReaders = *pcchReaders; - namesWinSCard = (char*) calloc(cchReaders, 2); - - if (!namesWinSCard) - return NULL; - - q = namesWinSCard; - p = (char*) names; - - while ((p - names) < cchReaders) - { - nameWinSCard = PCSC_GetReaderAliasFromName(p); - - if (nameWinSCard) - { - length = strlen(nameWinSCard); - CopyMemory(q, nameWinSCard, length); - allReaders = TRUE; - - free(nameWinSCard); - } - else - { - length = strlen(p); - CopyMemory(q, p, length); - } - - if (endReaderName) - { - q += length; - *q = '\0'; - q++; - endReaderName = FALSE; - } - else if (allReaders) - { - q += length; - *q = '\0'; - q++; - } - - p += strlen(p) + 1; - } - - *q = '\0'; - q++; - *pcchReaders = (DWORD)(q - namesWinSCard); - return namesWinSCard; -} - -char* PCSC_ConvertReaderNamesToPCSC(const char* names, LPDWORD pcchReaders) -{ - int length; - char* p, *q; - char* namePCSC; - char* namesPCSC; - DWORD cchReaders; - p = (char*) names; - cchReaders = *pcchReaders; - namesPCSC = (char*) calloc(cchReaders, 2); - - if (!namesPCSC) - return NULL; - - q = namesPCSC; - p = (char*) names; - - while ((p - names) < cchReaders) - { - namePCSC = PCSC_GetReaderNameFromAlias(p); - - if (!namePCSC) - namePCSC = p; - - length = strlen(namePCSC); - CopyMemory(q, namePCSC, length); - q += length; - *q = '\0'; - q++; - p += strlen(p) + 1; - } - - *q = '\0'; - q++; - *pcchReaders = (DWORD)(q - namesPCSC); - return namesPCSC; -} - -BOOL PCSC_AddMemoryBlock(SCARDCONTEXT hContext, void* pvMem) +static BOOL PCSC_AddMemoryBlock(SCARDCONTEXT hContext, void* pvMem) { if (!g_MemoryBlocks) { @@ -865,31 +569,16 @@ BOOL PCSC_AddMemoryBlock(SCARDCONTEXT hContext, void* pvMem) return ListDictionary_Add(g_MemoryBlocks, pvMem, (void*) hContext); } -void* PCSC_RemoveMemoryBlock(SCARDCONTEXT hContext, void* pvMem) +static void* PCSC_RemoveMemoryBlock(SCARDCONTEXT hContext, void* pvMem) { + WINPR_UNUSED(hContext); + if (!g_MemoryBlocks) return NULL; return ListDictionary_Remove(g_MemoryBlocks, pvMem); } -void* PCSC_SCardAllocMemory(SCARDCONTEXT hContext, size_t size) -{ - void* pvMem; - pvMem = malloc(size); - - if (!pvMem) - return NULL; - - if (!PCSC_AddMemoryBlock(hContext, pvMem)) - { - free(pvMem); - return NULL; - } - - return pvMem; -} - /** * Standard Windows Smart Card API (PCSC) */ @@ -897,14 +586,14 @@ void* PCSC_SCardAllocMemory(SCARDCONTEXT hContext, size_t size) WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) { + WINPR_UNUSED(dwScope); /* SCARD_SCOPE_SYSTEM is the only scope supported by pcsc-lite */ LONG status = SCARD_S_SUCCESS; - PCSC_DWORD pcsc_dwScope = (PCSC_DWORD) dwScope; if (!g_PCSC.pfnSCardEstablishContext) return SCARD_E_NO_SERVICE; - pcsc_dwScope = SCARD_SCOPE_SYSTEM; /* this is the only scope supported by pcsc-lite */ - status = (LONG) g_PCSC.pfnSCardEstablishContext(pcsc_dwScope, pvReserved1, pvReserved2, phContext); + status = (LONG) g_PCSC.pfnSCardEstablishContext(SCARD_SCOPE_SYSTEM, pvReserved1, pvReserved2, + phContext); status = PCSC_MapErrorCodeToWinSCard(status); return status; } @@ -912,7 +601,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) { - LONG status = SCARD_S_SUCCESS; + LONG status; status = PCSC_SCardEstablishContext_Internal(dwScope, pvReserved1, pvReserved2, phContext); if (status == SCARD_S_SUCCESS) @@ -966,7 +655,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaderGroups_Internal(SCARDCONTEXT hContex LPSTR mszGroups, LPDWORD pcchGroups) { LONG status = SCARD_S_SUCCESS; - char* mszGroupsWinSCard = NULL; BOOL pcchGroupsAlloc = FALSE; LPSTR* pMszGroups = (LPSTR*) mszGroups; PCSC_DWORD pcsc_cchGroups = 0; @@ -1009,19 +697,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaderGroups_Internal(SCARDCONTEXT hContex status = PCSC_MapErrorCodeToWinSCard(status); *pcchGroups = (DWORD) pcsc_cchGroups; - - if (status == SCARD_S_SUCCESS) - { - mszGroupsWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszGroups, pcchGroups); - - if (mszGroupsWinSCard) - { - PCSC_SCardFreeMemory_Internal(hContext, *pMszGroups); - *pMszGroups = mszGroupsWinSCard; - PCSC_AddMemoryBlock(hContext, *pMszGroups); - } - } - return status; } @@ -1076,7 +751,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) { LONG status = SCARD_S_SUCCESS; - char* mszReadersWinSCard = NULL; BOOL pcchReadersAlloc = FALSE; LPSTR* pMszReaders = (LPSTR*) mszReaders; PCSC_DWORD pcsc_cchReaders = 0; @@ -1121,19 +795,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext, status = PCSC_MapErrorCodeToWinSCard(status); *pcchReaders = (DWORD) pcsc_cchReaders; - - if (status == SCARD_S_SUCCESS) - { - mszReadersWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszReaders, pcchReaders); - - if (mszReadersWinSCard) - { - PCSC_SCardFreeMemory_Internal(hContext, *pMszReaders); - *pMszReaders = mszReadersWinSCard; - PCSC_AddMemoryBlock(hContext, *pMszReaders); - } - } - return status; } @@ -1491,8 +1152,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext { int i, j; int* map; - DWORD dwEventState; - BOOL stateChanged = FALSE; PCSC_DWORD cMappedReaders; PCSC_SCARD_READERSTATE* states; LONG status = SCARD_S_SUCCESS; @@ -1537,7 +1196,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext { if (!g_PnP_Notification) { - if (strcmp(rgReaderStates[i].szReader, SMARTCARD_PNP_NOTIFICATION_A) == 0) + if (0 == _stricmp(rgReaderStates[i].szReader, SMARTCARD_PNP_NOTIFICATION_A)) { map[i] = -1; /* unmapped */ continue; @@ -1545,11 +1204,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext } map[i] = j; - states[j].szReader = PCSC_GetReaderNameFromAlias((char*) rgReaderStates[i].szReader); - - if (!states[j].szReader) - states[j].szReader = rgReaderStates[i].szReader; - + states[j].szReader = rgReaderStates[i].szReader; states[j].dwCurrentState = rgReaderStates[i].dwCurrentState; states[j].pvUserData = rgReaderStates[i].pvUserData; states[j].dwEventState = rgReaderStates[i].dwEventState; @@ -1580,7 +1235,7 @@ 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); - rgReaderStates[i].dwEventState = states[j].dwEventState; + rgReaderStates[i].dwEventState = states[j].dwEventState; } free(map); @@ -1674,7 +1329,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) { BOOL shared; - BOOL access; char* szReaderPCSC; LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; @@ -1686,11 +1340,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, return SCARD_E_NO_SERVICE; shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE; - access = PCSC_WaitForCardAccess(hContext, 0, shared); - szReaderPCSC = PCSC_GetReaderNameFromAlias((char*) szReader); - - if (!szReaderPCSC) - szReaderPCSC = (char*) szReader; + PCSC_WaitForCardAccess(hContext, 0, shared); + szReaderPCSC = (char*) szReader; /** * As stated here : https://pcsclite.alioth.debian.org/api/group__API.html#ga4e515829752e0a8dbc4d630696a8d6a5 @@ -1762,7 +1413,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol) { BOOL shared; - BOOL access; LONG status = SCARD_S_SUCCESS; PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD) dwShareMode; PCSC_DWORD pcsc_dwPreferredProtocols = 0; @@ -1773,7 +1423,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, return SCARD_E_NO_SERVICE; shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE; - access = PCSC_WaitForCardAccess(0, hCard, shared); + PCSC_WaitForCardAccess(0, hCard, shared); pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols); status = (LONG) g_PCSC.pfnSCardReconnect(hCard, pcsc_dwShareMode, pcsc_dwPreferredProtocols, pcsc_dwInitialization, &pcsc_dwActiveProtocol); @@ -1906,22 +1556,27 @@ WINSCARDAPI LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, return status; } +/* + * PCSC returns a string but Windows SCardStatus requires the return to be a multi string. + * Therefore extra length checks and additional buffer allocation is required + */ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { - SCARDCONTEXT hContext; - char* mszReaderNamesWinSCard = NULL; - BOOL pcbAtrLenAlloc = FALSE; - BOOL pcchReaderLenAlloc = FALSE; - LPBYTE* pPbAtr = (LPBYTE*) pbAtr; - LPSTR* pMszReaderNames = (LPSTR*) mszReaderNames; - LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; + SCARDCONTEXT hContext; + LONG status; PCSC_DWORD pcsc_cchReaderLen = 0; + PCSC_DWORD pcsc_cbAtrLen = 0; PCSC_DWORD pcsc_dwState = 0; PCSC_DWORD pcsc_dwProtocol = 0; - PCSC_DWORD pcsc_cbAtrLen = 0; + BOOL allocateReader = FALSE; + BOOL allocateAtr = FALSE; + LPSTR readerNames = mszReaderNames; + LPBYTE atr = pbAtr; + LPSTR tReader = NULL; + LPBYTE tATR = NULL; if (!g_PCSC.pfnSCardStatus) return SCARD_E_NO_SERVICE; @@ -1934,109 +1589,113 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, PCSC_WaitForCardAccess(0, hCard, pCard->shared); hContext = PCSC_GetCardContextFromHandle(hCard); - if (!hContext || !pcchReaderLen || !pdwState || !pdwProtocol || !pcbAtrLen) + if (!hContext) return SCARD_E_INVALID_VALUE; - if (*pcchReaderLen == SCARD_AUTOALLOCATE) - pcchReaderLenAlloc = TRUE; + status = (LONG) g_PCSC.pfnSCardStatus(hCard, NULL, &pcsc_cchReaderLen, NULL, NULL, NULL, + &pcsc_cbAtrLen); - pcsc_cchReaderLen = pcchReaderLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcchReaderLen; + if (status != STATUS_SUCCESS) + return PCSC_MapErrorCodeToWinSCard(status); - if (*pcbAtrLen == SCARD_AUTOALLOCATE) - pcbAtrLenAlloc = TRUE; + pcsc_cchReaderLen++; - pcsc_cbAtrLen = pcbAtrLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcbAtrLen; - - if ((pcchReaderLenAlloc || pcbAtrLenAlloc) && !g_SCardAutoAllocate) + if (pcchReaderLen) { - if (pcchReaderLenAlloc) - pcsc_cchReaderLen = 0; + if (*pcchReaderLen == SCARD_AUTOALLOCATE) + allocateReader = TRUE; + else if (mszReaderNames && (*pcchReaderLen < pcsc_cchReaderLen)) + return SCARD_E_INSUFFICIENT_BUFFER; + else + pcsc_cchReaderLen = *pcchReaderLen; + } - if (pcbAtrLenAlloc) - pcsc_cbAtrLen = 0; + if (pcbAtrLen) + { + if (*pcbAtrLen == SCARD_AUTOALLOCATE) + allocateAtr = TRUE; + else if (pbAtr && (*pcbAtrLen < pcsc_cbAtrLen)) + return SCARD_E_INSUFFICIENT_BUFFER; + else + pcsc_cbAtrLen = *pcbAtrLen; + } - status = (LONG) g_PCSC.pfnSCardStatus(hCard, - (pcchReaderLenAlloc) ? NULL : mszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, - (pcbAtrLenAlloc) ? NULL : pbAtr, &pcsc_cbAtrLen); - - if (status == SCARD_S_SUCCESS) - { - if (pcchReaderLenAlloc) - { + if (allocateReader && pcsc_cchReaderLen > 0 && mszReaderNames) + { #ifdef __MACOSX__ - /** - * Workaround for SCardStatus Bug in MAC OS X Yosemite - */ - if (OSXVersion == 0x10100000) - pcsc_cchReaderLen++; + /** + * Workaround for SCardStatus Bug in MAC OS X Yosemite + */ + if (OSXVersion == 0x10100000) + pcsc_cchReaderLen++; #endif - *pMszReaderNames = (LPSTR) calloc(1, pcsc_cchReaderLen); + tReader = calloc(1, pcsc_cchReaderLen); - if (!*pMszReaderNames) - return SCARD_E_NO_MEMORY; - } - - if (pcbAtrLenAlloc) - { - *pPbAtr = (BYTE*) calloc(1, pcsc_cbAtrLen); - - if (!*pPbAtr) - return SCARD_E_NO_MEMORY; - } - - status = (LONG) g_PCSC.pfnSCardStatus(hCard, - *pMszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, - pbAtr, &pcsc_cbAtrLen); - - if (status != SCARD_S_SUCCESS) - { - if (pcchReaderLenAlloc) - { - free(*pMszReaderNames); - *pMszReaderNames = NULL; - } - - if (pcbAtrLenAlloc) - { - free(*pPbAtr); - *pPbAtr = NULL; - } - } - else - { - if (pcchReaderLenAlloc) - PCSC_AddMemoryBlock(hContext, *pMszReaderNames); - - if (pcbAtrLenAlloc) - PCSC_AddMemoryBlock(hContext, *pPbAtr); - } + if (!tReader) + { + status = ERROR_NOT_ENOUGH_MEMORY; + goto out_fail; } - } - else - { - status = (LONG) g_PCSC.pfnSCardStatus(hCard, mszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen); + + readerNames = tReader; } - status = PCSC_MapErrorCodeToWinSCard(status); - *pcchReaderLen = (DWORD) pcsc_cchReaderLen; - mszReaderNamesWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszReaderNames, pcchReaderLen); - - if (mszReaderNamesWinSCard) + if (allocateAtr && pcsc_cbAtrLen > 0 && pbAtr) { - PCSC_SCardFreeMemory_Internal(hContext, *pMszReaderNames); - *pMszReaderNames = mszReaderNamesWinSCard; - PCSC_AddMemoryBlock(hContext, *pMszReaderNames); + tATR = calloc(1, pcsc_cbAtrLen); + + if (!tATR) + { + status = ERROR_NOT_ENOUGH_MEMORY; + goto out_fail; + } + + atr = tATR; + } + + status = (LONG) g_PCSC.pfnSCardStatus(hCard, readerNames, &pcsc_cchReaderLen, &pcsc_dwState, + &pcsc_dwProtocol, atr, + &pcsc_cbAtrLen); + + if (status != STATUS_SUCCESS) + goto out_fail; + + if (tATR) + { + PCSC_AddMemoryBlock(hContext, tATR); + *(LPBYTE*)pbAtr = tATR; + } + + if (tReader) + { + PCSC_AddMemoryBlock(hContext, tReader); + *(LPSTR*)mszReaderNames = tReader; } pcsc_dwState &= 0xFFFF; - *pdwState = PCSC_ConvertCardStateToWinSCard((DWORD) pcsc_dwState, status); - *pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwProtocol); - *pcbAtrLen = (DWORD) pcsc_cbAtrLen; + + if (pdwState) + *pdwState = PCSC_ConvertCardStateToWinSCard((DWORD) pcsc_dwState, status); + + if (pdwProtocol) + *pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwProtocol); + + if (pcbAtrLen) + *pcbAtrLen = (DWORD) pcsc_cbAtrLen; + + if (pcchReaderLen) + *pcchReaderLen = pcsc_cchReaderLen + 1; + + /* Make sure the last byte is set */ + if (readerNames) + readerNames[pcsc_cchReaderLen] = '\0'; + + return status; +out_fail: + free(tReader); + free(tATR); return status; } @@ -2192,6 +1851,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, WINSCARDAPI LONG WINAPI PCSC_SCardGetTransmitCount(SCARDHANDLE hCard, LPDWORD pcTransmitCount) { + WINPR_UNUSED(pcTransmitCount); PCSC_SCARDHANDLE* pCard = NULL; pCard = PCSC_GetCardHandleData(hCard); @@ -2347,7 +2007,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR { int length = 0; char* namePCSC = NULL; - char* nameWinSCard; DWORD cbAttrLen = 0; char* pbAttrA = NULL; WCHAR* pbAttrW = NULL; @@ -2376,8 +2035,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR if (status != SCARD_S_SUCCESS) return status; - length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW, *pcbAttrLen, (char**) &pbAttrA, 0, NULL, - NULL); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW, *pcbAttrLen, (char**) &pbAttrA, 0, NULL, + NULL); namePCSC = pbAttrA; PCSC_SCardFreeMemory_Internal(hContext, pbAttrW); } @@ -2392,24 +2051,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR } length = strlen(namePCSC); - nameWinSCard = PCSC_GetReaderAliasFromName(namePCSC); - - if (nameWinSCard) - { - length = strlen(nameWinSCard); - friendlyNameA = _strdup(nameWinSCard); - - if (!friendlyNameA) - { - free(namePCSC); - return SCARD_E_NO_MEMORY; - } - } - else - { - friendlyNameA = namePCSC; - namePCSC = NULL; - } + friendlyNameA = namePCSC; + namePCSC = NULL; if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W) { @@ -2471,7 +2114,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR } free(namePCSC); - free(nameWinSCard); return status; } From bc8bdc3e54e665d9a72117c5deea54e0d89b0e1c Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Mon, 11 Dec 2017 16:25:46 +0100 Subject: [PATCH 10/15] fix channel/smartcard: compiler warnings * remove unused variables * remove unused jump label --- channels/smartcard/client/smartcard_main.c | 1 - channels/smartcard/client/smartcard_operations.c | 1 - libfreerdp/common/settings.c | 2 -- 3 files changed, 4 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index d3555f91c..6fb6b5a91 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -680,7 +680,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) size_t length; RDPDR_SMARTCARD* device; SMARTCARD_DEVICE* smartcard; - LONG status; UINT error = CHANNEL_RC_NO_MEMORY; device = (RDPDR_SMARTCARD*) pEntryPoints->device; smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE)); diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 3070ab33d..ccb8d7f8f 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -581,7 +581,6 @@ static LONG smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard, static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { - LONG status; UINT32 index; GetStatusChange_Return ret; LPSCARD_READERSTATEA rgReaderState = NULL; diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index fd4b008f7..9bf72a435 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -309,8 +309,6 @@ out_print_name_error: return (RDPDR_DEVICE*) _smartcard; -out_smartc_path_error: - free(_smartcard->Name); out_smartc_name_error: free(_smartcard); return NULL; From 9fc754170b9bd5ffdb37465d97e3d7209d02ce29 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 13 Dec 2017 15:46:50 +0100 Subject: [PATCH 11/15] fix channel/smartcard: SCardStatus Add support for fmszReaderNamesIsNULL. Formating of the touched files was also updated. --- .../smartcard/client/smartcard_operations.c | 74 +++++++++++++------ channels/smartcard/client/smartcard_pack.c | 44 +++++------ 2 files changed, 75 insertions(+), 43 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index ccb8d7f8f..cea58e971 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -586,13 +586,14 @@ static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, LPSCARD_READERSTATEA rgReaderState = NULL; IRP* irp = operation->irp; GetStatusChangeA_Call* call = operation->call; - ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, call->dwTimeOut, call->rgReaderStates, call->cReaders); - + ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, call->dwTimeOut, call->rgReaderStates, + call->cReaders); ret.cReaders = call->cReaders; ret.rgReaderStates = NULL; - if (ret.cReaders > 0) { - ret.rgReaderStates = (ReaderState_Return *) calloc(ret.cReaders, sizeof(ReaderState_Return)); + if (ret.cReaders > 0) + { + ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); if (!ret.rgReaderStates) return STATUS_NO_MEMORY; @@ -652,13 +653,13 @@ static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, IRP* irp = operation->irp; GetStatusChangeW_Call* call = operation->call; ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut, - call->rgReaderStates, call->cReaders); - + call->rgReaderStates, call->cReaders); ret.cReaders = call->cReaders; ret.rgReaderStates = NULL; - if (ret.cReaders > 0) { - ret.rgReaderStates = (ReaderState_Return *) calloc(ret.cReaders, sizeof(ReaderState_Return)); + if (ret.cReaders > 0) + { + ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); if (!ret.rgReaderStates) return STATUS_NO_MEMORY; @@ -1043,23 +1044,36 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT LONG status; Status_Return ret = { 0 }; DWORD cchReaderLen = 0; + DWORD cbAtrLen = 0; LPSTR mszReaderNames = NULL; IRP* irp = operation->irp; Status_Call* call = operation->call; + ZeroMemory(ret.pbAtr, 32); if (call->cbAtrLen > 32) call->cbAtrLen = 32; - ret.cbAtrLen = call->cbAtrLen; - ZeroMemory(ret.pbAtr, 32); - cchReaderLen = SCARD_AUTOALLOCATE; - status = ret.ReturnCode = SCardStatusA(operation->hCard, (LPSTR) &mszReaderNames, &cchReaderLen, - &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); + cbAtrLen = call->cbAtrLen; + + if (call->fmszReaderNamesIsNULL) + cchReaderLen = 0; + else + cchReaderLen = SCARD_AUTOALLOCATE; + + status = ret.ReturnCode = SCardStatusA(operation->hCard, + call->fmszReaderNamesIsNULL ? NULL : (LPSTR) &mszReaderNames, + &cchReaderLen, &ret.dwState, &ret.dwProtocol, + cbAtrLen ? (BYTE*) &ret.pbAtr : NULL, &cbAtrLen); if (status == SCARD_S_SUCCESS) { - ret.mszReaderNames = (BYTE*) mszReaderNames; + if (!call->fmszReaderNamesIsNULL) + ret.mszReaderNames = (BYTE*) mszReaderNames; + ret.cBytes = cchReaderLen; + + if (call->cbAtrLen) + ret.cbAtrLen = cbAtrLen; } smartcard_trace_status_return(smartcard, &ret, FALSE); @@ -1071,7 +1085,9 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT } if (mszReaderNames) + { SCardFreeMemory(operation->hContext, mszReaderNames); + } return ret.ReturnCode; } @@ -1103,19 +1119,34 @@ static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT LPWSTR mszReaderNames = NULL; IRP* irp = operation->irp; Status_Call* call = operation->call; + DWORD cbAtrLen; if (call->cbAtrLen > 32) call->cbAtrLen = 32; + if (call->fmszReaderNamesIsNULL) + cchReaderLen = 0; + else + cchReaderLen = SCARD_AUTOALLOCATE; + ret.cbAtrLen = call->cbAtrLen; ZeroMemory(ret.pbAtr, 32); - cchReaderLen = SCARD_AUTOALLOCATE; - status = ret.ReturnCode = SCardStatusW(operation->hCard, (LPWSTR) &mszReaderNames, &cchReaderLen, - &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); - ret.mszReaderNames = (BYTE*) mszReaderNames; - ret.cBytes = cchReaderLen * 2; + status = ret.ReturnCode = SCardStatusW(operation->hCard, + call->fmszReaderNamesIsNULL ? NULL : (LPWSTR) &mszReaderNames, + &cchReaderLen, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &cbAtrLen); smartcard_trace_status_return(smartcard, &ret, TRUE); + if (status == SCARD_S_SUCCESS) + { + if (!call->fmszReaderNamesIsNULL) + ret.mszReaderNames = (BYTE*) mszReaderNames; + + ret.cBytes = cchReaderLen * 2; + + if (call->cbAtrLen) + ret.cbAtrLen = cbAtrLen; + } + if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret))) { WLog_ERR(TAG, "smartcard_pack_status_return failed with error %"PRId32"", status); @@ -2017,10 +2048,9 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH); /* Device Control Response */ Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */ - smartcard_pack_common_type_header(smartcard, irp->output); /* CommonTypeHeader (8 bytes) */ - smartcard_pack_private_type_header(smartcard, irp->output, objectBufferLength); /* PrivateTypeHeader (8 bytes) */ - + smartcard_pack_private_type_header(smartcard, irp->output, + objectBufferLength); /* PrivateTypeHeader (8 bytes) */ Stream_Write_UINT32(irp->output, result); /* Result (4 bytes) */ Stream_SetPosition(irp->output, Stream_Length(irp->output)); return SCARD_S_SUCCESS; diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 373064e67..fed0d2a0c 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -1863,32 +1863,34 @@ void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, Status_Return* r if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) return; - if (unicode) + if (ret->mszReaderNames) { - length = ret->cBytes / 2; - - if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) ret->mszReaderNames, (int)length, - &mszReaderNamesA, 0, NULL, NULL) < 1) + if (unicode) { - WLog_ERR(TAG, "ConvertFromUnicode failed"); - return; + length = ret->cBytes / 2; + + if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) ret->mszReaderNames, (int) length, + &mszReaderNamesA, 0, NULL, NULL) < 1) + { + WLog_ERR(TAG, "ConvertFromUnicode failed"); + return; + } + } + else + { + length = (int) ret->cBytes; + mszReaderNamesA = (char*) malloc(length); + + if (!mszReaderNamesA) + { + WLog_ERR(TAG, "malloc failed!"); + return; + } + + CopyMemory(mszReaderNamesA, ret->mszReaderNames, ret->cBytes); } } else - { - length = (int) ret->cBytes; - mszReaderNamesA = (char*) malloc(length); - - if (!mszReaderNamesA) - { - WLog_ERR(TAG, "malloc failed!"); - return; - } - - CopyMemory(mszReaderNamesA, ret->mszReaderNames, ret->cBytes); - } - - if (!mszReaderNamesA) length = 0; if (length > 2) From bff9b98e67f40375921a323859fa8dd9e6a6c0eb Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 13 Dec 2017 15:50:33 +0100 Subject: [PATCH 12/15] feat winpr/smartcard: add test for SCardStatus Add an extensive test for SCardStatus. It's not enabled per default as it requires a reader with card to be present. --- .../smartcard/test/TestSmartCardStatus.c | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 winpr/libwinpr/smartcard/test/TestSmartCardStatus.c diff --git a/winpr/libwinpr/smartcard/test/TestSmartCardStatus.c b/winpr/libwinpr/smartcard/test/TestSmartCardStatus.c new file mode 100644 index 000000000..a830685e1 --- /dev/null +++ b/winpr/libwinpr/smartcard/test/TestSmartCardStatus.c @@ -0,0 +1,166 @@ +// compile against PCSC gcc -o scardtest TestSmartCardStatus.c -DPCSC=1 -I /usr/include/PCSC -lpcsclite +#include +#include +#include +#if defined(__APPLE__) || defined(PCSC) +#include +#include +#elif defined (__linux__) +#include +#include +#include +#else +#include +#endif + +#if defined(PCSC) +int main(int argc, char* argv[]) +#else +int TestSmartCardStatus(int argc, char* argv[]) +#endif +{ + SCARDCONTEXT hContext; + LPSTR mszReaders; + DWORD cchReaders = 0; + DWORD err; + SCARDHANDLE hCard; + DWORD dwActiveProtocol; + char name[100]; + char* aname = NULL; + char* aatr = NULL; + DWORD len; + BYTE atr[32]; + DWORD atrlen = 32; + DWORD status = 0; + DWORD protocol = 0; + err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); + + if (err != SCARD_S_SUCCESS) + { + printf("ScardEstablishedContext: 0x%08x\n", err); + return -1; + } + + err = SCardListReaders(hContext, "SCard$AllReaders", NULL, &cchReaders); + + if (err != 0) + { + printf("ScardListReaders: 0x%08x\n", err); + return -1; + } + + mszReaders = calloc(cchReaders, sizeof(char)); + + if (!mszReaders) + { + printf("calloc\n"); + return -1; + } + + err = SCardListReaders(hContext, "SCard$AllReaders", mszReaders, &cchReaders); + + if (err != SCARD_S_SUCCESS) + { + printf("ScardListReaders: 0x%08x\n", err); + return -1; + } + + printf("Reader: %s\n", mszReaders); + err = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, + &hCard, &dwActiveProtocol); + + if (err != SCARD_S_SUCCESS) + { + printf("ScardConnect: 0x%08x\n", err); + return -1; + } + + free(mszReaders); + + + printf("# test 1 - get reader length\n"); + err = SCardStatus(hCard, NULL, &len, NULL, NULL, NULL, NULL); + if (err != SCARD_S_SUCCESS) + { + printf("SCardStatus: 0x%08x\n", err); + return -1; + } + printf("reader name length: %u\n", len); + + + printf("# test 2 - get reader name value\n"); + err = SCardStatus(hCard, name, &len, NULL, NULL, NULL, NULL); + if (err != SCARD_S_SUCCESS) + { + printf("SCardStatus: 0x%08x\n", err); + return -1; + } + printf("Reader name: %s (%ld)\n", name, strlen(name)); + + + printf("# test 3 - get all values - pre allocated\n"); + err = SCardStatus(hCard, name, &len, &status, &protocol, atr, &atrlen); + if (err != SCARD_S_SUCCESS) + { + printf("SCardStatus: 0x%08x\n", err); + return -1; + } + printf("Reader name: %s (%ld/len %u)\n", name, strlen(name), len); + printf("status: 0x%08X\n", status); + printf("proto: 0x%08X\n", protocol); + printf("atrlen: %u\n", atrlen); + + + printf("# test 4 - get all values - auto allocate\n"); + len = atrlen = SCARD_AUTOALLOCATE; + err = SCardStatus(hCard, (LPSTR)&aname, &len, &status, &protocol, (LPBYTE)&aatr, &atrlen); + if (err != SCARD_S_SUCCESS) + { + printf("SCardStatus: 0x%08x\n", err); + return -1; + } + printf("Reader name: %s (%ld/%u)\n", aname, strlen(aname), len); + printf("status: 0x%08X\n", status); + printf("proto: 0x%08X\n", protocol); + printf("atrlen: %u\n", atrlen); + SCardFreeMemory(hContext, aname); + SCardFreeMemory(hContext, aatr); + + + printf("# test 5 - get status and protocol only\n"); + err = SCardStatus(hCard, NULL, NULL, &status, &protocol, NULL, NULL); + if (err != SCARD_S_SUCCESS) + { + printf("SCardStatus: 0x%08x\n", err); + return -1; + } + printf("status: 0x%08X\n", status); + printf("proto: 0x%08X\n", protocol); + + + printf("# test 6 - get atr only auto allocated\n"); + atrlen = SCARD_AUTOALLOCATE; + err = SCardStatus(hCard, NULL, NULL, NULL, NULL, (LPBYTE)&aatr, &atrlen); + if (err != SCARD_S_SUCCESS) + { + printf("SCardStatus: 0x%08x\n", err); + return -1; + } + printf("atrlen: %u\n", atrlen); + SCardFreeMemory(hContext, aatr); + + + printf("# test 7 - get atr only pre allocated\n"); + atrlen = 32; + err = SCardStatus(hCard, NULL, NULL, NULL, NULL, atr, &atrlen); + if (err != SCARD_S_SUCCESS) + { + printf("SCardStatus: 0x%08x\n", err); + return -1; + } + printf("atrlen: %u\n", atrlen); + SCardDisconnect(hCard, SCARD_LEAVE_CARD); + SCardReleaseContext(hContext); + + return 0; +} From 94b35cb4f7d7bc272519c1a018c87d9ddbb897a4 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 13 Dec 2017 16:57:53 +0100 Subject: [PATCH 13/15] fix channel/smartcard: leak in Connect[AW] smartcard_Connect[AW] leaked the reader buffer in error case. --- .../smartcard/client/smartcard_operations.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index cea58e971..d0ed44f4d 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -767,17 +767,20 @@ static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA if (status) { WLog_ERR(TAG, "SCardConnectA failed with error %"PRId32"", status); - return status; + goto out_fail; } if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret))) { WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %"PRId32"", status); - return status; + goto out_fail; } + status = ret.ReturnCode; + +out_fail: free(call->szReader); - return ret.ReturnCode; + return status; } static LONG smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) @@ -823,17 +826,20 @@ static LONG smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA if (status) { WLog_ERR(TAG, "SCardConnectW failed with error %"PRId32"", status); - return status; + goto out_fail; } if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret))) { WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %"PRId32"", status); - return status; + goto out_fail; } + status = ret.ReturnCode; + +out_fail: free(call->szReader); - return ret.ReturnCode; + return status; } static LONG smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) From 5a1c0081c5ca08968f738750ec71cff1c2fafd7c Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Thu, 14 Dec 2017 15:46:14 +0100 Subject: [PATCH 14/15] fix smartcard: SCardStatus unicode handling * fix StatusW_Call to rely and use SCardStatusW * fix trace call in StatusW_Call - needs to be called after the sizes are set * unify SCardStatus functions for pcsc - let the internal function handle unicode directly This fixes an issue with size calculations of SCardStatusW. --- .../smartcard/client/smartcard_operations.c | 7 +- winpr/libwinpr/smartcard/smartcard_pcsc.c | 69 ++++++++++--------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index d0ed44f4d..8183194b4 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1135,23 +1135,24 @@ static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT else cchReaderLen = SCARD_AUTOALLOCATE; - ret.cbAtrLen = call->cbAtrLen; + cbAtrLen = call->cbAtrLen; + ZeroMemory(ret.pbAtr, 32); status = ret.ReturnCode = SCardStatusW(operation->hCard, call->fmszReaderNamesIsNULL ? NULL : (LPWSTR) &mszReaderNames, &cchReaderLen, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &cbAtrLen); - smartcard_trace_status_return(smartcard, &ret, TRUE); if (status == SCARD_S_SUCCESS) { if (!call->fmszReaderNamesIsNULL) ret.mszReaderNames = (BYTE*) mszReaderNames; - ret.cBytes = cchReaderLen * 2; + ret.cBytes = cchReaderLen; if (call->cbAtrLen) ret.cbAtrLen = cbAtrLen; } + smartcard_trace_status_return(smartcard, &ret, TRUE); if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret))) { diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index a0bc34453..bbe8afbc6 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -1562,7 +1562,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, */ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, - LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) + LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen, BOOL unicode) { PCSC_SCARDHANDLE* pCard = NULL; SCARDCONTEXT hContext; @@ -1600,6 +1600,9 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, pcsc_cchReaderLen++; + if (unicode) + pcsc_cchReaderLen *= 2; + if (pcchReaderLen) { if (*pcchReaderLen == SCARD_AUTOALLOCATE) @@ -1670,8 +1673,29 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, if (tReader) { - PCSC_AddMemoryBlock(hContext, tReader); - *(LPSTR*)mszReaderNames = tReader; + if (unicode) + { + LPSTR mszReaderNamesW = NULL; + int pcsc_cchReaderLenW = 0; + pcsc_cchReaderLenW = ConvertToUnicode(CP_UTF8, 0, tReader, *pcchReaderLen, + (WCHAR**) &mszReaderNamesW, 0); + + if (pcsc_cchReaderLenW <= 0 || mszReaderNamesW == NULL) + { + status = ERROR_NOT_ENOUGH_MEMORY; + goto out_fail; + } + + readerNames = mszReaderNamesW; + free(tReader); + PCSC_AddMemoryBlock(hContext, mszReaderNamesW); + *(LPSTR*) mszReaderNames = mszReaderNamesW; + } + else + { + PCSC_AddMemoryBlock(hContext, tReader); + *(LPSTR*) mszReaderNames = tReader; + } } pcsc_dwState &= 0xFFFF; @@ -1686,7 +1710,12 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, *pcbAtrLen = (DWORD) pcsc_cbAtrLen; if (pcchReaderLen) - *pcchReaderLen = pcsc_cchReaderLen + 1; + { + if (unicode) + *pcchReaderLen = (pcsc_cchReaderLen + 1) * 2; + else + *pcchReaderLen = pcsc_cchReaderLen + 1; + } /* Make sure the last byte is set */ if (readerNames) @@ -1703,40 +1732,16 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { - LONG status = SCARD_S_SUCCESS; - status = PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, - pbAtr, pcbAtrLen); - return status; + return PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, + pbAtr, pcbAtrLen, FALSE); } WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { - SCARDCONTEXT hContext = 0; - LPSTR mszReaderNamesA = NULL; - LONG status = SCARD_S_SUCCESS; - - if (!g_PCSC.pfnSCardStatus) - return SCARD_E_NO_SERVICE; - - hContext = PCSC_GetCardContextFromHandle(hCard); - - if (!hContext) - return SCARD_E_INVALID_VALUE; - - status = PCSC_SCardStatus_Internal(hCard, (LPSTR) &mszReaderNamesA, pcchReaderLen, pdwState, - pdwProtocol, pbAtr, pcbAtrLen); - - if (mszReaderNamesA) - { - *pcchReaderLen = ConvertToUnicode(CP_UTF8, 0, mszReaderNamesA, *pcchReaderLen, - (WCHAR**) mszReaderNames, 0); - PCSC_AddMemoryBlock(hContext, mszReaderNames); - PCSC_SCardFreeMemory_Internal(hContext, mszReaderNamesA); - } - - return status; + return PCSC_SCardStatus_Internal(hCard, (LPSTR) mszReaderNames, pcchReaderLen, pdwState, + pdwProtocol, pbAtr, pcbAtrLen, TRUE); } WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, From 36c6478627a6032fb8f00216dec38e47fab44bbf Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Thu, 14 Dec 2017 16:21:19 +0100 Subject: [PATCH 15/15] fix client/smartcard: indentation and return value Integrate feedback from pull request review. --- channels/smartcard/client/smartcard_operations.c | 2 +- channels/smartcard/client/smartcard_pack.c | 6 ++---- channels/smartcard/client/smartcard_pack.h | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 8183194b4..91f14a700 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -773,7 +773,7 @@ static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret))) { WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %"PRId32"", status); - goto out_fail; + goto out_fail; } status = ret.ReturnCode; diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index fed0d2a0c..c5d66c18e 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -75,13 +75,12 @@ LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s return SCARD_S_SUCCESS; } -LONG smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s) +void smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s) { Stream_Write_UINT8(s, 1); /* Version (1 byte) */ Stream_Write_UINT8(s, 0x10); /* Endianness (1 byte) */ Stream_Write_UINT16(s, 8); /* CommonHeaderLength (2 bytes) */ Stream_Write_UINT32(s, 0xCCCCCCCC); /* Filler (4 bytes), should be 0xCCCCCCCC */ - return SCARD_S_SUCCESS; } LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s) @@ -116,12 +115,11 @@ LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* return SCARD_S_SUCCESS; } -LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, +void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 objectBufferLength) { Stream_Write_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */ Stream_Write_UINT32(s, 0x00000000); /* Filler (4 bytes), should be 0x00000000 */ - return SCARD_S_SUCCESS; } LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, diff --git a/channels/smartcard/client/smartcard_pack.h b/channels/smartcard/client/smartcard_pack.h index 19c0954c1..f7bc08340 100644 --- a/channels/smartcard/client/smartcard_pack.h +++ b/channels/smartcard/client/smartcard_pack.h @@ -452,10 +452,10 @@ void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_S SCARDHANDLE hCard); LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); -LONG smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); +void smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); -LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, +void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 objectBufferLength); LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s,