diff --git a/channels/rdpdr/client/irp.c b/channels/rdpdr/client/irp.c index 0ba98c726..f6f4603e1 100644 --- a/channels/rdpdr/client/irp.c +++ b/channels/rdpdr/client/irp.c @@ -31,6 +31,8 @@ #include #include +#include + #include "rdpdr_main.h" #include "devman.h" #include "irp.h" @@ -132,11 +134,15 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error) *error = CHANNEL_RC_NO_MEMORY; return NULL; } - Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE); /* Component (2 bytes) */ - Stream_Write_UINT16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION); /* PacketId (2 bytes) */ - Stream_Write_UINT32(irp->output, DeviceId); /* DeviceId (4 bytes) */ - Stream_Write_UINT32(irp->output, irp->CompletionId); /* CompletionId (4 bytes) */ - Stream_Write_UINT32(irp->output, 0); /* IoStatus (4 bytes) */ + + if (!rdpdr_write_iocompletion_header(irp->output, DeviceId, irp->CompletionId, 0)) + { + Stream_Free(irp->output, TRUE); + _aligned_free(irp); + if (error) + *error = CHANNEL_RC_NO_MEMORY; + return NULL; + } irp->Complete = irp_complete; irp->Discard = irp_free; diff --git a/channels/rdpdr/client/rdpdr_capabilities.c b/channels/rdpdr/client/rdpdr_capabilities.c index b8581e864..b505f5dbe 100644 --- a/channels/rdpdr/client/rdpdr_capabilities.c +++ b/channels/rdpdr/client/rdpdr_capabilities.c @@ -51,8 +51,8 @@ static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* s) rdpdr_write_capset_header(s, CAP_GENERAL_TYPE, 44, GENERAL_CAPABILITY_VERSION_02); Stream_Write_UINT32(s, 0); /* osType, ignored on receipt */ Stream_Write_UINT32(s, 0); /* osVersion, unused and must be set to zero */ - Stream_Write_UINT16(s, RDPDR_MAJOR_RDP_VERSION); /* protocolMajorVersion, must be set to 1 */ - Stream_Write_UINT16(s, RDPDR_MINOR_RDP_VERSION_13); /* protocolMinorVersion */ + Stream_Write_UINT16(s, rdpdr->versionMajor); /* protocolMajorVersion, must be set to 1 */ + Stream_Write_UINT16(s, rdpdr->versionMinor); /* protocolMinorVersion */ Stream_Write_UINT32(s, 0x0000FFFF); /* ioCode1 */ Stream_Write_UINT32(s, 0); /* ioCode2, must be set to zero, reserved for future use */ Stream_Write_UINT32(s, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 7b5072d48..82b99749a 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -34,10 +34,13 @@ #include #include +#include + #include #include #include #include +#include #ifdef _WIN32 #include @@ -1362,16 +1365,9 @@ static UINT dummy_irp_response(rdpdrPlugin* rdpdr, wStream* s) Stream_Read_UINT32(s, FileId); /* FileId (4 bytes) */ Stream_Read_UINT32(s, CompletionId); /* CompletionId (4 bytes) */ - Stream_Write_UINT16(output, RDPDR_CTYP_CORE); /* Component (2 bytes) */ - Stream_Write_UINT16(output, PAKID_CORE_DEVICE_IOCOMPLETION); /* PacketId (2 bytes) */ - Stream_Write_UINT32(output, DeviceId); /* DeviceId (4 bytes) */ - Stream_Write_UINT32(output, CompletionId); /* CompletionId (4 bytes) */ - Stream_Write_UINT32(output, (UINT32)STATUS_UNSUCCESSFUL); /* IoStatus (4 bytes) */ - - Stream_Zero(output, 256 - RDPDR_DEVICE_IO_RESPONSE_LENGTH); - // or usage - // Stream_Write_UINT32(output, 0); /* Length */ - // Stream_Write_UINT8(output, 0); /* Padding */ + if (!rdpdr_write_iocompletion_header(output, DeviceId, CompletionId, + (UINT32)STATUS_UNSUCCESSFUL)) + return CHANNEL_RC_NO_MEMORY; return rdpdr_send(rdpdr, output); } @@ -1488,6 +1484,7 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) if (!rdpdr || !s) return CHANNEL_RC_NULL_DATA; + rdpdr_dump_received_packet(s, "rdpdr-channel"); if (Stream_GetRemainingLength(s) >= 4) { Stream_Read_UINT16(s, component); /* Component (2 bytes) */ @@ -1630,9 +1627,10 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s) } else { + const size_t pos = Stream_GetPosition(s); + rdpdr_dump_send_packet(s, "rdpdr-channel"); status = plugin->channelEntryPoints.pVirtualChannelWriteEx( - plugin->InitHandle, plugin->OpenHandle, Stream_Buffer(s), (UINT32)Stream_GetPosition(s), - s); + plugin->InitHandle, plugin->OpenHandle, Stream_Buffer(s), pos, s); } if (status != CHANNEL_RC_OK) diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index f6880fec2..4cd1935ec 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -78,6 +78,7 @@ static UINT rdpdr_seal_send_free_request(RdpdrServerContext* context, wStream* s Stream_Free(s, TRUE); return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } + /** * Function description * diff --git a/channels/rdpdr/server/rdpdr_main.h b/channels/rdpdr/server/rdpdr_main.h index f3f54cc07..c1ec53445 100644 --- a/channels/rdpdr/server/rdpdr_main.h +++ b/channels/rdpdr/server/rdpdr_main.h @@ -57,13 +57,6 @@ struct _RDPDR_HEADER }; typedef struct _RDPDR_HEADER RDPDR_HEADER; -#define RDPDR_VERSION_MAJOR 0x0001 - -#define RDPDR_VERSION_MINOR_RDP50 0x0002 -#define RDPDR_VERSION_MINOR_RDP51 0x0005 -#define RDPDR_VERSION_MINOR_RDP52 0x000A -#define RDPDR_VERSION_MINOR_RDP6X 0x000C - #define RDPDR_CAPABILITY_HEADER_LENGTH 8 struct _RDPDR_CAPABILITY_HEADER diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index 381c00625..d9743e6e6 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -41,6 +41,7 @@ #include #include #include +#include #define TAG CHANNELS_TAG("serial.client") @@ -447,9 +448,8 @@ error_handle: static UINT serial_process_irp(SERIAL_DEVICE* serial, IRP* irp) { UINT error = CHANNEL_RC_OK; - WLog_Print(serial->log, WLOG_DEBUG, - "IRP MajorFunction: 0x%08" PRIX32 " MinorFunction: 0x%08" PRIX32 "\n", - irp->MajorFunction, irp->MinorFunction); + WLog_Print(serial->log, WLOG_DEBUG, "IRP MajorFunction: s, MinorFunction: 0x%08" PRIX32 "\n", + rdpdr_irp_string(irp->MajorFunction), irp->MinorFunction); switch (irp->MajorFunction) { diff --git a/channels/smartcard/client/CMakeLists.txt b/channels/smartcard/client/CMakeLists.txt index 717a7608f..79ebb7168 100644 --- a/channels/smartcard/client/CMakeLists.txt +++ b/channels/smartcard/client/CMakeLists.txt @@ -19,11 +19,8 @@ define_channel_client("smartcard") set(${MODULE_PREFIX}_SRCS smartcard_main.c - smartcard_main.h - smartcard_pack.c - smartcard_pack.h - smartcard_operations.h - smartcard_operations.c) + smartcard_main.h + ) add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "DeviceServiceEntry") diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index d37ede6e4..d97ea7536 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -31,21 +31,27 @@ #include #include +#include +#include +#include +#include #include "smartcard_main.h" #define CAST_FROM_DEVICE(device) cast_device_from(device, __FUNCTION__, __FILE__, __LINE__) -#if defined(WITH_SMARTCARD_EMULATE) -#include -#define str(x) #x -#define wrap(smartcard, fkt, ...) Emulate_##fkt(smartcard->emulation, ##__VA_ARGS__) -#else -#define wrap(smartcard, fkt, ...) fkt(__VA_ARGS__) -#endif +typedef struct +{ + SMARTCARD_OPERATION operation; + IRP* irp; +} scard_irp_queue_element; static SMARTCARD_DEVICE* sSmartcard = NULL; +static void smartcard_context_free(void* pCtx); + +static UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp); + static SMARTCARD_DEVICE* cast_device_from(DEVICE* device, const char* fkt, const char* file, int line) { @@ -74,7 +80,6 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg) HANDLE hEvents[2]; wMessage message; SMARTCARD_DEVICE* smartcard; - SMARTCARD_OPERATION* operation; UINT error = CHANNEL_RC_OK; smartcard = pContext->smartcard; nCount = 0; @@ -102,6 +107,8 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg) if (waitStatus == WAIT_OBJECT_0) { + scard_irp_queue_element* element; + if (!MessageQueue_Peek(pContext->IrpQueue, &message, TRUE)) { WLog_ERR(TAG, "MessageQueue_Peek failed!"); @@ -112,25 +119,32 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg) if (message.id == WMQ_QUIT) break; - operation = (SMARTCARD_OPERATION*)message.wParam; + element = (scard_irp_queue_element*)message.wParam; - if (operation) + if (element) { - if ((status = smartcard_irp_device_control_call(smartcard, operation))) + UINT error; + WINPR_ASSERT(smartcard); + + if ((status = smartcard_irp_device_control_call( + smartcard->callctx, element->irp->output, &element->irp->IoStatus, + &element->operation))) { + smartcard_operation_free(&element->operation, TRUE); WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %" PRIu32 "", status); break; } - if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*)operation->irp)) + if ((error = smartcard_complete_irp(smartcard, element->irp))) { + smartcard_operation_free(&element->operation, TRUE); WLog_ERR(TAG, "Queue_Enqueue failed!"); status = ERROR_INTERNAL_ERROR; break; } - free(operation); + smartcard_operation_free(&element->operation, TRUE); } } } @@ -142,7 +156,7 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg) return error; } -SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext) +static void* smartcard_context_new(void* smartcard, SCARDCONTEXT hContext) { SMARTCARD_CONTEXT* pContext; pContext = (SMARTCARD_CONTEXT*)calloc(1, sizeof(SMARTCARD_CONTEXT)); @@ -185,7 +199,8 @@ void smartcard_context_free(void* pCtx) return; /* cancel blocking calls like SCardGetStatusChange */ - wrap(pContext->smartcard, SCardCancel, pContext->hContext); + WINPR_ASSERT(pContext->smartcard); + smartcard_call_cancel_context(pContext->smartcard->callctx, pContext->hContext); if (pContext->IrpQueue) { @@ -198,77 +213,13 @@ void smartcard_context_free(void* pCtx) } MessageQueue_Free(pContext->IrpQueue); } - wrap(pContext->smartcard, SCardReleaseContext, pContext->hContext); + smartcard_call_release_context(pContext->smartcard->callctx, pContext->hContext); free(pContext); } static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) { - int index; - int keyCount; - ULONG_PTR* pKeys; - SCARDCONTEXT hContext; - SMARTCARD_CONTEXT* pContext; - - /** - * On protocol termination, the following actions are performed: - * For each context in rgSCardContextList, SCardCancel is called causing all - * SCardGetStatusChange calls to be processed. After that, SCardReleaseContext is called on each - * context and the context MUST be removed from rgSCardContextList. - */ - - /** - * Call SCardCancel on existing contexts, unblocking all outstanding SCardGetStatusChange calls. - */ - - ListDictionary_Lock(smartcard->rgSCardContextList); - if (ListDictionary_Count(smartcard->rgSCardContextList) > 0) - { - pKeys = NULL; - keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys); - - for (index = 0; index < keyCount; index++) - { - pContext = (SMARTCARD_CONTEXT*)ListDictionary_GetItemValue( - smartcard->rgSCardContextList, (void*)pKeys[index]); - - if (!pContext) - continue; - - hContext = pContext->hContext; - - if (wrap(smartcard, SCardIsValidContext, hContext) == SCARD_S_SUCCESS) - { - wrap(smartcard, SCardCancel, hContext); - } - } - - free(pKeys); - } - ListDictionary_Unlock(smartcard->rgSCardContextList); - - /* Put thread to sleep so that PC/SC can process the cancel requests. This fixes a race - * condition that sometimes caused the pc/sc daemon to crash on MacOS (_xpc_api_misuse) */ - SleepEx(100, FALSE); - - /** - * Call SCardReleaseContext on remaining contexts and remove them from rgSCardContextList. - */ - - ListDictionary_Lock(smartcard->rgSCardContextList); - if (ListDictionary_Count(smartcard->rgSCardContextList) > 0) - { - pKeys = NULL; - keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys); - - for (index = 0; index < keyCount; index++) - { - ListDictionary_SetItemValue(smartcard->rgSCardContextList, (void*)pKeys[index], NULL); - } - - free(pKeys); - } - ListDictionary_Unlock(smartcard->rgSCardContextList); + smartcard_call_cancel_all_context(smartcard->callctx); } static UINT smartcard_free_(SMARTCARD_DEVICE* smartcard) @@ -283,17 +234,10 @@ static UINT smartcard_free_(SMARTCARD_DEVICE* smartcard) } Stream_Free(smartcard->device.data, TRUE); - LinkedList_Free(smartcard->names); - ListDictionary_Free(smartcard->rgSCardContextList); ListDictionary_Free(smartcard->rgOutstandingMessages); - Queue_Free(smartcard->CompletedIrpQueue); - if (smartcard->StartedEvent) - wrap(smartcard, SCardReleaseStartedEvent); + smartcard_call_context_free(smartcard->callctx); -#if defined(WITH_SMARTCARD_EMULATE) - Emulate_Free(smartcard->emulation); -#endif free(smartcard); return CHANNEL_RC_OK; } @@ -360,11 +304,17 @@ static UINT smartcard_init(DEVICE* device) * * @return 0 on success, otherwise a Win32 error code */ -static UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) +UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) { void* key; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(irp); + key = (void*)(size_t)irp->CompletionId; ListDictionary_Remove(smartcard->rgOutstandingMessages, key); + + WINPR_ASSERT(irp->Complete); return irp->Complete(irp); } @@ -384,7 +334,6 @@ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) LONG status; BOOL asyncIrp = FALSE; SMARTCARD_CONTEXT* pContext = NULL; - SMARTCARD_OPERATION* operation = NULL; key = (void*)(size_t)irp->CompletionId; if (!ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp)) @@ -395,35 +344,35 @@ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) { - operation = (SMARTCARD_OPERATION*)calloc(1, sizeof(SMARTCARD_OPERATION)); + scard_irp_queue_element* element = calloc(1, sizeof(scard_irp_queue_element)); + if (!element) + return ERROR_OUTOFMEMORY; - if (!operation) - { - WLog_ERR(TAG, "calloc failed!"); - return CHANNEL_RC_NO_MEMORY; - } + element->irp = irp; + element->operation.completionID = irp->CompletionId; - operation->irp = irp; - status = smartcard_irp_device_control_decode(smartcard, operation); + status = smartcard_irp_device_control_decode(irp->input, irp->CompletionId, irp->FileId, + &element->operation); if (status != SCARD_S_SUCCESS) { + UINT error; + + smartcard_operation_free(&element->operation, TRUE); irp->IoStatus = (UINT32)STATUS_UNSUCCESSFUL; - if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*)irp)) + if ((error = smartcard_complete_irp(smartcard, irp))) { - free(operation); WLog_ERR(TAG, "Queue_Enqueue failed!"); - return ERROR_INTERNAL_ERROR; + return error; } - free(operation); return CHANNEL_RC_OK; } asyncIrp = TRUE; - switch (operation->ioControlCode) + switch (element->operation.ioControlCode) { case SCARD_IOCTL_ESTABLISHCONTEXT: case SCARD_IOCTL_RELEASECONTEXT: @@ -480,37 +429,40 @@ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) break; } - pContext = - ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*)operation->hContext); + pContext = smartcard_call_get_context(smartcard->callctx, element->operation.hContext); if (!pContext) asyncIrp = FALSE; if (!asyncIrp) { - if ((status = smartcard_irp_device_control_call(smartcard, operation))) + UINT error; + + status = + smartcard_irp_device_control_call(smartcard->callctx, element->irp->output, + &element->irp->IoStatus, &element->operation); + smartcard_operation_free(&element->operation, TRUE); + + if (status) { - free(operation); WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %" PRId32 "!", status); return (UINT32)status; } - if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*)irp)) + if ((error = smartcard_complete_irp(smartcard, irp))) { - free(operation); WLog_ERR(TAG, "Queue_Enqueue failed!"); - return ERROR_INTERNAL_ERROR; + return error; } - - free(operation); } else { if (pContext) { - if (!MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*)operation, NULL)) + if (!MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*)element, NULL)) { + smartcard_operation_free(&element->operation, TRUE); WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } @@ -519,16 +471,15 @@ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) } else { - WLog_ERR(TAG, - "Unexpected SmartCard IRP: MajorFunction 0x%08" PRIX32 - " MinorFunction: 0x%08" PRIX32 "", - irp->MajorFunction, irp->MinorFunction); + UINT status; + WLog_ERR(TAG, "Unexpected SmartCard IRP: MajorFunction %s, MinorFunction: 0x%08" PRIX32 "", + rdpdr_irp_string(irp->MajorFunction), irp->MinorFunction); irp->IoStatus = (UINT32)STATUS_NOT_SUPPORTED; - if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*)irp)) + if ((status = smartcard_complete_irp(smartcard, irp))) { WLog_ERR(TAG, "Queue_Enqueue failed!"); - return ERROR_INTERNAL_ERROR; + return status; } } @@ -540,7 +491,7 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg) IRP* irp; DWORD nCount; DWORD status; - HANDLE hEvents[2]; + HANDLE hEvents[1]; wMessage message; UINT error = CHANNEL_RC_OK; SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(arg); @@ -550,7 +501,6 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg) nCount = 0; hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue); - hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue); while (1) { @@ -563,15 +513,6 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg) break; } - status = WaitForSingleObject(MessageQueue_Event(smartcard->IrpQueue), 0); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error); - break; - } - if (status == WAIT_OBJECT_0) { if (!MessageQueue_Peek(smartcard->IrpQueue, &message, TRUE)) @@ -582,52 +523,7 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg) } if (message.id == WMQ_QUIT) - { - while (1) - { - status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error); - goto out; - } - - if (status == WAIT_TIMEOUT) - break; - - irp = (IRP*)Queue_Dequeue(smartcard->CompletedIrpQueue); - - if (irp) - { - if (irp->thread) - { - status = WaitForSingleObject(irp->thread, INFINITE); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", - error); - goto out; - } - - CloseHandle(irp->thread); - irp->thread = NULL; - } - - if ((error = smartcard_complete_irp(smartcard, irp))) - { - WLog_ERR(TAG, "smartcard_complete_irp failed with error %" PRIu32 "!", - error); - goto out; - } - } - } - break; - } irp = (IRP*)message.wParam; @@ -640,50 +536,6 @@ static DWORD WINAPI smartcard_thread_func(LPVOID arg) } } } - - status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error); - break; - } - - if (status == WAIT_OBJECT_0) - { - irp = (IRP*)Queue_Dequeue(smartcard->CompletedIrpQueue); - - if (irp) - { - if (irp->thread) - { - status = WaitForSingleObject(irp->thread, INFINITE); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error); - break; - } - - CloseHandle(irp->thread); - irp->thread = NULL; - } - - if ((error = smartcard_complete_irp(smartcard, irp))) - { - if (error == CHANNEL_RC_NOT_CONNECTED) - { - error = CHANNEL_RC_OK; - goto out; - } - - WLog_ERR(TAG, "smartcard_complete_irp failed with error %" PRIu32 "!", error); - goto out; - } - } - } } out: @@ -733,7 +585,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) if (!sSmartcard) { - wObject* obj; smartcard = (SMARTCARD_DEVICE*)calloc(1, sizeof(SMARTCARD_DEVICE)); if (!smartcard) @@ -747,12 +598,11 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) smartcard->device.IRPRequest = smartcard_irp_request; smartcard->device.Init = smartcard_init; smartcard->device.Free = smartcard_free; - smartcard->names = LinkedList_New(); smartcard->rdpcontext = pEntryPoints->rdpcontext; length = strlen(smartcard->device.name); smartcard->device.data = Stream_New(NULL, length + 1); - if (!smartcard->device.data || !smartcard->names) + if (!smartcard->device.data) { WLog_ERR(TAG, "Stream_New failed!"); goto fail; @@ -767,24 +617,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) goto fail; } - smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1); - - if (!smartcard->CompletedIrpQueue) - { - WLog_ERR(TAG, "Queue_New failed!"); - goto fail; - } - - smartcard->rgSCardContextList = ListDictionary_New(TRUE); - - if (!smartcard->rgSCardContextList) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - goto fail; - } - - obj = ListDictionary_ValueObject(smartcard->rgSCardContextList); - obj->fnObjectFree = smartcard_context_free; smartcard->rgOutstandingMessages = ListDictionary_New(TRUE); if (!smartcard->rgOutstandingMessages) @@ -793,11 +625,14 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) goto fail; } -#if defined(WITH_SMARTCARD_EMULATE) - smartcard->emulation = Emulate_New(smartcard->rdpcontext->settings); - if (!smartcard->emulation) + smartcard->callctx = smartcard_call_context_new(smartcard->rdpcontext->settings); + if (!smartcard->callctx) goto fail; -#endif + + if (!smarcard_call_set_callbacks(smartcard->callctx, smartcard, smartcard_context_new, + smartcard_context_free)) + goto fail; + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, &smartcard->device))) { WLog_ERR(TAG, "RegisterDevice failed!"); @@ -820,7 +655,9 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) smartcard = sSmartcard; if (pEntryPoints->device->Name) - LinkedList_AddLast(smartcard->names, pEntryPoints->device->Name); + { + smartcard_call_context_add(smartcard->callctx, pEntryPoints->device->Name); + } sSmartcard = smartcard; return CHANNEL_RC_OK; diff --git a/channels/smartcard/client/smartcard_main.h b/channels/smartcard/client/smartcard_main.h index c6476cf5b..559813735 100644 --- a/channels/smartcard/client/smartcard_main.h +++ b/channels/smartcard/client/smartcard_main.h @@ -32,7 +32,8 @@ #include #include -#include "smartcard_operations.h" +#include +#include #if defined(WITH_SMARTCARD_EMULATE) #include @@ -56,25 +57,10 @@ struct _SMARTCARD_DEVICE DEVICE device; HANDLE thread; - HANDLE StartedEvent; + scard_call_context* callctx; wMessageQueue* IrpQueue; - wQueue* CompletedIrpQueue; - wListDictionary* rgSCardContextList; wListDictionary* rgOutstandingMessages; rdpContext* rdpcontext; - wLinkedList* names; -#if defined(WITH_SMARTCARD_EMULATE) - SmartcardEmulationContext* emulation; -#endif }; -SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext); -void smartcard_context_free(void* pContext); - -LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation); -LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation); - -#include "smartcard_pack.h" - #endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H */ diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c deleted file mode 100644 index 446715de8..000000000 --- a/channels/smartcard/client/smartcard_operations.c +++ /dev/null @@ -1,2712 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Smartcard Device Service Virtual Channel - * - * Copyright (C) Alexi Volkov 2006 - * Copyright 2011 O.S. Systems Software Ltda. - * Copyright 2011 Anthony Tong - * Copyright 2015 Thincast Technologies GmbH - * Copyright 2015 DI (FH) Martin Haimberger - * Copyright 2017 Armin Novak - * Copyright 2017 Thincast Technologies GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include -#include -#include - -#include -#include - -#include "smartcard_operations.h" -#include "smartcard_main.h" - -#if defined(WITH_SMARTCARD_EMULATE) -#include - -#define str(x) #x -#define wrap(smartcard, fkt, ...) Emulate_##fkt(smartcard->emulation, ##__VA_ARGS__) -#else -#define wrap(smartcard, fkt, ...) fkt(__VA_ARGS__) -#endif - -static LONG smartcard_call_to_operation_handle(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - if (!smartcard || !operation) - return SCARD_E_INVALID_HANDLE; - operation->hContext = - smartcard_scard_context_native_from_redir(smartcard, &(operation->call.handles.hContext)); - operation->hCard = - smartcard_scard_handle_native_from_redir(smartcard, &(operation->call.handles.hCard)); - - return SCARD_S_SUCCESS; -} - -static LONG log_status_error(const char* tag, const char* what, LONG status) -{ - if (status != SCARD_S_SUCCESS) - { - DWORD level = WLOG_ERROR; - switch (status) - { - case SCARD_E_TIMEOUT: - level = WLOG_DEBUG; - break; - case SCARD_E_NO_READERS_AVAILABLE: - level = WLOG_INFO; - break; - default: - break; - } - WLog_Print(WLog_Get(tag), level, "%s failed with error %s [%" PRId32 "]", what, - SCardGetErrorString(status), status); - } - return status; -} - -static const char* smartcard_get_ioctl_string(UINT32 ioControlCode, BOOL funcName) -{ - switch (ioControlCode) - { - case SCARD_IOCTL_ESTABLISHCONTEXT: - return funcName ? "SCardEstablishContext" : "SCARD_IOCTL_ESTABLISHCONTEXT"; - - case SCARD_IOCTL_RELEASECONTEXT: - return funcName ? "SCardReleaseContext" : "SCARD_IOCTL_RELEASECONTEXT"; - - case SCARD_IOCTL_ISVALIDCONTEXT: - return funcName ? "SCardIsValidContext" : "SCARD_IOCTL_ISVALIDCONTEXT"; - - case SCARD_IOCTL_LISTREADERGROUPSA: - return funcName ? "SCardListReaderGroupsA" : "SCARD_IOCTL_LISTREADERGROUPSA"; - - case SCARD_IOCTL_LISTREADERGROUPSW: - return funcName ? "SCardListReaderGroupsW" : "SCARD_IOCTL_LISTREADERGROUPSW"; - - case SCARD_IOCTL_LISTREADERSA: - return funcName ? "SCardListReadersA" : "SCARD_IOCTL_LISTREADERSA"; - - case SCARD_IOCTL_LISTREADERSW: - return funcName ? "SCardListReadersW" : "SCARD_IOCTL_LISTREADERSW"; - - case SCARD_IOCTL_INTRODUCEREADERGROUPA: - return funcName ? "SCardIntroduceReaderGroupA" : "SCARD_IOCTL_INTRODUCEREADERGROUPA"; - - case SCARD_IOCTL_INTRODUCEREADERGROUPW: - return funcName ? "SCardIntroduceReaderGroupW" : "SCARD_IOCTL_INTRODUCEREADERGROUPW"; - - case SCARD_IOCTL_FORGETREADERGROUPA: - return funcName ? "SCardForgetReaderGroupA" : "SCARD_IOCTL_FORGETREADERGROUPA"; - - case SCARD_IOCTL_FORGETREADERGROUPW: - return funcName ? "SCardForgetReaderGroupW" : "SCARD_IOCTL_FORGETREADERGROUPW"; - - case SCARD_IOCTL_INTRODUCEREADERA: - return funcName ? "SCardIntroduceReaderA" : "SCARD_IOCTL_INTRODUCEREADERA"; - - case SCARD_IOCTL_INTRODUCEREADERW: - return funcName ? "SCardIntroduceReaderW" : "SCARD_IOCTL_INTRODUCEREADERW"; - - case SCARD_IOCTL_FORGETREADERA: - return funcName ? "SCardForgetReaderA" : "SCARD_IOCTL_FORGETREADERA"; - - case SCARD_IOCTL_FORGETREADERW: - return funcName ? "SCardForgetReaderW" : "SCARD_IOCTL_FORGETREADERW"; - - case SCARD_IOCTL_ADDREADERTOGROUPA: - return funcName ? "SCardAddReaderToGroupA" : "SCARD_IOCTL_ADDREADERTOGROUPA"; - - case SCARD_IOCTL_ADDREADERTOGROUPW: - return funcName ? "SCardAddReaderToGroupW" : "SCARD_IOCTL_ADDREADERTOGROUPW"; - - case SCARD_IOCTL_REMOVEREADERFROMGROUPA: - return funcName ? "SCardRemoveReaderFromGroupA" : "SCARD_IOCTL_REMOVEREADERFROMGROUPA"; - - case SCARD_IOCTL_REMOVEREADERFROMGROUPW: - return funcName ? "SCardRemoveReaderFromGroupW" : "SCARD_IOCTL_REMOVEREADERFROMGROUPW"; - - case SCARD_IOCTL_LOCATECARDSA: - return funcName ? "SCardLocateCardsA" : "SCARD_IOCTL_LOCATECARDSA"; - - case SCARD_IOCTL_LOCATECARDSW: - return funcName ? "SCardLocateCardsW" : "SCARD_IOCTL_LOCATECARDSW"; - - case SCARD_IOCTL_GETSTATUSCHANGEA: - return funcName ? "SCardGetStatusChangeA" : "SCARD_IOCTL_GETSTATUSCHANGEA"; - - case SCARD_IOCTL_GETSTATUSCHANGEW: - return funcName ? "SCardGetStatusChangeW" : "SCARD_IOCTL_GETSTATUSCHANGEW"; - - case SCARD_IOCTL_CANCEL: - return funcName ? "SCardCancel" : "SCARD_IOCTL_CANCEL"; - - case SCARD_IOCTL_CONNECTA: - return funcName ? "SCardConnectA" : "SCARD_IOCTL_CONNECTA"; - - case SCARD_IOCTL_CONNECTW: - return funcName ? "SCardConnectW" : "SCARD_IOCTL_CONNECTW"; - - case SCARD_IOCTL_RECONNECT: - return funcName ? "SCardReconnect" : "SCARD_IOCTL_RECONNECT"; - - case SCARD_IOCTL_DISCONNECT: - return funcName ? "SCardDisconnect" : "SCARD_IOCTL_DISCONNECT"; - - case SCARD_IOCTL_BEGINTRANSACTION: - return funcName ? "SCardBeginTransaction" : "SCARD_IOCTL_BEGINTRANSACTION"; - - case SCARD_IOCTL_ENDTRANSACTION: - return funcName ? "SCardEndTransaction" : "SCARD_IOCTL_ENDTRANSACTION"; - - case SCARD_IOCTL_STATE: - return funcName ? "SCardState" : "SCARD_IOCTL_STATE"; - - case SCARD_IOCTL_STATUSA: - return funcName ? "SCardStatusA" : "SCARD_IOCTL_STATUSA"; - - case SCARD_IOCTL_STATUSW: - return funcName ? "SCardStatusW" : "SCARD_IOCTL_STATUSW"; - - case SCARD_IOCTL_TRANSMIT: - return funcName ? "SCardTransmit" : "SCARD_IOCTL_TRANSMIT"; - - case SCARD_IOCTL_CONTROL: - return funcName ? "SCardControl" : "SCARD_IOCTL_CONTROL"; - - case SCARD_IOCTL_GETATTRIB: - return funcName ? "SCardGetAttrib" : "SCARD_IOCTL_GETATTRIB"; - - case SCARD_IOCTL_SETATTRIB: - return funcName ? "SCardSetAttrib" : "SCARD_IOCTL_SETATTRIB"; - - case SCARD_IOCTL_ACCESSSTARTEDEVENT: - return funcName ? "SCardAccessStartedEvent" : "SCARD_IOCTL_ACCESSSTARTEDEVENT"; - - case SCARD_IOCTL_LOCATECARDSBYATRA: - return funcName ? "SCardLocateCardsByATRA" : "SCARD_IOCTL_LOCATECARDSBYATRA"; - - case SCARD_IOCTL_LOCATECARDSBYATRW: - return funcName ? "SCardLocateCardsByATRB" : "SCARD_IOCTL_LOCATECARDSBYATRW"; - - case SCARD_IOCTL_READCACHEA: - return funcName ? "SCardReadCacheA" : "SCARD_IOCTL_READCACHEA"; - - case SCARD_IOCTL_READCACHEW: - return funcName ? "SCardReadCacheW" : "SCARD_IOCTL_READCACHEW"; - - case SCARD_IOCTL_WRITECACHEA: - return funcName ? "SCardWriteCacheA" : "SCARD_IOCTL_WRITECACHEA"; - - case SCARD_IOCTL_WRITECACHEW: - return funcName ? "SCardWriteCacheW" : "SCARD_IOCTL_WRITECACHEW"; - - case SCARD_IOCTL_GETTRANSMITCOUNT: - return funcName ? "SCardGetTransmitCount" : "SCARD_IOCTL_GETTRANSMITCOUNT"; - - case SCARD_IOCTL_RELEASETARTEDEVENT: - return funcName ? "SCardReleaseStartedEvent" : "SCARD_IOCTL_RELEASETARTEDEVENT"; - - case SCARD_IOCTL_GETREADERICON: - return funcName ? "SCardGetReaderIcon" : "SCARD_IOCTL_GETREADERICON"; - - case SCARD_IOCTL_GETDEVICETYPEID: - return funcName ? "SCardGetDeviceTypeId" : "SCARD_IOCTL_GETDEVICETYPEID"; - - default: - return funcName ? "SCardUnknown" : "SCARD_IOCTL_UNKNOWN"; - } -} - -static LONG smartcard_EstablishContext_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - - irp = operation->irp; - status = smartcard_unpack_establish_context_call(smartcard, irp->input, - &operation->call.establishContext); - if (status != SCARD_S_SUCCESS) - { - return log_status_error(TAG, "smartcard_unpack_establish_context_call", status); - } - - return SCARD_S_SUCCESS; -} - -static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - SCARDCONTEXT hContext = { 0 }; - EstablishContext_Return ret = { 0 }; - IRP* irp = operation->irp; - EstablishContext_Call* call = &operation->call.establishContext; - status = ret.ReturnCode = - wrap(smartcard, SCardEstablishContext, call->dwScope, NULL, NULL, &hContext); - - if (ret.ReturnCode == SCARD_S_SUCCESS) - { - SMARTCARD_CONTEXT* pContext; - void* key = (void*)(size_t)hContext; - // TODO: handle return values - pContext = smartcard_context_new(smartcard, hContext); - - if (!pContext) - { - WLog_ERR(TAG, "smartcard_context_new failed!"); - return STATUS_NO_MEMORY; - } - - if (!ListDictionary_Add(smartcard->rgSCardContextList, key, (void*)pContext)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return STATUS_INTERNAL_ERROR; - } - } - else - { - return log_status_error(TAG, "SCardEstablishContext", status); - } - - smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext); - - status = smartcard_pack_establish_context_return(smartcard, irp->output, &ret); - if (status != SCARD_S_SUCCESS) - { - return log_status_error(TAG, "smartcard_pack_establish_context_return", status); - } - - return ret.ReturnCode; -} - -static LONG smartcard_ReleaseContext_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - - irp = operation->irp; - status = smartcard_unpack_context_call(smartcard, irp->input, &operation->call.context, - "ReleaseContext"); - if (status != SCARD_S_SUCCESS) - log_status_error(TAG, "smartcard_unpack_context_call", status); - - return status; -} - -static LONG smartcard_ReleaseContext_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ret.ReturnCode = wrap(smartcard, SCardReleaseContext, operation->hContext); - - if (ret.ReturnCode == SCARD_S_SUCCESS) - { - SMARTCARD_CONTEXT* pContext; - void* key = (void*)(size_t)operation->hContext; - pContext = (SMARTCARD_CONTEXT*)ListDictionary_Remove(smartcard->rgSCardContextList, key); - smartcard_context_free(pContext); - } - else - { - return log_status_error(TAG, "SCardReleaseContext", ret.ReturnCode); - } - - smartcard_trace_long_return(smartcard, &ret, "ReleaseContext"); - return ret.ReturnCode; -} - -static LONG smartcard_IsValidContext_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - - irp = operation->irp; - status = smartcard_unpack_context_call(smartcard, irp->input, &operation->call.context, - "IsValidContext"); - - return status; -} - -static LONG smartcard_IsValidContext_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - - ret.ReturnCode = wrap(smartcard, SCardIsValidContext, operation->hContext); - smartcard_trace_long_return(smartcard, &ret, "IsValidContext"); - return ret.ReturnCode; -} - -static LONG smartcard_ListReaderGroupsA_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_list_reader_groups_call(smartcard, irp->input, - &operation->call.listReaderGroups, FALSE); - - return status; -} - -static LONG smartcard_ListReaderGroupsA_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - ListReaderGroups_Return ret = { 0 }; - LPSTR mszGroups = NULL; - DWORD cchGroups = 0; - IRP* irp = operation->irp; - cchGroups = SCARD_AUTOALLOCATE; - ret.ReturnCode = - wrap(smartcard, SCardListReaderGroupsA, operation->hContext, (LPSTR)&mszGroups, &cchGroups); - ret.msz = (BYTE*)mszGroups; - ret.cBytes = cchGroups; - - status = smartcard_pack_list_reader_groups_return(smartcard, irp->output, &ret, FALSE); - - if (status != SCARD_S_SUCCESS) - return status; - - if (mszGroups) - wrap(smartcard, SCardFreeMemory, operation->hContext, mszGroups); - - return ret.ReturnCode; -} - -static LONG smartcard_ListReaderGroupsW_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_list_reader_groups_call(smartcard, irp->input, - &operation->call.listReaderGroups, TRUE); - - return status; -} - -static LONG smartcard_ListReaderGroupsW_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - ListReaderGroups_Return ret = { 0 }; - LPWSTR mszGroups = NULL; - DWORD cchGroups = 0; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - - irp = operation->irp; - cchGroups = SCARD_AUTOALLOCATE; - status = ret.ReturnCode = wrap(smartcard, SCardListReaderGroupsW, operation->hContext, - (LPWSTR)&mszGroups, &cchGroups); - ret.msz = (BYTE*)mszGroups; - ret.cBytes = cchGroups * sizeof(WCHAR); - - if (status != SCARD_S_SUCCESS) - return status; - - status = smartcard_pack_list_reader_groups_return(smartcard, irp->output, &ret, TRUE); - - if (status != SCARD_S_SUCCESS) - return status; - - if (mszGroups) - wrap(smartcard, SCardFreeMemory, operation->hContext, mszGroups); - - return ret.ReturnCode; -} - -static BOOL filter_match(wLinkedList* list, LPCSTR reader, size_t readerLen) -{ - if (readerLen < 1) - return FALSE; - - LinkedList_Enumerator_Reset(list); - - while (LinkedList_Enumerator_MoveNext(list)) - { - const char* filter = LinkedList_Enumerator_Current(list); - - if (filter) - { - if (strstr(reader, filter) != NULL) - return TRUE; - } - } - - return FALSE; -} - -static DWORD filter_device_by_name_a(wLinkedList* list, LPSTR* mszReaders, DWORD cchReaders) -{ - size_t rpos = 0, wpos = 0; - - if (*mszReaders == NULL || LinkedList_Count(list) < 1) - return cchReaders; - - do - { - LPCSTR rreader = &(*mszReaders)[rpos]; - LPSTR wreader = &(*mszReaders)[wpos]; - size_t readerLen = strnlen(rreader, cchReaders - rpos); - - rpos += readerLen + 1; - - if (filter_match(list, rreader, readerLen)) - { - if (rreader != wreader) - memmove(wreader, rreader, readerLen + 1); - - wpos += readerLen + 1; - } - } while (rpos < cchReaders); - - /* this string must be double 0 terminated */ - if (rpos != wpos) - { - if (wpos >= cchReaders) - return 0; - - (*mszReaders)[wpos++] = '\0'; - } - - return (DWORD)wpos; -} - -static DWORD filter_device_by_name_w(wLinkedList* list, LPWSTR* mszReaders, DWORD cchReaders) -{ - int res; - DWORD rc; - LPSTR readers = NULL; - - if (LinkedList_Count(list) < 1) - return cchReaders; - - res = ConvertFromUnicode(CP_UTF8, 0, *mszReaders, (int)cchReaders, &readers, 0, NULL, NULL); - - /* When res==0, readers may have been set to NULL by ConvertFromUnicode */ - if ((res < 0) || ((DWORD)res != cchReaders) || (readers == 0)) - { - free(readers); - return 0; - } - - free(*mszReaders); - *mszReaders = NULL; - rc = filter_device_by_name_a(list, &readers, cchReaders); - res = ConvertToUnicode(CP_UTF8, 0, readers, (int)rc, mszReaders, 0); - - if ((res < 0) || ((DWORD)res != rc)) - rc = 0; - - free(readers); - return rc; -} - -static LONG smartcard_ListReadersA_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_list_readers_call(smartcard, irp->input, &operation->call.listReaders, - FALSE); - - return status; -} - -static LONG smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - ListReaders_Return ret = { 0 }; - LPSTR mszReaders = NULL; - DWORD cchReaders = 0; - IRP* irp = operation->irp; - ListReaders_Call* call = &operation->call.listReaders; - cchReaders = SCARD_AUTOALLOCATE; - status = ret.ReturnCode = wrap(smartcard, SCardListReadersA, operation->hContext, - (LPCSTR)call->mszGroups, (LPSTR)&mszReaders, &cchReaders); - - if (call->mszGroups) - { - free(call->mszGroups); - call->mszGroups = NULL; - } - - if (status != SCARD_S_SUCCESS) - { - return log_status_error(TAG, "SCardListReadersA", status); - } - - cchReaders = filter_device_by_name_a(smartcard->names, &mszReaders, cchReaders); - ret.msz = (BYTE*)mszReaders; - ret.cBytes = cchReaders; - - status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret, FALSE); - if (status != SCARD_S_SUCCESS) - { - return log_status_error(TAG, "smartcard_pack_list_readers_return", status); - } - - if (mszReaders) - wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaders); - - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_ListReadersW_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_list_readers_call(smartcard, irp->input, &operation->call.listReaders, - TRUE); - - return status; -} - -static LONG smartcard_context_and_two_strings_a_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_context_and_two_strings_a_call(smartcard, irp->input, - &operation->call.contextAndTwoStringA); - - return status; -} - -static LONG smartcard_context_and_two_strings_w_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_context_and_two_strings_w_call(smartcard, irp->input, - &operation->call.contextAndTwoStringW); - - return status; -} - -static LONG smartcard_context_and_string_a_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_context_and_string_a_call(smartcard, irp->input, - &operation->call.contextAndStringA); - - return status; -} - -static LONG smartcard_context_and_string_w_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_context_and_string_w_call(smartcard, irp->input, - &operation->call.contextAndStringW); - - return status; -} - -static LONG smartcard_LocateCardsA_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = - smartcard_unpack_locate_cards_a_call(smartcard, irp->input, &operation->call.locateCardsA); - - return status; -} - -static LONG smartcard_LocateCardsW_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = - smartcard_unpack_locate_cards_w_call(smartcard, irp->input, &operation->call.locateCardsW); - - return status; -} - -static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - ListReaders_Return ret = { 0 }; - DWORD cchReaders = 0; - IRP* irp = operation->irp; - ListReaders_Call* call = &operation->call.listReaders; - union - { - const BYTE* bp; - const char* sz; - const WCHAR* wz; - } string; - union - { - WCHAR** ppw; - WCHAR* pw; - CHAR* pc; - BYTE* pb; - } mszReaders; - - string.bp = call->mszGroups; - cchReaders = SCARD_AUTOALLOCATE; - status = ret.ReturnCode = wrap(smartcard, SCardListReadersW, operation->hContext, string.wz, - (LPWSTR)&mszReaders.pw, &cchReaders); - - if (call->mszGroups) - { - free(call->mszGroups); - call->mszGroups = NULL; - } - - if (status != SCARD_S_SUCCESS) - return log_status_error(TAG, "SCardListReadersW", status); - - cchReaders = filter_device_by_name_w(smartcard->names, &mszReaders.pw, cchReaders); - ret.msz = mszReaders.pb; - ret.cBytes = cchReaders; - status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret, TRUE); - - if (mszReaders.pb) - wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaders.pb); - - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_IntroduceReaderGroupA_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndStringA_Call* call = &operation->call.contextAndStringA; - ret.ReturnCode = wrap(smartcard, SCardIntroduceReaderGroupA, operation->hContext, call->sz); - log_status_error(TAG, "SCardIntroduceReaderGroupA", ret.ReturnCode); - if (call->sz) - { - free(call->sz); - call->sz = NULL; - } - - smartcard_trace_long_return(smartcard, &ret, "IntroduceReaderGroupA"); - return ret.ReturnCode; -} - -static LONG smartcard_IntroduceReaderGroupW_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndStringW_Call* call = &operation->call.contextAndStringW; - ret.ReturnCode = wrap(smartcard, SCardIntroduceReaderGroupW, operation->hContext, call->sz); - log_status_error(TAG, "SCardIntroduceReaderGroupW", ret.ReturnCode); - if (call->sz) - { - free(call->sz); - call->sz = NULL; - } - - smartcard_trace_long_return(smartcard, &ret, "IntroduceReaderGroupW"); - return ret.ReturnCode; -} - -static LONG smartcard_IntroduceReaderA_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndTwoStringA_Call* call = &operation->call.contextAndTwoStringA; - ret.ReturnCode = - wrap(smartcard, SCardIntroduceReaderA, operation->hContext, call->sz1, call->sz2); - log_status_error(TAG, "SCardIntroduceReaderA", ret.ReturnCode); - free(call->sz1); - call->sz1 = NULL; - free(call->sz2); - call->sz2 = NULL; - - smartcard_trace_long_return(smartcard, &ret, "IntroduceReaderA"); - return ret.ReturnCode; -} - -static LONG smartcard_IntroduceReaderW_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndTwoStringW_Call* call = &operation->call.contextAndTwoStringW; - ret.ReturnCode = - wrap(smartcard, SCardIntroduceReaderW, operation->hContext, call->sz1, call->sz2); - log_status_error(TAG, "SCardIntroduceReaderW", ret.ReturnCode); - free(call->sz1); - call->sz1 = NULL; - free(call->sz2); - call->sz2 = NULL; - - smartcard_trace_long_return(smartcard, &ret, "IntroduceReaderW"); - return ret.ReturnCode; -} - -static LONG smartcard_ForgetReaderA_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndStringA_Call* call = &operation->call.contextAndStringA; - ret.ReturnCode = wrap(smartcard, SCardForgetReaderA, operation->hContext, call->sz); - log_status_error(TAG, "SCardForgetReaderA", ret.ReturnCode); - if (call->sz) - { - free(call->sz); - call->sz = NULL; - } - - smartcard_trace_long_return(smartcard, &ret, "SCardForgetReaderA"); - return ret.ReturnCode; -} - -static LONG smartcard_ForgetReaderW_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndStringW_Call* call = &operation->call.contextAndStringW; - ret.ReturnCode = wrap(smartcard, SCardForgetReaderW, operation->hContext, call->sz); - log_status_error(TAG, "SCardForgetReaderW", ret.ReturnCode); - if (call->sz) - { - free(call->sz); - call->sz = NULL; - } - - smartcard_trace_long_return(smartcard, &ret, "SCardForgetReaderW"); - return ret.ReturnCode; -} - -static LONG smartcard_AddReaderToGroupA_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndTwoStringA_Call* call = &operation->call.contextAndTwoStringA; - ret.ReturnCode = - wrap(smartcard, SCardAddReaderToGroupA, operation->hContext, call->sz1, call->sz2); - log_status_error(TAG, "SCardAddReaderToGroupA", ret.ReturnCode); - free(call->sz1); - call->sz1 = NULL; - free(call->sz2); - call->sz2 = NULL; - - smartcard_trace_long_return(smartcard, &ret, "SCardAddReaderToGroupA"); - return ret.ReturnCode; -} - -static LONG smartcard_AddReaderToGroupW_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndTwoStringW_Call* call = &operation->call.contextAndTwoStringW; - ret.ReturnCode = - wrap(smartcard, SCardAddReaderToGroupW, operation->hContext, call->sz1, call->sz2); - log_status_error(TAG, "SCardAddReaderToGroupW", ret.ReturnCode); - free(call->sz1); - call->sz1 = NULL; - free(call->sz2); - call->sz2 = NULL; - - smartcard_trace_long_return(smartcard, &ret, "SCardAddReaderToGroupA"); - return ret.ReturnCode; -} - -static LONG smartcard_RemoveReaderFromGroupA_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndTwoStringA_Call* call = &operation->call.contextAndTwoStringA; - ret.ReturnCode = - wrap(smartcard, SCardRemoveReaderFromGroupA, operation->hContext, call->sz1, call->sz2); - log_status_error(TAG, "SCardRemoveReaderFromGroupA", ret.ReturnCode); - free(call->sz1); - call->sz1 = NULL; - free(call->sz2); - call->sz2 = NULL; - - smartcard_trace_long_return(smartcard, &ret, "SCardRemoveReaderFromGroupA"); - return ret.ReturnCode; -} - -static LONG smartcard_RemoveReaderFromGroupW_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - ContextAndTwoStringW_Call* call = &operation->call.contextAndTwoStringW; - ret.ReturnCode = - wrap(smartcard, SCardRemoveReaderFromGroupW, operation->hContext, call->sz1, call->sz2); - log_status_error(TAG, "SCardRemoveReaderFromGroupW", ret.ReturnCode); - free(call->sz1); - call->sz1 = NULL; - free(call->sz2); - call->sz2 = NULL; - - smartcard_trace_long_return(smartcard, &ret, "SCardRemoveReaderFromGroupW"); - return ret.ReturnCode; -} - -static LONG smartcard_LocateCardsA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - UINT32 x; - LONG status; - LocateCards_Return ret = { 0 }; - LocateCardsA_Call* call = &operation->call.locateCardsA; - IRP* irp = operation->irp; - - ret.ReturnCode = wrap(smartcard, SCardLocateCardsA, operation->hContext, call->mszCards, - call->rgReaderStates, call->cReaders); - log_status_error(TAG, "SCardLocateCardsA", ret.ReturnCode); - ret.cReaders = call->cReaders; - ret.rgReaderStates = NULL; - - free(call->mszCards); - - if (ret.cReaders > 0) - { - ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); - - if (!ret.rgReaderStates) - return STATUS_NO_MEMORY; - } - - for (x = 0; x < ret.cReaders; x++) - { - ret.rgReaderStates[x].dwCurrentState = call->rgReaderStates[x].dwCurrentState; - ret.rgReaderStates[x].dwEventState = call->rgReaderStates[x].dwEventState; - ret.rgReaderStates[x].cbAtr = call->rgReaderStates[x].cbAtr; - CopyMemory(&(ret.rgReaderStates[x].rgbAtr), &(call->rgReaderStates[x].rgbAtr), - sizeof(ret.rgReaderStates[x].rgbAtr)); - } - - status = smartcard_pack_locate_cards_return(smartcard, irp->output, &ret); - - for (x = 0; x < call->cReaders; x++) - { - SCARD_READERSTATEA* state = &call->rgReaderStates[x]; - free(state->szReader); - } - - free(call->rgReaderStates); - - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_LocateCardsW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - UINT32 x; - LONG status; - LocateCards_Return ret = { 0 }; - LocateCardsW_Call* call = &operation->call.locateCardsW; - IRP* irp = operation->irp; - - ret.ReturnCode = wrap(smartcard, SCardLocateCardsW, operation->hContext, call->mszCards, - call->rgReaderStates, call->cReaders); - log_status_error(TAG, "SCardLocateCardsW", ret.ReturnCode); - ret.cReaders = call->cReaders; - ret.rgReaderStates = NULL; - - free(call->mszCards); - - if (ret.cReaders > 0) - { - ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); - - if (!ret.rgReaderStates) - return STATUS_NO_MEMORY; - } - - for (x = 0; x < ret.cReaders; x++) - { - ret.rgReaderStates[x].dwCurrentState = call->rgReaderStates[x].dwCurrentState; - ret.rgReaderStates[x].dwEventState = call->rgReaderStates[x].dwEventState; - ret.rgReaderStates[x].cbAtr = call->rgReaderStates[x].cbAtr; - CopyMemory(&(ret.rgReaderStates[x].rgbAtr), &(call->rgReaderStates[x].rgbAtr), - sizeof(ret.rgReaderStates[x].rgbAtr)); - } - - status = smartcard_pack_locate_cards_return(smartcard, irp->output, &ret); - - for (x = 0; x < call->cReaders; x++) - { - SCARD_READERSTATEW* state = &call->rgReaderStates[x]; - free(state->szReader); - } - - free(call->rgReaderStates); - - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_ReadCacheA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - ReadCache_Return ret = { 0 }; - ReadCacheA_Call* call = &operation->call.readCacheA; - IRP* irp = operation->irp; - BOOL autoalloc = (call->Common.cbDataLen == SCARD_AUTOALLOCATE); - - if (!call->Common.fPbDataIsNULL) - { - ret.cbDataLen = call->Common.cbDataLen; - if (!autoalloc) - { - ret.pbData = malloc(ret.cbDataLen); - if (!ret.pbData) - return SCARD_F_INTERNAL_ERROR; - } - } - - if (autoalloc) - ret.ReturnCode = wrap(smartcard, SCardReadCacheA, operation->hContext, - call->Common.CardIdentifier, call->Common.FreshnessCounter, - call->szLookupName, (BYTE*)&ret.pbData, &ret.cbDataLen); - else - ret.ReturnCode = - wrap(smartcard, SCardReadCacheA, operation->hContext, call->Common.CardIdentifier, - call->Common.FreshnessCounter, call->szLookupName, ret.pbData, &ret.cbDataLen); - if ((ret.ReturnCode != SCARD_W_CACHE_ITEM_NOT_FOUND) && - (ret.ReturnCode != SCARD_W_CACHE_ITEM_STALE)) - { - log_status_error(TAG, "SCardReadCacheA", ret.ReturnCode); - } - free(call->szLookupName); - free(call->Common.CardIdentifier); - - status = smartcard_pack_read_cache_return(smartcard, irp->output, &ret); - if (autoalloc) - wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData); - else - free(ret.pbData); - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_ReadCacheW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - ReadCache_Return ret = { 0 }; - ReadCacheW_Call* call = &operation->call.readCacheW; - IRP* irp = operation->irp; - - if (!call->Common.fPbDataIsNULL) - ret.cbDataLen = SCARD_AUTOALLOCATE; - - ret.ReturnCode = - wrap(smartcard, SCardReadCacheW, operation->hContext, call->Common.CardIdentifier, - call->Common.FreshnessCounter, call->szLookupName, (BYTE*)&ret.pbData, &ret.cbDataLen); - - if ((ret.ReturnCode != SCARD_W_CACHE_ITEM_NOT_FOUND) && - (ret.ReturnCode != SCARD_W_CACHE_ITEM_STALE)) - { - log_status_error(TAG, "SCardReadCacheA", ret.ReturnCode); - } - free(call->szLookupName); - free(call->Common.CardIdentifier); - - status = smartcard_pack_read_cache_return(smartcard, irp->output, &ret); - - wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData); - - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_WriteCacheA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - WriteCacheA_Call* call = &operation->call.writeCacheA; - - ret.ReturnCode = wrap(smartcard, SCardWriteCacheA, operation->hContext, - call->Common.CardIdentifier, call->Common.FreshnessCounter, - call->szLookupName, call->Common.pbData, call->Common.cbDataLen); - log_status_error(TAG, "SCardWriteCacheA", ret.ReturnCode); - free(call->szLookupName); - free(call->Common.CardIdentifier); - free(call->Common.pbData); - - smartcard_trace_long_return(smartcard, &ret, "SCardWriteCacheA"); - return ret.ReturnCode; -} - -static LONG smartcard_WriteCacheW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - WriteCacheW_Call* call = &operation->call.writeCacheW; - - ret.ReturnCode = wrap(smartcard, SCardWriteCacheW, operation->hContext, - call->Common.CardIdentifier, call->Common.FreshnessCounter, - call->szLookupName, call->Common.pbData, call->Common.cbDataLen); - log_status_error(TAG, "SCardWriteCacheW", ret.ReturnCode); - free(call->szLookupName); - free(call->Common.CardIdentifier); - free(call->Common.pbData); - - smartcard_trace_long_return(smartcard, &ret, "SCardWriteCacheW"); - return ret.ReturnCode; -} - -static LONG smartcard_GetTransmitCount_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - GetTransmitCount_Return ret = { 0 }; - IRP* irp = operation->irp; - - ret.ReturnCode = wrap(smartcard, SCardGetTransmitCount, operation->hCard, &ret.cTransmitCount); - log_status_error(TAG, "SCardGetTransmitCount", ret.ReturnCode); - status = smartcard_pack_get_transmit_count_return(smartcard, irp->output, &ret); - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_ReleaseStartedEvent_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - WINPR_UNUSED(smartcard); - WINPR_UNUSED(operation); - - WLog_WARN(TAG, "According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules " - "this is not supported?!?"); - return SCARD_E_UNSUPPORTED_FEATURE; -} - -static LONG smartcard_GetReaderIcon_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - GetReaderIcon_Return ret = { 0 }; - GetReaderIcon_Call* call = &operation->call.getReaderIcon; - IRP* irp = operation->irp; - - ret.cbDataLen = SCARD_AUTOALLOCATE; - ret.ReturnCode = wrap(smartcard, SCardGetReaderIconW, operation->hContext, call->szReaderName, - (LPBYTE)&ret.pbData, &ret.cbDataLen); - log_status_error(TAG, "SCardGetReaderIconW", ret.ReturnCode); - free(call->szReaderName); - status = smartcard_pack_get_reader_icon_return(smartcard, irp->output, &ret); - wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData); - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_GetDeviceTypeId_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - GetDeviceTypeId_Return ret = { 0 }; - GetDeviceTypeId_Call* call = &operation->call.getDeviceTypeId; - IRP* irp = operation->irp; - - ret.ReturnCode = wrap(smartcard, SCardGetDeviceTypeIdW, operation->hContext, call->szReaderName, - &ret.dwDeviceId); - log_status_error(TAG, "SCardGetDeviceTypeIdW", ret.ReturnCode); - free(call->szReaderName); - - status = smartcard_pack_device_type_id_return(smartcard, irp->output, &ret); - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_get_status_change_a_call(smartcard, irp->input, - &operation->call.getStatusChangeA); - - return status; -} - -static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - UINT32 index; - GetStatusChange_Return ret = { 0 }; - LPSCARD_READERSTATEA rgReaderState = NULL; - IRP* irp = operation->irp; - GetStatusChangeA_Call* call = &operation->call.getStatusChangeA; - ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeA, operation->hContext, call->dwTimeOut, - call->rgReaderStates, call->cReaders); - log_status_error(TAG, "SCardGetStatusChangeA", ret.ReturnCode); - ret.cReaders = call->cReaders; - ret.rgReaderStates = NULL; - - if (ret.cReaders > 0) - { - ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); - - if (!ret.rgReaderStates) - return STATUS_NO_MEMORY; - } - - for (index = 0; index < ret.cReaders; index++) - { - ret.rgReaderStates[index].dwCurrentState = call->rgReaderStates[index].dwCurrentState; - ret.rgReaderStates[index].dwEventState = call->rgReaderStates[index].dwEventState; - ret.rgReaderStates[index].cbAtr = call->rgReaderStates[index].cbAtr; - CopyMemory(&(ret.rgReaderStates[index].rgbAtr), &(call->rgReaderStates[index].rgbAtr), - sizeof(ret.rgReaderStates[index].rgbAtr)); - } - - smartcard_pack_get_status_change_return(smartcard, irp->output, &ret, FALSE); - - if (call->rgReaderStates) - { - for (index = 0; index < call->cReaders; index++) - { - rgReaderState = &call->rgReaderStates[index]; - free((void*)rgReaderState->szReader); - } - - free(call->rgReaderStates); - } - - free(ret.rgReaderStates); - return ret.ReturnCode; -} - -static LONG smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_get_status_change_w_call(smartcard, irp->input, - &operation->call.getStatusChangeW); - - return status; -} - -static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - UINT32 index; - GetStatusChange_Return ret = { 0 }; - LPSCARD_READERSTATEW rgReaderState = NULL; - IRP* irp = operation->irp; - GetStatusChangeW_Call* call = &operation->call.getStatusChangeW; - ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeW, operation->hContext, call->dwTimeOut, - call->rgReaderStates, call->cReaders); - log_status_error(TAG, "SCardGetStatusChangeW", ret.ReturnCode); - ret.cReaders = call->cReaders; - ret.rgReaderStates = NULL; - - if (ret.cReaders > 0) - { - ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); - - if (!ret.rgReaderStates) - return STATUS_NO_MEMORY; - } - - for (index = 0; index < ret.cReaders; index++) - { - ret.rgReaderStates[index].dwCurrentState = call->rgReaderStates[index].dwCurrentState; - ret.rgReaderStates[index].dwEventState = call->rgReaderStates[index].dwEventState; - ret.rgReaderStates[index].cbAtr = call->rgReaderStates[index].cbAtr; - CopyMemory(&(ret.rgReaderStates[index].rgbAtr), &(call->rgReaderStates[index].rgbAtr), - sizeof(ret.rgReaderStates[index].rgbAtr)); - } - - status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret, TRUE); - - if (call->rgReaderStates) - { - for (index = 0; index < call->cReaders; index++) - { - rgReaderState = &call->rgReaderStates[index]; - free((void*)rgReaderState->szReader); - } - - free(call->rgReaderStates); - } - - free(ret.rgReaderStates); - if (status != SCARD_S_SUCCESS) - return status; - return ret.ReturnCode; -} - -static LONG smartcard_Cancel_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = - smartcard_unpack_context_call(smartcard, irp->input, &operation->call.context, "Cancel"); - - return status; -} - -static LONG smartcard_Cancel_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - - ret.ReturnCode = wrap(smartcard, SCardCancel, operation->hContext); - log_status_error(TAG, "SCardCancel", ret.ReturnCode); - smartcard_trace_long_return(smartcard, &ret, "Cancel"); - return ret.ReturnCode; -} - -static LONG smartcard_ConnectA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_connect_a_call(smartcard, irp->input, &operation->call.connectA); - - return status; -} - -static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - SCARDHANDLE hCard = 0; - Connect_Return ret = { 0 }; - IRP* irp = operation->irp; - ConnectA_Call* call = &operation->call.connectA; - - if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) && - (call->Common.dwShareMode != SCARD_SHARE_DIRECT)) - { - call->Common.dwPreferredProtocols = SCARD_PROTOCOL_Tx; - } - - ret.ReturnCode = wrap(smartcard, SCardConnectA, operation->hContext, (char*)call->szReader, - call->Common.dwShareMode, 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); - - status = smartcard_pack_connect_return(smartcard, irp->output, &ret); - if (status != SCARD_S_SUCCESS) - goto out_fail; - - status = ret.ReturnCode; -out_fail: - free(call->szReader); - return status; -} - -static LONG smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_connect_w_call(smartcard, irp->input, &operation->call.connectW); - - return status; -} - -static LONG smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - SCARDHANDLE hCard = 0; - Connect_Return ret = { 0 }; - IRP* irp = operation->irp; - ConnectW_Call* call = &operation->call.connectW; - - if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) && - (call->Common.dwShareMode != SCARD_SHARE_DIRECT)) - { - call->Common.dwPreferredProtocols = SCARD_PROTOCOL_Tx; - } - - ret.ReturnCode = wrap(smartcard, SCardConnectW, operation->hContext, (WCHAR*)call->szReader, - call->Common.dwShareMode, 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); - - status = smartcard_pack_connect_return(smartcard, irp->output, &ret); - if (status != SCARD_S_SUCCESS) - goto out_fail; - - status = ret.ReturnCode; -out_fail: - free(call->szReader); - return status; -} - -static LONG smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_reconnect_call(smartcard, irp->input, &operation->call.reconnect); - - return status; -} - -static LONG smartcard_Reconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - Reconnect_Return ret = { 0 }; - IRP* irp = operation->irp; - Reconnect_Call* call = &operation->call.reconnect; - ret.ReturnCode = - wrap(smartcard, SCardReconnect, operation->hCard, call->dwShareMode, - call->dwPreferredProtocols, call->dwInitialization, &ret.dwActiveProtocol); - log_status_error(TAG, "SCardReconnect", ret.ReturnCode); - status = smartcard_pack_reconnect_return(smartcard, irp->output, &ret); - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_Disconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_hcard_and_disposition_call( - smartcard, irp->input, &operation->call.hCardAndDisposition, "Disconnect"); - - return status; -} - -static LONG smartcard_Disconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - HCardAndDisposition_Call* call = &operation->call.hCardAndDisposition; - - ret.ReturnCode = wrap(smartcard, SCardDisconnect, operation->hCard, call->dwDisposition); - log_status_error(TAG, "SCardDisconnect", ret.ReturnCode); - smartcard_trace_long_return(smartcard, &ret, "Disconnect"); - - return ret.ReturnCode; -} - -static LONG smartcard_BeginTransaction_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_hcard_and_disposition_call( - smartcard, irp->input, &operation->call.hCardAndDisposition, "BeginTransaction"); - - return status; -} - -static LONG smartcard_BeginTransaction_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - - ret.ReturnCode = wrap(smartcard, SCardBeginTransaction, operation->hCard); - log_status_error(TAG, "SCardBeginTransaction", ret.ReturnCode); - smartcard_trace_long_return(smartcard, &ret, "BeginTransaction"); - return ret.ReturnCode; -} - -static LONG smartcard_EndTransaction_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_hcard_and_disposition_call( - smartcard, irp->input, &operation->call.hCardAndDisposition, "EndTransaction"); - - return status; -} - -static LONG smartcard_EndTransaction_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - HCardAndDisposition_Call* call = &operation->call.hCardAndDisposition; - - ret.ReturnCode = wrap(smartcard, SCardEndTransaction, operation->hCard, call->dwDisposition); - log_status_error(TAG, "SCardEndTransaction", ret.ReturnCode); - smartcard_trace_long_return(smartcard, &ret, "EndTransaction"); - return ret.ReturnCode; -} - -static LONG smartcard_State_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_state_call(smartcard, irp->input, &operation->call.state); - - return status; -} - -static LONG smartcard_State_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - State_Return ret = { 0 }; - IRP* irp = operation->irp; - ret.cbAtrLen = SCARD_ATR_LENGTH; - ret.ReturnCode = wrap(smartcard, SCardState, operation->hCard, &ret.dwState, &ret.dwProtocol, - (BYTE*)&ret.rgAtr, &ret.cbAtrLen); - - log_status_error(TAG, "SCardState", ret.ReturnCode); - status = smartcard_pack_state_return(smartcard, irp->output, &ret); - if (status != SCARD_S_SUCCESS) - return status; - - return ret.ReturnCode; -} - -static LONG smartcard_StatusA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_status_call(smartcard, irp->input, &operation->call.status, FALSE); - - return status; -} - -static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - Status_Return ret = { 0 }; - DWORD cchReaderLen = 0; - DWORD cbAtrLen = 0; - LPSTR mszReaderNames = NULL; - IRP* irp = operation->irp; - Status_Call* call = &operation->call.status; - - call->cbAtrLen = 32; - cbAtrLen = call->cbAtrLen; - - if (call->fmszReaderNamesIsNULL) - cchReaderLen = 0; - else - cchReaderLen = SCARD_AUTOALLOCATE; - - status = ret.ReturnCode = - wrap(smartcard, SCardStatusA, operation->hCard, - call->fmszReaderNamesIsNULL ? NULL : (LPSTR)&mszReaderNames, &cchReaderLen, - &ret.dwState, &ret.dwProtocol, cbAtrLen ? (BYTE*)&ret.pbAtr : NULL, &cbAtrLen); - - log_status_error(TAG, "SCardStatusA", status); - if (status == SCARD_S_SUCCESS) - { - if (!call->fmszReaderNamesIsNULL) - ret.mszReaderNames = (BYTE*)mszReaderNames; - - ret.cBytes = cchReaderLen; - - if (call->cbAtrLen) - ret.cbAtrLen = cbAtrLen; - } - - status = smartcard_pack_status_return(smartcard, irp->output, &ret, FALSE); - - if (mszReaderNames) - wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaderNames); - - if (status != SCARD_S_SUCCESS) - return status; - return ret.ReturnCode; -} - -static LONG smartcard_StatusW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_status_call(smartcard, irp->input, &operation->call.status, TRUE); - - return status; -} - -static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - Status_Return ret = { 0 }; - LPWSTR mszReaderNames = NULL; - IRP* irp = operation->irp; - Status_Call* call = &operation->call.status; - DWORD cbAtrLen; - - /** - * [MS-RDPESC] - * According to 2.2.2.18 Status_Call cbAtrLen is unused an must be ignored upon receipt. - */ - cbAtrLen = call->cbAtrLen = 32; - - if (call->fmszReaderNamesIsNULL) - ret.cBytes = 0; - else - ret.cBytes = SCARD_AUTOALLOCATE; - - status = ret.ReturnCode = - wrap(smartcard, SCardStatusW, operation->hCard, - call->fmszReaderNamesIsNULL ? NULL : (LPWSTR)&mszReaderNames, &ret.cBytes, - &ret.dwState, &ret.dwProtocol, (BYTE*)&ret.pbAtr, &cbAtrLen); - log_status_error(TAG, "SCardStatusW", status); - if (status == SCARD_S_SUCCESS) - { - if (!call->fmszReaderNamesIsNULL) - ret.mszReaderNames = (BYTE*)mszReaderNames; - - ret.cbAtrLen = cbAtrLen; - } - - /* SCardStatusW returns number of characters, we need number of bytes */ - ret.cBytes *= sizeof(WCHAR); - - status = smartcard_pack_status_return(smartcard, irp->output, &ret, TRUE); - if (status != SCARD_S_SUCCESS) - return status; - - if (mszReaderNames) - wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaderNames); - - return ret.ReturnCode; -} - -static LONG smartcard_Transmit_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_transmit_call(smartcard, irp->input, &operation->call.transmit); - - return status; -} - -static LONG smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - Transmit_Return ret = { 0 }; - IRP* irp = operation->irp; - Transmit_Call* call = &operation->call.transmit; - ret.cbRecvLength = 0; - ret.pbRecvBuffer = NULL; - - if (call->cbRecvLength && !call->fpbRecvBufferIsNULL) - { - if (call->cbRecvLength >= 66560) - call->cbRecvLength = 66560; - - ret.cbRecvLength = call->cbRecvLength; - ret.pbRecvBuffer = (BYTE*)malloc(ret.cbRecvLength); - - if (!ret.pbRecvBuffer) - return STATUS_NO_MEMORY; - } - - ret.pioRecvPci = call->pioRecvPci; - ret.ReturnCode = - wrap(smartcard, SCardTransmit, operation->hCard, call->pioSendPci, call->pbSendBuffer, - call->cbSendLength, ret.pioRecvPci, ret.pbRecvBuffer, &(ret.cbRecvLength)); - - log_status_error(TAG, "SCardTransmit", ret.ReturnCode); - - status = smartcard_pack_transmit_return(smartcard, irp->output, &ret); - free(call->pbSendBuffer); - free(ret.pbRecvBuffer); - free(call->pioSendPci); - free(call->pioRecvPci); - - if (status != SCARD_S_SUCCESS) - return status; - return ret.ReturnCode; -} - -static LONG smartcard_Control_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_control_call(smartcard, irp->input, &operation->call.control); - - return status; -} - -static LONG smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - Control_Return ret = { 0 }; - IRP* irp = operation->irp; - Control_Call* call = &operation->call.control; - ret.cbOutBufferSize = call->cbOutBufferSize; - ret.pvOutBuffer = (BYTE*)malloc(call->cbOutBufferSize); - - if (!ret.pvOutBuffer) - return SCARD_E_NO_MEMORY; - - ret.ReturnCode = - wrap(smartcard, SCardControl, operation->hCard, call->dwControlCode, call->pvInBuffer, - call->cbInBufferSize, ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize); - log_status_error(TAG, "SCardControl", ret.ReturnCode); - status = smartcard_pack_control_return(smartcard, irp->output, &ret); - - free(call->pvInBuffer); - free(ret.pvOutBuffer); - if (status != SCARD_S_SUCCESS) - return status; - return ret.ReturnCode; -} - -static LONG smartcard_GetAttrib_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_get_attrib_call(smartcard, irp->input, &operation->call.getAttrib); - - return status; -} - -static LONG smartcard_SetAttrib_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_set_attrib_call(smartcard, irp->input, &operation->call.setAttrib); - - return status; -} - -static LONG smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - BOOL autoAllocate = FALSE; - LONG status; - DWORD cbAttrLen = 0; - LPBYTE pbAttr = NULL; - GetAttrib_Return ret = { 0 }; - IRP* irp = operation->irp; - const GetAttrib_Call* call = &operation->call.getAttrib; - - if (!call->fpbAttrIsNULL) - { - autoAllocate = (call->cbAttrLen == SCARD_AUTOALLOCATE) ? TRUE : FALSE; - cbAttrLen = call->cbAttrLen; - if (cbAttrLen && !autoAllocate) - { - ret.pbAttr = (BYTE*)malloc(cbAttrLen); - - if (!ret.pbAttr) - return SCARD_E_NO_MEMORY; - } - - pbAttr = autoAllocate ? (LPBYTE) & (ret.pbAttr) : ret.pbAttr; - } - - ret.ReturnCode = - wrap(smartcard, SCardGetAttrib, operation->hCard, call->dwAttrId, pbAttr, &cbAttrLen); - log_status_error(TAG, "SCardGetAttrib", ret.ReturnCode); - ret.cbAttrLen = cbAttrLen; - - status = smartcard_pack_get_attrib_return(smartcard, irp->output, &ret, call->dwAttrId, - call->cbAttrLen); - - if (autoAllocate) - wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbAttr); - else - free(ret.pbAttr); - return status; -} - -static LONG smartcard_SetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - Long_Return ret = { 0 }; - SetAttrib_Call* call = &operation->call.setAttrib; - - ret.ReturnCode = wrap(smartcard, SCardSetAttrib, operation->hCard, call->dwAttrId, call->pbAttr, - call->cbAttrLen); - log_status_error(TAG, "SCardSetAttrib", ret.ReturnCode); - free(call->pbAttr); - smartcard_trace_long_return(smartcard, &ret, "SetAttrib"); - - return ret.ReturnCode; -} - -static LONG smartcard_AccessStartedEvent_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - IRP* irp; - WINPR_UNUSED(smartcard); - irp = operation->irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - - if (Stream_GetRemainingLength(irp->input) < 4) - { - WLog_WARN(TAG, "AccessStartedEvent is too short: %" PRIuz "", - Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; - } - - Stream_Read_INT32(irp->input, operation->call.lng.LongValue); /* Unused (4 bytes) */ - - return SCARD_S_SUCCESS; -} - -static LONG smartcard_AccessStartedEvent_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status = SCARD_S_SUCCESS; - WINPR_UNUSED(operation); - - if (!smartcard->StartedEvent) - smartcard->StartedEvent = wrap(smartcard, SCardAccessStartedEvent); - - if (!smartcard->StartedEvent) - status = SCARD_E_NO_SERVICE; - - return status; -} - -static LONG smartcard_LocateCardsByATRA_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_locate_cards_by_atr_a_call(smartcard, irp->input, - &operation->call.locateCardsByATRA); - - return status; -} - -static LONG smartcard_LocateCardsByATRW_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_locate_cards_by_atr_w_call(smartcard, irp->input, - &operation->call.locateCardsByATRW); - - return status; -} - -static LONG smartcard_ReadCacheA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_read_cache_a_call(smartcard, irp->input, &operation->call.readCacheA); - - return status; -} - -static LONG smartcard_ReadCacheW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - - status = smartcard_unpack_read_cache_w_call(smartcard, irp->input, &operation->call.readCacheW); - - return status; -} - -static LONG smartcard_WriteCacheA_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = - smartcard_unpack_write_cache_a_call(smartcard, irp->input, &operation->call.writeCacheA); - - return status; -} - -static LONG smartcard_WriteCacheW_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = - smartcard_unpack_write_cache_w_call(smartcard, irp->input, &operation->call.writeCacheW); - - return status; -} - -static LONG smartcard_GetTransmitCount_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_get_transmit_count_call(smartcard, irp->input, - &operation->call.getTransmitCount); - - return status; -} - -static LONG smartcard_ReleaseStartedEvent_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - WINPR_UNUSED(smartcard); - WINPR_UNUSED(operation); - WLog_WARN(TAG, "According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules " - "SCARD_IOCTL_RELEASETARTEDEVENT is not supported"); - return SCARD_E_UNSUPPORTED_FEATURE; -} - -static LONG smartcard_GetReaderIcon_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - - status = smartcard_unpack_get_reader_icon_call(smartcard, irp->input, - &operation->call.getReaderIcon); - - return status; -} - -static LONG smartcard_GetDeviceTypeId_Decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - IRP* irp; - - if (!operation || !operation->irp) - return STATUS_NO_MEMORY; - irp = operation->irp; - status = smartcard_unpack_get_device_type_id_call(smartcard, irp->input, - &operation->call.getDeviceTypeId); - - return status; -} - -static LONG smartcard_LocateCardsByATRA_Call(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - DWORD i, j, k; - GetStatusChange_Return ret = { 0 }; - LPSCARD_READERSTATEA state = NULL; - LPSCARD_READERSTATEA states = NULL; - IRP* irp = operation->irp; - LocateCardsByATRA_Call* call = &operation->call.locateCardsByATRA; - states = (LPSCARD_READERSTATEA)calloc(call->cReaders, sizeof(SCARD_READERSTATEA)); - - if (!states) - return STATUS_NO_MEMORY; - - for (i = 0; i < call->cReaders; i++) - { - states[i].szReader = (LPSTR)call->rgReaderStates[i].szReader; - states[i].dwCurrentState = call->rgReaderStates[i].dwCurrentState; - states[i].dwEventState = call->rgReaderStates[i].dwEventState; - states[i].cbAtr = call->rgReaderStates[i].cbAtr; - CopyMemory(&(states[i].rgbAtr), &(call->rgReaderStates[i].rgbAtr), 36); - } - - status = ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeA, operation->hContext, - 0x000001F4, states, call->cReaders); - - log_status_error(TAG, "SCardGetStatusChangeA", status); - for (i = 0; i < call->cAtrs; i++) - { - for (j = 0; j < call->cReaders; j++) - { - for (k = 0; k < call->rgAtrMasks[i].cbAtr; k++) - { - if ((call->rgAtrMasks[i].rgbAtr[k] & call->rgAtrMasks[i].rgbMask[k]) != - (states[j].rgbAtr[k] & call->rgAtrMasks[i].rgbMask[k])) - { - break; - } - - states[j].dwEventState |= SCARD_STATE_ATRMATCH; - } - } - } - - ret.cReaders = call->cReaders; - ret.rgReaderStates = NULL; - - if (ret.cReaders > 0) - ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); - - if (!ret.rgReaderStates) - { - free(states); - return STATUS_NO_MEMORY; - } - - for (i = 0; i < ret.cReaders; i++) - { - state = &states[i]; - ret.rgReaderStates[i].dwCurrentState = state->dwCurrentState; - ret.rgReaderStates[i].dwEventState = state->dwEventState; - ret.rgReaderStates[i].cbAtr = state->cbAtr; - CopyMemory(&(ret.rgReaderStates[i].rgbAtr), &(state->rgbAtr), - sizeof(ret.rgReaderStates[i].rgbAtr)); - } - - free(states); - - status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret, FALSE); - - if (call->rgReaderStates) - { - for (i = 0; i < call->cReaders; i++) - { - state = (LPSCARD_READERSTATEA)&call->rgReaderStates[i]; - - if (state->szReader) - { - free((void*)state->szReader); - state->szReader = NULL; - } - } - - free(call->rgReaderStates); - call->rgReaderStates = NULL; - } - - free(ret.rgReaderStates); - if (status != SCARD_S_SUCCESS) - return status; - return ret.ReturnCode; -} - -LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, - SMARTCARD_OPERATION* operation) -{ - LONG status; - UINT32 offset; - UINT32 ioControlCode; - UINT32 outputBufferLength; - UINT32 inputBufferLength; - IRP* irp; - - if (!operation || !operation->irp) - return SCARD_E_NO_MEMORY; - irp = operation->irp; - - /* Device Control Request */ - - if (Stream_GetRemainingLength(irp->input) < 32) - { - WLog_WARN(TAG, "Device Control Request is too short: %" PRIuz "", - Stream_GetRemainingLength(irp->input)); - return SCARD_F_INTERNAL_ERROR; - } - - Stream_Read_UINT32(irp->input, outputBufferLength); /* OutputBufferLength (4 bytes) */ - Stream_Read_UINT32(irp->input, inputBufferLength); /* InputBufferLength (4 bytes) */ - Stream_Read_UINT32(irp->input, ioControlCode); /* IoControlCode (4 bytes) */ - Stream_Seek(irp->input, 20); /* Padding (20 bytes) */ - operation->ioControlCode = ioControlCode; - - if (Stream_Length(irp->input) != (Stream_GetPosition(irp->input) + inputBufferLength)) - { - WLog_WARN(TAG, "InputBufferLength mismatch: Actual: %" PRIuz " Expected: %" PRIuz "", - Stream_Length(irp->input), Stream_GetPosition(irp->input) + inputBufferLength); - return SCARD_F_INTERNAL_ERROR; - } - - WLog_DBG(TAG, "%s (0x%08" PRIX32 ") FileId: %" PRIu32 " CompletionId: %" PRIu32 "", - smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, - irp->CompletionId); - - if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && - (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT)) - { - status = smartcard_unpack_common_type_header(smartcard, irp->input); - if (status != SCARD_S_SUCCESS) - return status; - - status = smartcard_unpack_private_type_header(smartcard, irp->input); - if (status != SCARD_S_SUCCESS) - return status; - } - - /* Decode */ - switch (ioControlCode) - { - case SCARD_IOCTL_ESTABLISHCONTEXT: - status = smartcard_EstablishContext_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_RELEASECONTEXT: - status = smartcard_ReleaseContext_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_ISVALIDCONTEXT: - status = smartcard_IsValidContext_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_LISTREADERGROUPSA: - status = smartcard_ListReaderGroupsA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_LISTREADERGROUPSW: - status = smartcard_ListReaderGroupsW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_LISTREADERSA: - status = smartcard_ListReadersA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_LISTREADERSW: - status = smartcard_ListReadersW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_INTRODUCEREADERGROUPA: - status = smartcard_context_and_string_a_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_INTRODUCEREADERGROUPW: - status = smartcard_context_and_string_w_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_FORGETREADERGROUPA: - status = smartcard_context_and_string_a_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_FORGETREADERGROUPW: - status = smartcard_context_and_string_w_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_INTRODUCEREADERA: - status = smartcard_context_and_two_strings_a_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_INTRODUCEREADERW: - status = smartcard_context_and_two_strings_w_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_FORGETREADERA: - status = smartcard_context_and_string_a_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_FORGETREADERW: - status = smartcard_context_and_string_w_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_ADDREADERTOGROUPA: - status = smartcard_context_and_two_strings_a_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_ADDREADERTOGROUPW: - status = smartcard_context_and_two_strings_w_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_REMOVEREADERFROMGROUPA: - status = smartcard_context_and_two_strings_a_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_REMOVEREADERFROMGROUPW: - status = smartcard_context_and_two_strings_w_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_LOCATECARDSA: - status = smartcard_LocateCardsA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_LOCATECARDSW: - status = smartcard_LocateCardsW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_GETSTATUSCHANGEA: - status = smartcard_GetStatusChangeA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_GETSTATUSCHANGEW: - status = smartcard_GetStatusChangeW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_CANCEL: - status = smartcard_Cancel_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_CONNECTA: - status = smartcard_ConnectA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_CONNECTW: - status = smartcard_ConnectW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_RECONNECT: - status = smartcard_Reconnect_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_DISCONNECT: - status = smartcard_Disconnect_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_BEGINTRANSACTION: - status = smartcard_BeginTransaction_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_ENDTRANSACTION: - status = smartcard_EndTransaction_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_STATE: - status = smartcard_State_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_STATUSA: - status = smartcard_StatusA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_STATUSW: - status = smartcard_StatusW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_TRANSMIT: - status = smartcard_Transmit_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_CONTROL: - status = smartcard_Control_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_GETATTRIB: - status = smartcard_GetAttrib_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_SETATTRIB: - status = smartcard_SetAttrib_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_ACCESSSTARTEDEVENT: - status = smartcard_AccessStartedEvent_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_LOCATECARDSBYATRA: - status = smartcard_LocateCardsByATRA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_LOCATECARDSBYATRW: - status = smartcard_LocateCardsByATRW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_READCACHEA: - status = smartcard_ReadCacheA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_READCACHEW: - status = smartcard_ReadCacheW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_WRITECACHEA: - status = smartcard_WriteCacheA_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_WRITECACHEW: - status = smartcard_WriteCacheW_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_GETTRANSMITCOUNT: - status = smartcard_GetTransmitCount_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_RELEASETARTEDEVENT: - status = smartcard_ReleaseStartedEvent_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_GETREADERICON: - status = smartcard_GetReaderIcon_Decode(smartcard, operation); - break; - - case SCARD_IOCTL_GETDEVICETYPEID: - status = smartcard_GetDeviceTypeId_Decode(smartcard, operation); - break; - - default: - status = SCARD_F_INTERNAL_ERROR; - break; - } - - smartcard_call_to_operation_handle(smartcard, operation); - - if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && - (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT)) - { - offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH); - smartcard_unpack_read_size_align(smartcard, irp->input, - Stream_GetPosition(irp->input) - offset, 8); - } - - if (Stream_GetPosition(irp->input) < Stream_Length(irp->input)) - { - SIZE_T difference; - difference = Stream_Length(irp->input) - Stream_GetPosition(irp->input); - WLog_WARN(TAG, - "IRP was not fully parsed %s (%s [0x%08" PRIX32 "]): Actual: %" PRIuz - ", Expected: %" PRIuz ", Difference: %" PRIuz "", - smartcard_get_ioctl_string(ioControlCode, TRUE), - smartcard_get_ioctl_string(ioControlCode, FALSE), ioControlCode, - Stream_GetPosition(irp->input), Stream_Length(irp->input), difference); - winpr_HexDump(TAG, WLOG_WARN, Stream_Pointer(irp->input), difference); - } - - if (Stream_GetPosition(irp->input) > Stream_Length(irp->input)) - { - SIZE_T difference; - difference = Stream_GetPosition(irp->input) - Stream_Length(irp->input); - WLog_WARN(TAG, - "IRP was parsed beyond its end %s (0x%08" PRIX32 "): Actual: %" PRIuz - ", Expected: %" PRIuz ", Difference: %" PRIuz "", - smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, - Stream_GetPosition(irp->input), Stream_Length(irp->input), difference); - } - - return status; -} - -LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) -{ - IRP* irp; - LONG result; - UINT32 offset; - UINT32 ioControlCode; - size_t outputBufferLength; - size_t objectBufferLength; - irp = operation->irp; - ioControlCode = operation->ioControlCode; - /** - * [MS-RDPESC] 3.2.5.1: Sending Outgoing Messages: - * the output buffer length SHOULD be set to 2048 - * - * Since it's a SHOULD and not a MUST, we don't care - * about it, but we still reserve at least 2048 bytes. - */ - if (!Stream_EnsureRemainingCapacity(irp->output, 2048)) - return SCARD_E_NO_MEMORY; - - /* Device Control Response */ - Stream_Seek_UINT32(irp->output); /* OutputBufferLength (4 bytes) */ - Stream_Seek(irp->output, SMARTCARD_COMMON_TYPE_HEADER_LENGTH); /* CommonTypeHeader (8 bytes) */ - Stream_Seek(irp->output, - SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH); /* PrivateTypeHeader (8 bytes) */ - Stream_Seek_UINT32(irp->output); /* Result (4 bytes) */ - - /* Call */ - - switch (ioControlCode) - { - case SCARD_IOCTL_ESTABLISHCONTEXT: - result = smartcard_EstablishContext_Call(smartcard, operation); - break; - - case SCARD_IOCTL_RELEASECONTEXT: - result = smartcard_ReleaseContext_Call(smartcard, operation); - break; - - case SCARD_IOCTL_ISVALIDCONTEXT: - result = smartcard_IsValidContext_Call(smartcard, operation); - break; - - case SCARD_IOCTL_LISTREADERGROUPSA: - result = smartcard_ListReaderGroupsA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_LISTREADERGROUPSW: - result = smartcard_ListReaderGroupsW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_LISTREADERSA: - result = smartcard_ListReadersA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_LISTREADERSW: - result = smartcard_ListReadersW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_INTRODUCEREADERGROUPA: - result = smartcard_IntroduceReaderGroupA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_INTRODUCEREADERGROUPW: - result = smartcard_IntroduceReaderGroupW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_FORGETREADERGROUPA: - result = smartcard_ForgetReaderA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_FORGETREADERGROUPW: - result = smartcard_ForgetReaderW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_INTRODUCEREADERA: - result = smartcard_IntroduceReaderA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_INTRODUCEREADERW: - result = smartcard_IntroduceReaderW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_FORGETREADERA: - result = smartcard_ForgetReaderA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_FORGETREADERW: - result = smartcard_ForgetReaderW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_ADDREADERTOGROUPA: - result = smartcard_AddReaderToGroupA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_ADDREADERTOGROUPW: - result = smartcard_AddReaderToGroupW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_REMOVEREADERFROMGROUPA: - result = smartcard_RemoveReaderFromGroupA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_REMOVEREADERFROMGROUPW: - result = smartcard_RemoveReaderFromGroupW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_LOCATECARDSA: - result = smartcard_LocateCardsA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_LOCATECARDSW: - result = smartcard_LocateCardsW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_GETSTATUSCHANGEA: - result = smartcard_GetStatusChangeA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_GETSTATUSCHANGEW: - result = smartcard_GetStatusChangeW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_CANCEL: - result = smartcard_Cancel_Call(smartcard, operation); - break; - - case SCARD_IOCTL_CONNECTA: - result = smartcard_ConnectA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_CONNECTW: - result = smartcard_ConnectW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_RECONNECT: - result = smartcard_Reconnect_Call(smartcard, operation); - break; - - case SCARD_IOCTL_DISCONNECT: - result = smartcard_Disconnect_Call(smartcard, operation); - break; - - case SCARD_IOCTL_BEGINTRANSACTION: - result = smartcard_BeginTransaction_Call(smartcard, operation); - break; - - case SCARD_IOCTL_ENDTRANSACTION: - result = smartcard_EndTransaction_Call(smartcard, operation); - break; - - case SCARD_IOCTL_STATE: - result = smartcard_State_Call(smartcard, operation); - break; - - case SCARD_IOCTL_STATUSA: - result = smartcard_StatusA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_STATUSW: - result = smartcard_StatusW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_TRANSMIT: - result = smartcard_Transmit_Call(smartcard, operation); - break; - - case SCARD_IOCTL_CONTROL: - result = smartcard_Control_Call(smartcard, operation); - break; - - case SCARD_IOCTL_GETATTRIB: - result = smartcard_GetAttrib_Call(smartcard, operation); - break; - - case SCARD_IOCTL_SETATTRIB: - result = smartcard_SetAttrib_Call(smartcard, operation); - break; - - case SCARD_IOCTL_ACCESSSTARTEDEVENT: - result = smartcard_AccessStartedEvent_Call(smartcard, operation); - break; - - case SCARD_IOCTL_LOCATECARDSBYATRA: - result = smartcard_LocateCardsByATRA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_LOCATECARDSBYATRW: - result = smartcard_LocateCardsW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_READCACHEA: - result = smartcard_ReadCacheA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_READCACHEW: - result = smartcard_ReadCacheW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_WRITECACHEA: - result = smartcard_WriteCacheA_Call(smartcard, operation); - break; - - case SCARD_IOCTL_WRITECACHEW: - result = smartcard_WriteCacheW_Call(smartcard, operation); - break; - - case SCARD_IOCTL_GETTRANSMITCOUNT: - result = smartcard_GetTransmitCount_Call(smartcard, operation); - break; - - case SCARD_IOCTL_RELEASETARTEDEVENT: - result = smartcard_ReleaseStartedEvent_Call(smartcard, operation); - break; - - case SCARD_IOCTL_GETREADERICON: - result = smartcard_GetReaderIcon_Call(smartcard, operation); - break; - - case SCARD_IOCTL_GETDEVICETYPEID: - result = smartcard_GetDeviceTypeId_Call(smartcard, operation); - break; - - default: - result = STATUS_UNSUCCESSFUL; - break; - } - - /** - * [MS-RPCE] 2.2.6.3 Primitive Type Serialization - * The type MUST be aligned on an 8-byte boundary. If the size of the - * primitive type is not a multiple of 8 bytes, the data MUST be padded. - */ - - if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && - (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT)) - { - offset = (RDPDR_DEVICE_IO_RESPONSE_LENGTH + RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH); - smartcard_pack_write_size_align(smartcard, irp->output, - Stream_GetPosition(irp->output) - offset, 8); - } - - if ((result != SCARD_S_SUCCESS) && (result != SCARD_E_TIMEOUT) && - (result != SCARD_E_NO_READERS_AVAILABLE) && (result != SCARD_E_NO_SERVICE) && - (result != SCARD_W_CACHE_ITEM_NOT_FOUND) && (result != SCARD_W_CACHE_ITEM_STALE)) - { - WLog_WARN(TAG, "IRP failure: %s (0x%08" PRIX32 "), status: %s (0x%08" PRIX32 ")", - smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, - SCardGetErrorString(result), result); - } - - irp->IoStatus = STATUS_SUCCESS; - - if ((result & 0xC0000000L) == 0xC0000000L) - { - /* NTSTATUS error */ - irp->IoStatus = (UINT32)result; - WLog_WARN(TAG, "IRP failure: %s (0x%08" PRIX32 "), ntstatus: 0x%08" PRIX32 "", - smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result); - } - - Stream_SealLength(irp->output); - outputBufferLength = Stream_Length(irp->output); - WINPR_ASSERT(outputBufferLength >= RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4U); - outputBufferLength -= (RDPDR_DEVICE_IO_RESPONSE_LENGTH + 4U); - WINPR_ASSERT(outputBufferLength >= RDPDR_DEVICE_IO_RESPONSE_LENGTH); - objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH; - WINPR_ASSERT(outputBufferLength <= UINT32_MAX); - WINPR_ASSERT(objectBufferLength <= UINT32_MAX); - Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH); - /* Device Control Response */ - Stream_Write_UINT32(irp->output, (UINT32)outputBufferLength); /* OutputBufferLength (4 bytes) */ - smartcard_pack_common_type_header(smartcard, irp->output); /* CommonTypeHeader (8 bytes) */ - smartcard_pack_private_type_header( - smartcard, irp->output, (UINT32)objectBufferLength); /* PrivateTypeHeader (8 bytes) */ - Stream_Write_INT32(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.h b/channels/smartcard/client/smartcard_pack.h deleted file mode 100644 index 82b1f3bc2..000000000 --- a/channels/smartcard/client/smartcard_pack.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Smart Card Structure Packing - * - * Copyright 2014 Marc-Andre Moreau - * Copyright 2015 Thincast Technologies GmbH - * Copyright 2015 DI (FH) Martin Haimberger - * Copyright 2020 Armin Novak - * Copyright 2020 Thincast Technologies GmbH - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H -#define FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H - -#include -#include -#include - -#define SMARTCARD_COMMON_TYPE_HEADER_LENGTH 8 -#define SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH 8 - -#include "smartcard_main.h" - -LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size, - UINT32 alignment); -LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size, - UINT32 alignment); - -SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard, - REDIR_SCARDCONTEXT* context); -void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard, - REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext); - -SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard, - REDIR_SCARDHANDLE* handle); -void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle, - SCARDHANDLE hCard); - -LONG smartcard_unpack_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); -void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, - UINT32 objectBufferLength); - -LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, - EstablishContext_Call* call); - -LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const EstablishContext_Return* ret); - -LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call, - const char* name); - -void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, const Long_Return* ret, - const char* name); - -LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ListReaderGroups_Call* call, BOOL unicode); - -LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const ListReaderGroups_Return* ret, BOOL unicode); - -LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ListReaders_Call* call, BOOL unicode); - -LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const ListReaders_Return* ret, BOOL unicode); - -LONG smartcard_unpack_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ContextAndTwoStringA_Call* call); - -LONG smartcard_unpack_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ContextAndTwoStringW_Call* call); - -LONG smartcard_unpack_context_and_string_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ContextAndStringA_Call* call); - -LONG smartcard_unpack_context_and_string_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ContextAndStringW_Call* call); - -LONG smartcard_unpack_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - LocateCardsA_Call* call); - -LONG smartcard_pack_locate_cards_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const LocateCards_Return* ret); - -LONG smartcard_unpack_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - LocateCardsW_Call* call); - -LONG smartcard_pack_locate_cards_w_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const LocateCardsW_Call* ret); - -LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call); - -LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call); - -LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const Connect_Return* ret); - -LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call); - -LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const Reconnect_Return* ret); - -LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, - HCardAndDisposition_Call* call, const char* name); - -LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetStatusChangeA_Call* call); - -LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetStatusChangeW_Call* call); - -LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetStatusChange_Return* ret, BOOL unicode); - -LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call); -LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, const State_Return* ret); - -LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call, - BOOL unicode); - -LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, const Status_Return* ret, - BOOL unicode); - -LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetAttrib_Call* call); - -LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetAttrib_Return* ret, DWORD dwAttrId, - DWORD cbAttrCallLen); - -LONG smartcard_unpack_set_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, - SetAttrib_Call* call); - -LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call); - -LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const Control_Return* ret); - -LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call); - -LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const Transmit_Return* ret); - -LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - LocateCardsByATRA_Call* call); - -LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - LocateCardsByATRW_Call* call); - -LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ReadCacheA_Call* call); - -LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ReadCacheW_Call* call); - -LONG smartcard_pack_read_cache_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const ReadCache_Return* ret); - -LONG smartcard_unpack_write_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - WriteCacheA_Call* call); - -LONG smartcard_unpack_write_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - WriteCacheW_Call* call); - -LONG smartcard_unpack_get_transmit_count_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetTransmitCount_Call* call); -LONG smartcard_pack_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetTransmitCount_Return* call); - -LONG smartcard_unpack_get_reader_icon_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetReaderIcon_Call* call); -LONG smartcard_pack_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetReaderIcon_Return* ret); - -LONG smartcard_unpack_get_device_type_id_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetDeviceTypeId_Call* call); - -LONG smartcard_pack_device_type_id_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetDeviceTypeId_Return* ret); - -#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H */ diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index f2b14dba4..0e77805f0 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -43,6 +43,14 @@ #define RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH 32 #define RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH 4 +#define RDPDR_VERSION_MAJOR 0x0001 + +#define RDPDR_VERSION_MINOR_RDP50 0x0002 +#define RDPDR_VERSION_MINOR_RDP51 0x0005 +#define RDPDR_VERSION_MINOR_RDP52 0x000A +#define RDPDR_VERSION_MINOR_RDP6X 0x000C +#define RDPDR_VERSION_MINOR_RDP10X 0x000D + /* RDPDR_HEADER.Component */ enum RDPDR_CTYP { diff --git a/channels/smartcard/client/smartcard_operations.h b/include/freerdp/channels/scard.h similarity index 87% rename from channels/smartcard/client/smartcard_operations.h rename to include/freerdp/channels/scard.h index 39add1811..2b6aeb3e5 100644 --- a/channels/smartcard/client/smartcard_operations.h +++ b/include/freerdp/channels/scard.h @@ -1,11 +1,9 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * Smartcard Device Service Virtual Channel + * Smartcard Redirection Virtual Channel * - * Copyright 2011 O.S. Systems Software Ltda. - * Copyright 2011 Eduardo Fiss Beloni - * Copyright 2015 Thincast Technologies GmbH - * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2021 Armin Novak + * Copyright 2021 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +18,11 @@ * limitations under the License. */ -#ifndef FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H -#define FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H +#ifndef FREERDP_CHANNEL_SCARD_H +#define FREERDP_CHANNEL_SCARD_H #include +#include #define RDP_SCARD_CTL_CODE(code) \ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, (code), METHOD_BUFFERED, FILE_ANY_ACCESS) @@ -493,54 +492,4 @@ typedef struct _WriteCacheW_Call /* [string] */ WCHAR* szLookupName; } WriteCacheW_Call; -struct _SMARTCARD_OPERATION -{ - IRP* irp; - union - { - Handles_Call handles; - Long_Call lng; - Context_Call context; - ContextAndStringA_Call contextAndStringA; - ContextAndStringW_Call contextAndStringW; - ContextAndTwoStringA_Call contextAndTwoStringA; - ContextAndTwoStringW_Call contextAndTwoStringW; - EstablishContext_Call establishContext; - ListReaderGroups_Call listReaderGroups; - ListReaders_Call listReaders; - GetStatusChangeA_Call getStatusChangeA; - LocateCardsA_Call locateCardsA; - LocateCardsW_Call locateCardsW; - LocateCards_ATRMask locateCardsATRMask; - LocateCardsByATRA_Call locateCardsByATRA; - LocateCardsByATRW_Call locateCardsByATRW; - GetStatusChangeW_Call getStatusChangeW; - GetReaderIcon_Call getReaderIcon; - GetDeviceTypeId_Call getDeviceTypeId; - Connect_Common_Call connect; - ConnectA_Call connectA; - ConnectW_Call connectW; - Reconnect_Call reconnect; - HCardAndDisposition_Call hCardAndDisposition; - State_Call state; - Status_Call status; - SCardIO_Request scardIO; - Transmit_Call transmit; - GetTransmitCount_Call getTransmitCount; - Control_Call control; - GetAttrib_Call getAttrib; - SetAttrib_Call setAttrib; - ReadCache_Common readCache; - ReadCacheA_Call readCacheA; - ReadCacheW_Call readCacheW; - WriteCache_Common writeCache; - WriteCacheA_Call writeCacheA; - WriteCacheW_Call writeCacheW; - } call; - UINT32 ioControlCode; - SCARDCONTEXT hContext; - SCARDHANDLE hCard; -}; -typedef struct _SMARTCARD_OPERATION SMARTCARD_OPERATION; - -#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_OPERATIONS_H */ +#endif /* FREERDP_CHANNEL_SCARD_H */ diff --git a/include/freerdp/utils/rdpdr_utils.h b/include/freerdp/utils/rdpdr_utils.h new file mode 100644 index 000000000..e0711f0e4 --- /dev/null +++ b/include/freerdp/utils/rdpdr_utils.h @@ -0,0 +1,41 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * RDPDR utility functions + * + * Copyright 2021 Armin Novak + * Copyright 2021 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_UTILS_RDPDR_H +#define FREERDP_UTILS_RDPDR_H + +#include +#include + +FREERDP_API const char* rdpdr_component_string(UINT16 component); +FREERDP_API const char* rdpdr_packetid_string(UINT16 packetid); +FREERDP_API const char* rdpdr_irp_string(UINT32 major); +FREERDP_API const char* rdpdr_cap_type_string(UINT16 capability); + +FREERDP_API LONG scard_log_status_error(const char* tag, const char* what, LONG status); +FREERDP_API const char* scard_get_ioctl_string(UINT32 ioControlCode, BOOL funcName); + +FREERDP_API BOOL rdpdr_write_iocompletion_header(wStream* out, UINT32 DeviceId, UINT32 CompletionId, + UINT32 ioStatus); + +FREERDP_API void rdpdr_dump_received_packet(wStream* out, const char* custom); +FREERDP_API void rdpdr_dump_send_packet(wStream* out, const char* custom); + +#endif diff --git a/include/freerdp/utils/smartcard_call.h b/include/freerdp/utils/smartcard_call.h new file mode 100644 index 000000000..2467a14f3 --- /dev/null +++ b/include/freerdp/utils/smartcard_call.h @@ -0,0 +1,54 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Smartcard Device Service Virtual Channel + * + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Eduardo Fiss Beloni + * Copyright 2015 Thincast Technologies GmbH + * Copyright 2015 DI (FH) Martin Haimberger + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SMARTCARD_CALL_H +#define FREERDP_CHANNEL_SMARTCARD_CALL_H + +#include +#include + +#include +#include +#include +#include + +typedef struct _scard_call_context scard_call_context; + +FREERDP_API scard_call_context* smartcard_call_context_new(const rdpSettings* settings); +FREERDP_API void smartcard_call_context_free(scard_call_context* ctx); +FREERDP_API BOOL smartcard_call_context_signal_stop(scard_call_context* ctx); +FREERDP_API BOOL smartcard_call_context_add(scard_call_context* ctx, const char* name); +FREERDP_API BOOL smartcard_call_cancel_context(scard_call_context* ctx, SCARDCONTEXT context); +FREERDP_API BOOL smartcard_call_cancel_all_context(scard_call_context* ctx); +FREERDP_API BOOL smartcard_call_release_context(scard_call_context* ctx, SCARDCONTEXT context); +FREERDP_API BOOL smartcard_call_is_configured(scard_call_context* ctx); + +FREERDP_API BOOL smarcard_call_set_callbacks(scard_call_context* ctx, void* userdata, + void* (*fn_new)(void*, SCARDCONTEXT), + void (*fn_free)(void*)); +FREERDP_API void* smartcard_call_get_context(scard_call_context* ctx, SCARDCONTEXT hContext); + +FREERDP_API LONG smartcard_irp_device_control_call(scard_call_context* context, wStream* out, + UINT32* pIoStatus, + SMARTCARD_OPERATION* operation); + +#endif /* FREERDP_CHANNEL_SMARTCARD_CALL_H */ diff --git a/include/freerdp/utils/smartcard_operations.h b/include/freerdp/utils/smartcard_operations.h new file mode 100644 index 000000000..310902b46 --- /dev/null +++ b/include/freerdp/utils/smartcard_operations.h @@ -0,0 +1,89 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Smartcard Device Service Virtual Channel + * + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Eduardo Fiss Beloni + * Copyright 2015 Thincast Technologies GmbH + * Copyright 2015 DI (FH) Martin Haimberger + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H +#define FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H + +#include +#include +#include + +#include +#include + +struct _SMARTCARD_OPERATION +{ + union + { + Handles_Call handles; + Long_Call lng; + Context_Call context; + ContextAndStringA_Call contextAndStringA; + ContextAndStringW_Call contextAndStringW; + ContextAndTwoStringA_Call contextAndTwoStringA; + ContextAndTwoStringW_Call contextAndTwoStringW; + EstablishContext_Call establishContext; + ListReaderGroups_Call listReaderGroups; + ListReaders_Call listReaders; + GetStatusChangeA_Call getStatusChangeA; + LocateCardsA_Call locateCardsA; + LocateCardsW_Call locateCardsW; + LocateCards_ATRMask locateCardsATRMask; + LocateCardsByATRA_Call locateCardsByATRA; + LocateCardsByATRW_Call locateCardsByATRW; + GetStatusChangeW_Call getStatusChangeW; + GetReaderIcon_Call getReaderIcon; + GetDeviceTypeId_Call getDeviceTypeId; + Connect_Common_Call connect; + ConnectA_Call connectA; + ConnectW_Call connectW; + Reconnect_Call reconnect; + HCardAndDisposition_Call hCardAndDisposition; + State_Call state; + Status_Call status; + SCardIO_Request scardIO; + Transmit_Call transmit; + GetTransmitCount_Call getTransmitCount; + Control_Call control; + GetAttrib_Call getAttrib; + SetAttrib_Call setAttrib; + ReadCache_Common readCache; + ReadCacheA_Call readCacheA; + ReadCacheW_Call readCacheW; + WriteCache_Common writeCache; + WriteCacheA_Call writeCacheA; + WriteCacheW_Call writeCacheW; + } call; + UINT32 ioControlCode; + UINT32 completionID; + UINT32 deviceID; + SCARDCONTEXT hContext; + SCARDHANDLE hCard; + const char* ioControlCodeName; +}; +typedef struct _SMARTCARD_OPERATION SMARTCARD_OPERATION; + +FREERDP_API LONG smartcard_irp_device_control_decode(wStream* s, UINT32 CompletionId, UINT32 FileId, + SMARTCARD_OPERATION* operation); +FREERDP_API void smartcard_operation_free(SMARTCARD_OPERATION* op, BOOL allocated); + +#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_OPERATIONS_H */ diff --git a/include/freerdp/utils/smartcard_pack.h b/include/freerdp/utils/smartcard_pack.h new file mode 100644 index 000000000..fa342cd90 --- /dev/null +++ b/include/freerdp/utils/smartcard_pack.h @@ -0,0 +1,168 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Smart Card Structure Packing + * + * Copyright 2014 Marc-Andre Moreau + * Copyright 2015 Thincast Technologies GmbH + * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2020 Armin Novak + * Copyright 2020 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H +#define FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H + +#include +#include +#include + +#include +#include + +#define SMARTCARD_COMMON_TYPE_HEADER_LENGTH 8 +#define SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH 8 + +FREERDP_API LONG smartcard_pack_write_size_align(wStream* s, size_t size, UINT32 alignment); +FREERDP_API LONG smartcard_unpack_read_size_align(wStream* s, size_t size, UINT32 alignment); + +FREERDP_API SCARDCONTEXT smartcard_scard_context_native_from_redir(REDIR_SCARDCONTEXT* context); +FREERDP_API void smartcard_scard_context_native_to_redir(REDIR_SCARDCONTEXT* context, + SCARDCONTEXT hContext); + +FREERDP_API SCARDHANDLE smartcard_scard_handle_native_from_redir(REDIR_SCARDHANDLE* handle); +FREERDP_API void smartcard_scard_handle_native_to_redir(REDIR_SCARDHANDLE* handle, + SCARDHANDLE hCard); + +FREERDP_API LONG smartcard_unpack_common_type_header(wStream* s); +FREERDP_API void smartcard_pack_common_type_header(wStream* s); + +FREERDP_API LONG smartcard_unpack_private_type_header(wStream* s); +FREERDP_API void smartcard_pack_private_type_header(wStream* s, UINT32 objectBufferLength); + +FREERDP_API LONG smartcard_unpack_establish_context_call(wStream* s, EstablishContext_Call* call); + +FREERDP_API LONG smartcard_pack_establish_context_return(wStream* s, + const EstablishContext_Return* ret); + +FREERDP_API LONG smartcard_unpack_context_call(wStream* s, Context_Call* call, const char* name); + +FREERDP_API void smartcard_trace_long_return(const Long_Return* ret, const char* name); + +FREERDP_API LONG smartcard_unpack_list_reader_groups_call(wStream* s, ListReaderGroups_Call* call, + BOOL unicode); + +FREERDP_API LONG smartcard_pack_list_reader_groups_return(wStream* s, + const ListReaderGroups_Return* ret, + BOOL unicode); + +FREERDP_API LONG smartcard_unpack_list_readers_call(wStream* s, ListReaders_Call* call, + BOOL unicode); + +FREERDP_API LONG smartcard_pack_list_readers_return(wStream* s, const ListReaders_Return* ret, + BOOL unicode); + +FREERDP_API LONG smartcard_unpack_context_and_two_strings_a_call(wStream* s, + ContextAndTwoStringA_Call* call); + +FREERDP_API LONG smartcard_unpack_context_and_two_strings_w_call(wStream* s, + ContextAndTwoStringW_Call* call); + +FREERDP_API LONG smartcard_unpack_context_and_string_a_call(wStream* s, + ContextAndStringA_Call* call); + +FREERDP_API LONG smartcard_unpack_context_and_string_w_call(wStream* s, + ContextAndStringW_Call* call); + +FREERDP_API LONG smartcard_unpack_locate_cards_a_call(wStream* s, LocateCardsA_Call* call); + +FREERDP_API LONG smartcard_pack_locate_cards_return(wStream* s, const LocateCards_Return* ret); + +FREERDP_API LONG smartcard_unpack_locate_cards_w_call(wStream* s, LocateCardsW_Call* call); + +FREERDP_API LONG smartcard_pack_locate_cards_w_return(wStream* s, const LocateCardsW_Call* ret); + +FREERDP_API LONG smartcard_unpack_connect_a_call(wStream* s, ConnectA_Call* call); + +FREERDP_API LONG smartcard_unpack_connect_w_call(wStream* s, ConnectW_Call* call); + +FREERDP_API LONG smartcard_pack_connect_return(wStream* s, const Connect_Return* ret); + +FREERDP_API LONG smartcard_unpack_reconnect_call(wStream* s, Reconnect_Call* call); + +FREERDP_API LONG smartcard_pack_reconnect_return(wStream* s, const Reconnect_Return* ret); + +FREERDP_API LONG smartcard_unpack_hcard_and_disposition_call(wStream* s, + HCardAndDisposition_Call* call, + const char* name); + +FREERDP_API LONG smartcard_unpack_get_status_change_a_call(wStream* s, GetStatusChangeA_Call* call); + +FREERDP_API LONG smartcard_unpack_get_status_change_w_call(wStream* s, GetStatusChangeW_Call* call); + +FREERDP_API LONG smartcard_pack_get_status_change_return(wStream* s, + const GetStatusChange_Return* ret, + BOOL unicode); + +FREERDP_API LONG smartcard_unpack_state_call(wStream* s, State_Call* call); +FREERDP_API LONG smartcard_pack_state_return(wStream* s, const State_Return* ret); + +FREERDP_API LONG smartcard_unpack_status_call(wStream* s, Status_Call* call, BOOL unicode); + +FREERDP_API LONG smartcard_pack_status_return(wStream* s, const Status_Return* ret, BOOL unicode); + +FREERDP_API LONG smartcard_unpack_get_attrib_call(wStream* s, GetAttrib_Call* call); + +FREERDP_API LONG smartcard_pack_get_attrib_return(wStream* s, const GetAttrib_Return* ret, + DWORD dwAttrId, DWORD cbAttrCallLen); + +FREERDP_API LONG smartcard_unpack_set_attrib_call(wStream* s, SetAttrib_Call* call); + +FREERDP_API LONG smartcard_unpack_control_call(wStream* s, Control_Call* call); + +FREERDP_API LONG smartcard_pack_control_return(wStream* s, const Control_Return* ret); + +FREERDP_API LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call); + +FREERDP_API LONG smartcard_pack_transmit_return(wStream* s, const Transmit_Return* ret); + +FREERDP_API LONG smartcard_unpack_locate_cards_by_atr_a_call(wStream* s, + LocateCardsByATRA_Call* call); + +FREERDP_API LONG smartcard_unpack_locate_cards_by_atr_w_call(wStream* s, + LocateCardsByATRW_Call* call); + +FREERDP_API LONG smartcard_unpack_read_cache_a_call(wStream* s, ReadCacheA_Call* call); + +FREERDP_API LONG smartcard_unpack_read_cache_w_call(wStream* s, ReadCacheW_Call* call); + +FREERDP_API LONG smartcard_pack_read_cache_return(wStream* s, const ReadCache_Return* ret); + +FREERDP_API LONG smartcard_unpack_write_cache_a_call(wStream* s, WriteCacheA_Call* call); + +FREERDP_API LONG smartcard_unpack_write_cache_w_call(wStream* s, WriteCacheW_Call* call); + +FREERDP_API LONG smartcard_unpack_get_transmit_count_call(wStream* s, GetTransmitCount_Call* call); +FREERDP_API LONG smartcard_pack_get_transmit_count_return(wStream* s, + const GetTransmitCount_Return* call); + +FREERDP_API LONG smartcard_unpack_get_reader_icon_call(wStream* s, GetReaderIcon_Call* call); +FREERDP_API LONG smartcard_pack_get_reader_icon_return(wStream* s, const GetReaderIcon_Return* ret); + +FREERDP_API LONG smartcard_unpack_get_device_type_id_call(wStream* s, GetDeviceTypeId_Call* call); + +FREERDP_API LONG smartcard_pack_device_type_id_return(wStream* s, + const GetDeviceTypeId_Return* ret); + +#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H */ diff --git a/libfreerdp/utils/CMakeLists.txt b/libfreerdp/utils/CMakeLists.txt index e3a8981d8..2d02ac1fa 100644 --- a/libfreerdp/utils/CMakeLists.txt +++ b/libfreerdp/utils/CMakeLists.txt @@ -20,10 +20,14 @@ set(MODULE_PREFIX "FREERDP_UTILS") set(${MODULE_PREFIX}_SRCS passphrase.c + rdpdr_utils.c pcap.c profiler.c ringbuffer.c signal.c + smartcard_operations.c + smartcard_pack.c + smartcard_call.c stopwatch.c) freerdp_module_add(${${MODULE_PREFIX}_SRCS}) diff --git a/libfreerdp/utils/rdpdr_utils.c b/libfreerdp/utils/rdpdr_utils.c new file mode 100644 index 000000000..db8634d70 --- /dev/null +++ b/libfreerdp/utils/rdpdr_utils.c @@ -0,0 +1,416 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * SCard utility functions + * + * Copyright 2021 Armin Novak + * Copyright 2021 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include + +#include +#define TAG FREERDP_TAG("utils.scard") + +LONG scard_log_status_error(const char* tag, const char* what, LONG status) +{ + if (status != SCARD_S_SUCCESS) + { + DWORD level = WLOG_ERROR; + switch (status) + { + case SCARD_E_TIMEOUT: + level = WLOG_DEBUG; + break; + case SCARD_E_NO_READERS_AVAILABLE: + level = WLOG_INFO; + break; + default: + break; + } + WLog_Print(WLog_Get(tag), level, "%s failed with error %s [%" PRId32 "]", what, + SCardGetErrorString(status), status); + } + return status; +} + +const char* scard_get_ioctl_string(UINT32 ioControlCode, BOOL funcName) +{ + switch (ioControlCode) + { + case SCARD_IOCTL_ESTABLISHCONTEXT: + return funcName ? "SCardEstablishContext" : "SCARD_IOCTL_ESTABLISHCONTEXT"; + + case SCARD_IOCTL_RELEASECONTEXT: + return funcName ? "SCardReleaseContext" : "SCARD_IOCTL_RELEASECONTEXT"; + + case SCARD_IOCTL_ISVALIDCONTEXT: + return funcName ? "SCardIsValidContext" : "SCARD_IOCTL_ISVALIDCONTEXT"; + + case SCARD_IOCTL_LISTREADERGROUPSA: + return funcName ? "SCardListReaderGroupsA" : "SCARD_IOCTL_LISTREADERGROUPSA"; + + case SCARD_IOCTL_LISTREADERGROUPSW: + return funcName ? "SCardListReaderGroupsW" : "SCARD_IOCTL_LISTREADERGROUPSW"; + + case SCARD_IOCTL_LISTREADERSA: + return funcName ? "SCardListReadersA" : "SCARD_IOCTL_LISTREADERSA"; + + case SCARD_IOCTL_LISTREADERSW: + return funcName ? "SCardListReadersW" : "SCARD_IOCTL_LISTREADERSW"; + + case SCARD_IOCTL_INTRODUCEREADERGROUPA: + return funcName ? "SCardIntroduceReaderGroupA" : "SCARD_IOCTL_INTRODUCEREADERGROUPA"; + + case SCARD_IOCTL_INTRODUCEREADERGROUPW: + return funcName ? "SCardIntroduceReaderGroupW" : "SCARD_IOCTL_INTRODUCEREADERGROUPW"; + + case SCARD_IOCTL_FORGETREADERGROUPA: + return funcName ? "SCardForgetReaderGroupA" : "SCARD_IOCTL_FORGETREADERGROUPA"; + + case SCARD_IOCTL_FORGETREADERGROUPW: + return funcName ? "SCardForgetReaderGroupW" : "SCARD_IOCTL_FORGETREADERGROUPW"; + + case SCARD_IOCTL_INTRODUCEREADERA: + return funcName ? "SCardIntroduceReaderA" : "SCARD_IOCTL_INTRODUCEREADERA"; + + case SCARD_IOCTL_INTRODUCEREADERW: + return funcName ? "SCardIntroduceReaderW" : "SCARD_IOCTL_INTRODUCEREADERW"; + + case SCARD_IOCTL_FORGETREADERA: + return funcName ? "SCardForgetReaderA" : "SCARD_IOCTL_FORGETREADERA"; + + case SCARD_IOCTL_FORGETREADERW: + return funcName ? "SCardForgetReaderW" : "SCARD_IOCTL_FORGETREADERW"; + + case SCARD_IOCTL_ADDREADERTOGROUPA: + return funcName ? "SCardAddReaderToGroupA" : "SCARD_IOCTL_ADDREADERTOGROUPA"; + + case SCARD_IOCTL_ADDREADERTOGROUPW: + return funcName ? "SCardAddReaderToGroupW" : "SCARD_IOCTL_ADDREADERTOGROUPW"; + + case SCARD_IOCTL_REMOVEREADERFROMGROUPA: + return funcName ? "SCardRemoveReaderFromGroupA" : "SCARD_IOCTL_REMOVEREADERFROMGROUPA"; + + case SCARD_IOCTL_REMOVEREADERFROMGROUPW: + return funcName ? "SCardRemoveReaderFromGroupW" : "SCARD_IOCTL_REMOVEREADERFROMGROUPW"; + + case SCARD_IOCTL_LOCATECARDSA: + return funcName ? "SCardLocateCardsA" : "SCARD_IOCTL_LOCATECARDSA"; + + case SCARD_IOCTL_LOCATECARDSW: + return funcName ? "SCardLocateCardsW" : "SCARD_IOCTL_LOCATECARDSW"; + + case SCARD_IOCTL_GETSTATUSCHANGEA: + return funcName ? "SCardGetStatusChangeA" : "SCARD_IOCTL_GETSTATUSCHANGEA"; + + case SCARD_IOCTL_GETSTATUSCHANGEW: + return funcName ? "SCardGetStatusChangeW" : "SCARD_IOCTL_GETSTATUSCHANGEW"; + + case SCARD_IOCTL_CANCEL: + return funcName ? "SCardCancel" : "SCARD_IOCTL_CANCEL"; + + case SCARD_IOCTL_CONNECTA: + return funcName ? "SCardConnectA" : "SCARD_IOCTL_CONNECTA"; + + case SCARD_IOCTL_CONNECTW: + return funcName ? "SCardConnectW" : "SCARD_IOCTL_CONNECTW"; + + case SCARD_IOCTL_RECONNECT: + return funcName ? "SCardReconnect" : "SCARD_IOCTL_RECONNECT"; + + case SCARD_IOCTL_DISCONNECT: + return funcName ? "SCardDisconnect" : "SCARD_IOCTL_DISCONNECT"; + + case SCARD_IOCTL_BEGINTRANSACTION: + return funcName ? "SCardBeginTransaction" : "SCARD_IOCTL_BEGINTRANSACTION"; + + case SCARD_IOCTL_ENDTRANSACTION: + return funcName ? "SCardEndTransaction" : "SCARD_IOCTL_ENDTRANSACTION"; + + case SCARD_IOCTL_STATE: + return funcName ? "SCardState" : "SCARD_IOCTL_STATE"; + + case SCARD_IOCTL_STATUSA: + return funcName ? "SCardStatusA" : "SCARD_IOCTL_STATUSA"; + + case SCARD_IOCTL_STATUSW: + return funcName ? "SCardStatusW" : "SCARD_IOCTL_STATUSW"; + + case SCARD_IOCTL_TRANSMIT: + return funcName ? "SCardTransmit" : "SCARD_IOCTL_TRANSMIT"; + + case SCARD_IOCTL_CONTROL: + return funcName ? "SCardControl" : "SCARD_IOCTL_CONTROL"; + + case SCARD_IOCTL_GETATTRIB: + return funcName ? "SCardGetAttrib" : "SCARD_IOCTL_GETATTRIB"; + + case SCARD_IOCTL_SETATTRIB: + return funcName ? "SCardSetAttrib" : "SCARD_IOCTL_SETATTRIB"; + + case SCARD_IOCTL_ACCESSSTARTEDEVENT: + return funcName ? "SCardAccessStartedEvent" : "SCARD_IOCTL_ACCESSSTARTEDEVENT"; + + case SCARD_IOCTL_LOCATECARDSBYATRA: + return funcName ? "SCardLocateCardsByATRA" : "SCARD_IOCTL_LOCATECARDSBYATRA"; + + case SCARD_IOCTL_LOCATECARDSBYATRW: + return funcName ? "SCardLocateCardsByATRB" : "SCARD_IOCTL_LOCATECARDSBYATRW"; + + case SCARD_IOCTL_READCACHEA: + return funcName ? "SCardReadCacheA" : "SCARD_IOCTL_READCACHEA"; + + case SCARD_IOCTL_READCACHEW: + return funcName ? "SCardReadCacheW" : "SCARD_IOCTL_READCACHEW"; + + case SCARD_IOCTL_WRITECACHEA: + return funcName ? "SCardWriteCacheA" : "SCARD_IOCTL_WRITECACHEA"; + + case SCARD_IOCTL_WRITECACHEW: + return funcName ? "SCardWriteCacheW" : "SCARD_IOCTL_WRITECACHEW"; + + case SCARD_IOCTL_GETTRANSMITCOUNT: + return funcName ? "SCardGetTransmitCount" : "SCARD_IOCTL_GETTRANSMITCOUNT"; + + case SCARD_IOCTL_RELEASETARTEDEVENT: + return funcName ? "SCardReleaseStartedEvent" : "SCARD_IOCTL_RELEASETARTEDEVENT"; + + case SCARD_IOCTL_GETREADERICON: + return funcName ? "SCardGetReaderIcon" : "SCARD_IOCTL_GETREADERICON"; + + case SCARD_IOCTL_GETDEVICETYPEID: + return funcName ? "SCardGetDeviceTypeId" : "SCARD_IOCTL_GETDEVICETYPEID"; + + default: + return funcName ? "SCardUnknown" : "SCARD_IOCTL_UNKNOWN"; + } +} + +const char* rdpdr_component_string(UINT16 component) +{ + switch (component) + { + case RDPDR_CTYP_PRN: + return "RDPDR_CTYP_PRN"; + case RDPDR_CTYP_CORE: + return "RDPDR_CTYP_CORE"; + default: + return "UNKNOWN"; + } +} + +const char* rdpdr_packetid_string(UINT16 packetid) +{ + switch (packetid) + { + case PAKID_CORE_SERVER_ANNOUNCE: + return "PAKID_CORE_SERVER_ANNOUNCE"; + case PAKID_CORE_CLIENTID_CONFIRM: + return "PAKID_CORE_CLIENTID_CONFIRM"; + case PAKID_CORE_CLIENT_NAME: + return "PAKID_CORE_CLIENT_NAME"; + case PAKID_CORE_DEVICELIST_ANNOUNCE: + return "PAKID_CORE_DEVICELIST_ANNOUNCE"; + case PAKID_CORE_DEVICE_REPLY: + return "PAKID_CORE_DEVICE_REPLY"; + case PAKID_CORE_DEVICE_IOREQUEST: + return "PAKID_CORE_DEVICE_IOREQUEST"; + case PAKID_CORE_DEVICE_IOCOMPLETION: + return "PAKID_CORE_DEVICE_IOCOMPLETION"; + case PAKID_CORE_SERVER_CAPABILITY: + return "PAKID_CORE_SERVER_CAPABILITY"; + case PAKID_CORE_CLIENT_CAPABILITY: + return "PAKID_CORE_CLIENT_CAPABILITY"; + case PAKID_CORE_DEVICELIST_REMOVE: + return "PAKID_CORE_DEVICELIST_REMOVE"; + case PAKID_CORE_USER_LOGGEDON: + return "PAKID_CORE_USER_LOGGEDON"; + case PAKID_PRN_CACHE_DATA: + return "PAKID_PRN_CACHE_DATA"; + case PAKID_PRN_USING_XPS: + return "PAKID_PRN_USING_XPS"; + default: + return "UNKNOWN"; + } +} + +BOOL rdpdr_write_iocompletion_header(wStream* out, UINT32 DeviceId, UINT32 CompletionId, + UINT32 ioStatus) +{ + WINPR_ASSERT(out); + Stream_SetPosition(out, 0); + if (!Stream_EnsureRemainingCapacity(out, 16)) + return FALSE; + Stream_Write_UINT16(out, RDPDR_CTYP_CORE); /* Component (2 bytes) */ + Stream_Write_UINT16(out, PAKID_CORE_DEVICE_IOCOMPLETION); /* PacketId (2 bytes) */ + Stream_Write_UINT32(out, DeviceId); /* DeviceId (4 bytes) */ + Stream_Write_UINT32(out, CompletionId); /* CompletionId (4 bytes) */ + Stream_Write_UINT32(out, ioStatus); /* IoStatus (4 bytes) */ + + return TRUE; +} + +void rdpdr_dump_received_packet(wStream* s, const char* custom) +{ + const size_t pos = Stream_GetPosition(s); + Stream_SetPosition(s, 0); + if (Stream_Length(s) >= 4) + { + BOOL done = FALSE; + UINT16 component, packetid; + UINT32 deviceID = 0; + UINT32 FileId = 0; + UINT32 CompletionId = 0; + UINT32 MajorFunction = 0; + UINT32 MinorFunction = 0; + const size_t pos = Stream_GetPosition(s); + + Stream_Read_UINT16(s, component); + Stream_Read_UINT16(s, packetid); + if (Stream_GetRemainingLength(s) >= 4) + Stream_Read_UINT32(s, deviceID); + if (component == RDPDR_CTYP_CORE) + { + if (packetid == PAKID_CORE_DEVICE_IOREQUEST) + { + if (Stream_GetRemainingLength(s) >= 16) + { + Stream_Read_UINT32(s, FileId); /* FileId (4 bytes) */ + Stream_Read_UINT32(s, CompletionId); /* CompletionId (4 bytes) */ + Stream_Read_UINT32(s, MajorFunction); /* MajorFunction (4 bytes) */ + Stream_Read_UINT32(s, MinorFunction); /* MinorFunction (4 bytes) */ + + WLog_DBG(TAG, + "[%s] receive [%s | %s] [0x%08" PRIx32 "] FileID=0x%08" PRIx32 + ", CompletionID=0x%08" PRIx32 ", MajorFunction=%s [0x%08" PRIx32 + "] -> %" PRIuz, + custom, rdpdr_component_string(component), + rdpdr_packetid_string(packetid), deviceID, FileId, CompletionId, + rdpdr_irp_string(MajorFunction), MinorFunction, deviceID, + Stream_Length(s)); + done = TRUE; + } + } + } + Stream_SetPosition(s, pos); + + if (!done) + { + WLog_DBG(TAG, "[%s] receive [%s | %s] [0x%08" PRIx32 "] -> %" PRIuz, custom, + rdpdr_component_string(component), rdpdr_packetid_string(packetid), deviceID, + Stream_Length(s)); + } + winpr_HexDump(TAG, WLOG_TRACE, Stream_Buffer(s), Stream_Length(s)); + } + + Stream_SetPosition(s, pos); +} + +void rdpdr_dump_send_packet(wStream* s, const char* custom) +{ + WINPR_ASSERT(s); + + if (Stream_Length(s) >= 8) + { + UINT16 component, packetid; + UINT32 deviceID; + const size_t pos = Stream_GetPosition(s); + Stream_SetPosition(s, 0); + + Stream_Read_UINT16(s, component); + Stream_Read_UINT16(s, packetid); + Stream_Read_UINT32(s, deviceID); + switch (packetid) + { + case PAKID_CORE_DEVICE_IOCOMPLETION: + { + UINT32 completionID, ioStatus; + Stream_Read_UINT32(s, completionID); + Stream_Read_UINT32(s, ioStatus); + + WLog_DBG(TAG, + "[%s] sending [%s | %s] [0x%08" PRIx32 "] completionID=0x%08" PRIx32 + ", ioStatus=0x%08" PRIx32 " -> %" PRIuz, + custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid), + deviceID, completionID, ioStatus, pos); + } + break; + default: + WLog_DBG(TAG, "[%s] sending [%s | %s] [0x%08" PRIx32 "] -> %" PRIuz, custom, + rdpdr_component_string(component), rdpdr_packetid_string(packetid), + deviceID, pos); + break; + } + + winpr_HexDump(TAG, WLOG_TRACE, Stream_Buffer(s), pos); + Stream_SetPosition(s, pos); + } +} + +const char* rdpdr_irp_string(UINT32 major) +{ + switch (major) + { + case IRP_MJ_CREATE: + return "IRP_MJ_CREATE"; + case IRP_MJ_CLOSE: + return "IRP_MJ_CLOSE"; + case IRP_MJ_READ: + return "IRP_MJ_READ"; + case IRP_MJ_WRITE: + return "IRP_MJ_WRITE"; + case IRP_MJ_DEVICE_CONTROL: + return "IRP_MJ_DEVICE_CONTROL"; + case IRP_MJ_QUERY_VOLUME_INFORMATION: + return "IRP_MJ_QUERY_VOLUME_INFORMATION"; + case IRP_MJ_SET_VOLUME_INFORMATION: + return "IRP_MJ_SET_VOLUME_INFORMATION"; + case IRP_MJ_QUERY_INFORMATION: + return "IRP_MJ_QUERY_INFORMATION"; + case IRP_MJ_SET_INFORMATION: + return "IRP_MJ_SET_INFORMATION"; + case IRP_MJ_DIRECTORY_CONTROL: + return "IRP_MJ_DIRECTORY_CONTROL"; + case IRP_MJ_LOCK_CONTROL: + return "IRP_MJ_LOCK_CONTROL"; + default: + return "IRP_UNKNOWN"; + } +} + +const char* rdpdr_cap_type_string(UINT16 capability) +{ + switch (capability) + { + case CAP_GENERAL_TYPE: + return "CAP_GENERAL_TYPE"; + case CAP_PRINTER_TYPE: + return "CAP_PRINTER_TYPE"; + case CAP_PORT_TYPE: + return "CAP_PORT_TYPE"; + case CAP_DRIVE_TYPE: + return "CAP_DRIVE_TYPE"; + case CAP_SMARTCARD_TYPE: + return "CAP_SMARTCARD_TYPE"; + default: + return "CAP_UNKNOWN"; + } +} diff --git a/libfreerdp/utils/smartcard_call.c b/libfreerdp/utils/smartcard_call.c new file mode 100644 index 000000000..97f50f2bc --- /dev/null +++ b/libfreerdp/utils/smartcard_call.c @@ -0,0 +1,1950 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Smartcard Device Service Virtual Channel + * + * Copyright (C) Alexi Volkov 2006 + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Anthony Tong + * Copyright 2015 Thincast Technologies GmbH + * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2017 Armin Novak + * Copyright 2017 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#define TAG FREERDP_TAG("utils.smartcard.call") + +#if defined(WITH_SMARTCARD_EMULATE) +#include + +#define str(x) #x +#define wrap(ctx, fkt, ...) Emulate_##fkt(ctx->emulation, ##__VA_ARGS__) +#else +#define wrap(ctx, fkt, ...) fkt(__VA_ARGS__) +#endif + +#define SCARD_MAX_TIMEOUT 60000 + +struct _scard_call_context +{ + HANDLE StartedEvent; + wLinkedList* names; + wHashTable* rgSCardContextList; +#if defined(WITH_SMARTCARD_EMULATE) + SmartcardEmulationContext* emulation; +#endif + HANDLE stopEvent; + void* userdata; + + void* (*fn_new)(void*, SCARDCONTEXT); + void (*fn_free)(void*); +}; + +struct _scard_context_element +{ + void* context; + void (*fn_free)(void*); +}; + +static LONG smartcard_EstablishContext_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + SCARDCONTEXT hContext = { 0 }; + EstablishContext_Return ret = { 0 }; + EstablishContext_Call* call = &operation->call.establishContext; + status = ret.ReturnCode = + wrap(smartcard, SCardEstablishContext, call->dwScope, NULL, NULL, &hContext); + + if (ret.ReturnCode == SCARD_S_SUCCESS) + { + const void* key = (void*)(size_t)hContext; + struct _scard_context_element* pContext = calloc(1, sizeof(struct _scard_context_element)); + if (!pContext) + return STATUS_NO_MEMORY; + + pContext->fn_free = smartcard->fn_free; + + if (smartcard->fn_new) + { + pContext->context = smartcard->fn_new(smartcard->userdata, hContext); + if (!pContext->context) + { + free(pContext); + return STATUS_NO_MEMORY; + } + } + + if (!pContext) + { + WLog_ERR(TAG, "smartcard_context_new failed!"); + return STATUS_NO_MEMORY; + } + + if (!HashTable_Insert(smartcard->rgSCardContextList, key, (void*)pContext)) + { + WLog_ERR(TAG, "ListDictionary_Add failed!"); + return STATUS_INTERNAL_ERROR; + } + } + else + { + return scard_log_status_error(TAG, "SCardEstablishContext", status); + } + + smartcard_scard_context_native_to_redir(&(ret.hContext), hContext); + + status = smartcard_pack_establish_context_return(out, &ret); + if (status != SCARD_S_SUCCESS) + { + return scard_log_status_error(TAG, "smartcard_pack_establish_context_return", status); + } + + return ret.ReturnCode; +} + +static LONG smartcard_ReleaseContext_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + ret.ReturnCode = wrap(smartcard, SCardReleaseContext, operation->hContext); + + if (ret.ReturnCode == SCARD_S_SUCCESS) + HashTable_Remove(smartcard->rgSCardContextList, (void*)operation->hContext); + else + { + return scard_log_status_error(TAG, "SCardReleaseContext", ret.ReturnCode); + } + + smartcard_trace_long_return(&ret, "ReleaseContext"); + return ret.ReturnCode; +} + +static LONG smartcard_IsValidContext_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + ret.ReturnCode = wrap(smartcard, SCardIsValidContext, operation->hContext); + smartcard_trace_long_return(&ret, "IsValidContext"); + return ret.ReturnCode; +} + +static LONG smartcard_ListReaderGroupsA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ListReaderGroups_Return ret = { 0 }; + LPSTR mszGroups = NULL; + DWORD cchGroups = 0; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + cchGroups = SCARD_AUTOALLOCATE; + ret.ReturnCode = + wrap(smartcard, SCardListReaderGroupsA, operation->hContext, (LPSTR)&mszGroups, &cchGroups); + ret.msz = (BYTE*)mszGroups; + ret.cBytes = cchGroups; + + status = smartcard_pack_list_reader_groups_return(out, &ret, FALSE); + + if (status != SCARD_S_SUCCESS) + return status; + + if (mszGroups) + wrap(smartcard, SCardFreeMemory, operation->hContext, mszGroups); + + return ret.ReturnCode; +} + +static LONG smartcard_ListReaderGroupsW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ListReaderGroups_Return ret = { 0 }; + LPWSTR mszGroups = NULL; + DWORD cchGroups = 0; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + cchGroups = SCARD_AUTOALLOCATE; + status = ret.ReturnCode = wrap(smartcard, SCardListReaderGroupsW, operation->hContext, + (LPWSTR)&mszGroups, &cchGroups); + ret.msz = (BYTE*)mszGroups; + ret.cBytes = cchGroups * sizeof(WCHAR); + + if (status != SCARD_S_SUCCESS) + return status; + + status = smartcard_pack_list_reader_groups_return(out, &ret, TRUE); + + if (status != SCARD_S_SUCCESS) + return status; + + if (mszGroups) + wrap(smartcard, SCardFreeMemory, operation->hContext, mszGroups); + + return ret.ReturnCode; +} + +static BOOL filter_match(wLinkedList* list, LPCSTR reader, size_t readerLen) +{ + if (readerLen < 1) + return FALSE; + + LinkedList_Enumerator_Reset(list); + + while (LinkedList_Enumerator_MoveNext(list)) + { + const char* filter = LinkedList_Enumerator_Current(list); + + if (filter) + { + if (strstr(reader, filter) != NULL) + return TRUE; + } + } + + return FALSE; +} + +static DWORD filter_device_by_name_a(wLinkedList* list, LPSTR* mszReaders, DWORD cchReaders) +{ + size_t rpos = 0, wpos = 0; + + if (*mszReaders == NULL || LinkedList_Count(list) < 1) + return cchReaders; + + do + { + LPCSTR rreader = &(*mszReaders)[rpos]; + LPSTR wreader = &(*mszReaders)[wpos]; + size_t readerLen = strnlen(rreader, cchReaders - rpos); + + rpos += readerLen + 1; + + if (filter_match(list, rreader, readerLen)) + { + if (rreader != wreader) + memmove(wreader, rreader, readerLen + 1); + + wpos += readerLen + 1; + } + } while (rpos < cchReaders); + + /* this string must be double 0 terminated */ + if (rpos != wpos) + { + if (wpos >= cchReaders) + return 0; + + (*mszReaders)[wpos++] = '\0'; + } + + return (DWORD)wpos; +} + +static DWORD filter_device_by_name_w(wLinkedList* list, LPWSTR* mszReaders, DWORD cchReaders) +{ + int res; + DWORD rc; + LPSTR readers = NULL; + + if (LinkedList_Count(list) < 1) + return cchReaders; + + res = ConvertFromUnicode(CP_UTF8, 0, *mszReaders, (int)cchReaders, &readers, 0, NULL, NULL); + + /* When res==0, readers may have been set to NULL by ConvertFromUnicode */ + if ((res < 0) || ((DWORD)res != cchReaders) || (readers == 0)) + { + free(readers); + return 0; + } + + free(*mszReaders); + *mszReaders = NULL; + rc = filter_device_by_name_a(list, &readers, cchReaders); + res = ConvertToUnicode(CP_UTF8, 0, readers, (int)rc, mszReaders, 0); + + if ((res < 0) || ((DWORD)res != rc)) + rc = 0; + + free(readers); + return rc; +} + +static LONG smartcard_ListReadersA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ListReaders_Return ret = { 0 }; + LPSTR mszReaders = NULL; + DWORD cchReaders = 0; + ListReaders_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.listReaders; + cchReaders = SCARD_AUTOALLOCATE; + status = ret.ReturnCode = wrap(smartcard, SCardListReadersA, operation->hContext, + (LPCSTR)call->mszGroups, (LPSTR)&mszReaders, &cchReaders); + + if (status != SCARD_S_SUCCESS) + { + return scard_log_status_error(TAG, "SCardListReadersA", status); + } + + cchReaders = filter_device_by_name_a(smartcard->names, &mszReaders, cchReaders); + ret.msz = (BYTE*)mszReaders; + ret.cBytes = cchReaders; + + status = smartcard_pack_list_readers_return(out, &ret, FALSE); + if (status != SCARD_S_SUCCESS) + { + return scard_log_status_error(TAG, "smartcard_pack_list_readers_return", status); + } + + if (mszReaders) + wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaders); + + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_ListReadersW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ListReaders_Return ret = { 0 }; + DWORD cchReaders = 0; + ListReaders_Call* call; + union + { + const BYTE* bp; + const char* sz; + const WCHAR* wz; + } string; + union + { + WCHAR** ppw; + WCHAR* pw; + CHAR* pc; + BYTE* pb; + } mszReaders; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(operation); + + call = &operation->call.listReaders; + + string.bp = call->mszGroups; + cchReaders = SCARD_AUTOALLOCATE; + status = ret.ReturnCode = wrap(smartcard, SCardListReadersW, operation->hContext, string.wz, + (LPWSTR)&mszReaders.pw, &cchReaders); + + if (status != SCARD_S_SUCCESS) + return scard_log_status_error(TAG, "SCardListReadersW", status); + + cchReaders = filter_device_by_name_w(smartcard->names, &mszReaders.pw, cchReaders); + ret.msz = mszReaders.pb; + ret.cBytes = cchReaders * sizeof(WCHAR); + status = smartcard_pack_list_readers_return(out, &ret, TRUE); + + if (mszReaders.pb) + wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaders.pb); + + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_IntroduceReaderGroupA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndStringA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndStringA; + ret.ReturnCode = wrap(smartcard, SCardIntroduceReaderGroupA, operation->hContext, call->sz); + scard_log_status_error(TAG, "SCardIntroduceReaderGroupA", ret.ReturnCode); + smartcard_trace_long_return(&ret, "IntroduceReaderGroupA"); + return ret.ReturnCode; +} + +static LONG smartcard_IntroduceReaderGroupW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndStringW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndStringW; + ret.ReturnCode = wrap(smartcard, SCardIntroduceReaderGroupW, operation->hContext, call->sz); + scard_log_status_error(TAG, "SCardIntroduceReaderGroupW", ret.ReturnCode); + smartcard_trace_long_return(&ret, "IntroduceReaderGroupW"); + return ret.ReturnCode; +} + +static LONG smartcard_IntroduceReaderA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndTwoStringA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndTwoStringA; + ret.ReturnCode = + wrap(smartcard, SCardIntroduceReaderA, operation->hContext, call->sz1, call->sz2); + scard_log_status_error(TAG, "SCardIntroduceReaderA", ret.ReturnCode); + smartcard_trace_long_return(&ret, "IntroduceReaderA"); + return ret.ReturnCode; +} + +static LONG smartcard_IntroduceReaderW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndTwoStringW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndTwoStringW; + ret.ReturnCode = + wrap(smartcard, SCardIntroduceReaderW, operation->hContext, call->sz1, call->sz2); + scard_log_status_error(TAG, "SCardIntroduceReaderW", ret.ReturnCode); + smartcard_trace_long_return(&ret, "IntroduceReaderW"); + return ret.ReturnCode; +} + +static LONG smartcard_ForgetReaderA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndStringA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndStringA; + ret.ReturnCode = wrap(smartcard, SCardForgetReaderA, operation->hContext, call->sz); + scard_log_status_error(TAG, "SCardForgetReaderA", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SCardForgetReaderA"); + return ret.ReturnCode; +} + +static LONG smartcard_ForgetReaderW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndStringW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndStringW; + ret.ReturnCode = wrap(smartcard, SCardForgetReaderW, operation->hContext, call->sz); + scard_log_status_error(TAG, "SCardForgetReaderW", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SCardForgetReaderW"); + return ret.ReturnCode; +} + +static LONG smartcard_AddReaderToGroupA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndTwoStringA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndTwoStringA; + ret.ReturnCode = + wrap(smartcard, SCardAddReaderToGroupA, operation->hContext, call->sz1, call->sz2); + scard_log_status_error(TAG, "SCardAddReaderToGroupA", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SCardAddReaderToGroupA"); + return ret.ReturnCode; +} + +static LONG smartcard_AddReaderToGroupW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndTwoStringW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndTwoStringW; + ret.ReturnCode = + wrap(smartcard, SCardAddReaderToGroupW, operation->hContext, call->sz1, call->sz2); + scard_log_status_error(TAG, "SCardAddReaderToGroupW", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SCardAddReaderToGroupA"); + return ret.ReturnCode; +} + +static LONG smartcard_RemoveReaderFromGroupA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndTwoStringA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndTwoStringA; + ret.ReturnCode = + wrap(smartcard, SCardRemoveReaderFromGroupA, operation->hContext, call->sz1, call->sz2); + scard_log_status_error(TAG, "SCardRemoveReaderFromGroupA", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SCardRemoveReaderFromGroupA"); + return ret.ReturnCode; +} + +static LONG smartcard_RemoveReaderFromGroupW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + ContextAndTwoStringW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.contextAndTwoStringW; + ret.ReturnCode = + wrap(smartcard, SCardRemoveReaderFromGroupW, operation->hContext, call->sz1, call->sz2); + scard_log_status_error(TAG, "SCardRemoveReaderFromGroupW", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SCardRemoveReaderFromGroupW"); + return ret.ReturnCode; +} + +static LONG smartcard_LocateCardsA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + UINT32 x; + LONG status; + LocateCards_Return ret = { 0 }; + LocateCardsA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(operation); + + call = &operation->call.locateCardsA; + + ret.ReturnCode = wrap(smartcard, SCardLocateCardsA, operation->hContext, call->mszCards, + call->rgReaderStates, call->cReaders); + scard_log_status_error(TAG, "SCardLocateCardsA", ret.ReturnCode); + ret.cReaders = call->cReaders; + ret.rgReaderStates = NULL; + + if (ret.cReaders > 0) + { + ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); + + if (!ret.rgReaderStates) + return STATUS_NO_MEMORY; + } + + for (x = 0; x < ret.cReaders; x++) + { + ret.rgReaderStates[x].dwCurrentState = call->rgReaderStates[x].dwCurrentState; + ret.rgReaderStates[x].dwEventState = call->rgReaderStates[x].dwEventState; + ret.rgReaderStates[x].cbAtr = call->rgReaderStates[x].cbAtr; + CopyMemory(&(ret.rgReaderStates[x].rgbAtr), &(call->rgReaderStates[x].rgbAtr), + sizeof(ret.rgReaderStates[x].rgbAtr)); + } + + status = smartcard_pack_locate_cards_return(out, &ret); + + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_LocateCardsW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + UINT32 x; + LONG status; + LocateCards_Return ret = { 0 }; + LocateCardsW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(operation); + + call = &operation->call.locateCardsW; + + ret.ReturnCode = wrap(smartcard, SCardLocateCardsW, operation->hContext, call->mszCards, + call->rgReaderStates, call->cReaders); + scard_log_status_error(TAG, "SCardLocateCardsW", ret.ReturnCode); + ret.cReaders = call->cReaders; + ret.rgReaderStates = NULL; + + if (ret.cReaders > 0) + { + ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); + + if (!ret.rgReaderStates) + return STATUS_NO_MEMORY; + } + + for (x = 0; x < ret.cReaders; x++) + { + ret.rgReaderStates[x].dwCurrentState = call->rgReaderStates[x].dwCurrentState; + ret.rgReaderStates[x].dwEventState = call->rgReaderStates[x].dwEventState; + ret.rgReaderStates[x].cbAtr = call->rgReaderStates[x].cbAtr; + CopyMemory(&(ret.rgReaderStates[x].rgbAtr), &(call->rgReaderStates[x].rgbAtr), + sizeof(ret.rgReaderStates[x].rgbAtr)); + } + + status = smartcard_pack_locate_cards_return(out, &ret); + + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_ReadCacheA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + BOOL autoalloc; + ReadCache_Return ret = { 0 }; + ReadCacheA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.readCacheA; + autoalloc = (call->Common.cbDataLen == SCARD_AUTOALLOCATE); + + if (!call->Common.fPbDataIsNULL) + { + ret.cbDataLen = call->Common.cbDataLen; + if (!autoalloc) + { + ret.pbData = malloc(ret.cbDataLen); + if (!ret.pbData) + return SCARD_F_INTERNAL_ERROR; + } + } + + if (autoalloc) + ret.ReturnCode = wrap(smartcard, SCardReadCacheA, operation->hContext, + call->Common.CardIdentifier, call->Common.FreshnessCounter, + call->szLookupName, (BYTE*)&ret.pbData, &ret.cbDataLen); + else + ret.ReturnCode = + wrap(smartcard, SCardReadCacheA, operation->hContext, call->Common.CardIdentifier, + call->Common.FreshnessCounter, call->szLookupName, ret.pbData, &ret.cbDataLen); + if ((ret.ReturnCode != SCARD_W_CACHE_ITEM_NOT_FOUND) && + (ret.ReturnCode != SCARD_W_CACHE_ITEM_STALE)) + { + scard_log_status_error(TAG, "SCardReadCacheA", ret.ReturnCode); + } + + status = smartcard_pack_read_cache_return(out, &ret); + if (autoalloc) + wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData); + else + free(ret.pbData); + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_ReadCacheW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ReadCache_Return ret = { 0 }; + ReadCacheW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.readCacheW; + + if (!call->Common.fPbDataIsNULL) + ret.cbDataLen = SCARD_AUTOALLOCATE; + + ret.ReturnCode = + wrap(smartcard, SCardReadCacheW, operation->hContext, call->Common.CardIdentifier, + call->Common.FreshnessCounter, call->szLookupName, (BYTE*)&ret.pbData, &ret.cbDataLen); + + if ((ret.ReturnCode != SCARD_W_CACHE_ITEM_NOT_FOUND) && + (ret.ReturnCode != SCARD_W_CACHE_ITEM_STALE)) + { + scard_log_status_error(TAG, "SCardReadCacheA", ret.ReturnCode); + } + + status = smartcard_pack_read_cache_return(out, &ret); + + wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData); + + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_WriteCacheA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + WriteCacheA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.writeCacheA; + + ret.ReturnCode = wrap(smartcard, SCardWriteCacheA, operation->hContext, + call->Common.CardIdentifier, call->Common.FreshnessCounter, + call->szLookupName, call->Common.pbData, call->Common.cbDataLen); + scard_log_status_error(TAG, "SCardWriteCacheA", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SCardWriteCacheA"); + return ret.ReturnCode; +} + +static LONG smartcard_WriteCacheW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + WriteCacheW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.writeCacheW; + + ret.ReturnCode = wrap(smartcard, SCardWriteCacheW, operation->hContext, + call->Common.CardIdentifier, call->Common.FreshnessCounter, + call->szLookupName, call->Common.pbData, call->Common.cbDataLen); + scard_log_status_error(TAG, "SCardWriteCacheW", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SCardWriteCacheW"); + return ret.ReturnCode; +} + +static LONG smartcard_GetTransmitCount_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + GetTransmitCount_Return ret = { 0 }; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + ret.ReturnCode = wrap(smartcard, SCardGetTransmitCount, operation->hCard, &ret.cTransmitCount); + scard_log_status_error(TAG, "SCardGetTransmitCount", ret.ReturnCode); + status = smartcard_pack_get_transmit_count_return(out, &ret); + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_ReleaseStartedEvent_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + WINPR_UNUSED(smartcard); + WINPR_UNUSED(out); + WINPR_UNUSED(operation); + + WLog_WARN(TAG, "According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules " + "this is not supported?!?"); + return SCARD_E_UNSUPPORTED_FEATURE; +} + +static LONG smartcard_GetReaderIcon_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + GetReaderIcon_Return ret = { 0 }; + GetReaderIcon_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.getReaderIcon; + + ret.cbDataLen = SCARD_AUTOALLOCATE; + ret.ReturnCode = wrap(smartcard, SCardGetReaderIconW, operation->hContext, call->szReaderName, + (LPBYTE)&ret.pbData, &ret.cbDataLen); + scard_log_status_error(TAG, "SCardGetReaderIconW", ret.ReturnCode); + + status = smartcard_pack_get_reader_icon_return(out, &ret); + wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData); + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_GetDeviceTypeId_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + GetDeviceTypeId_Return ret = { 0 }; + GetDeviceTypeId_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.getDeviceTypeId; + + ret.ReturnCode = wrap(smartcard, SCardGetDeviceTypeIdW, operation->hContext, call->szReaderName, + &ret.dwDeviceId); + scard_log_status_error(TAG, "SCardGetDeviceTypeIdW", ret.ReturnCode); + + status = smartcard_pack_device_type_id_return(out, &ret); + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_GetStatusChangeA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status = STATUS_NO_MEMORY; + UINT32 index; + DWORD dwTimeOut, x; + const DWORD dwTimeStep = 100; + GetStatusChange_Return ret = { 0 }; + GetStatusChangeA_Call* call; + LPSCARD_READERSTATEA rgReaderStates = NULL; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.getStatusChangeA; + dwTimeOut = call->dwTimeOut; + if ((dwTimeOut == INFINITE) || (dwTimeOut > SCARD_MAX_TIMEOUT)) + dwTimeOut = SCARD_MAX_TIMEOUT; + + if (call->cReaders > 0) + { + ret.cReaders = call->cReaders; + rgReaderStates = calloc(ret.cReaders, sizeof(SCARD_READERSTATEA)); + ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); + if (!rgReaderStates || !ret.rgReaderStates) + goto fail; + } + + for (x = 0; x < MAX(1, dwTimeOut); x += dwTimeStep) + { + memcpy(rgReaderStates, call->rgReaderStates, call->cReaders * sizeof(SCARD_READERSTATEA)); + ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeA, operation->hContext, + MIN(dwTimeOut, dwTimeStep), rgReaderStates, call->cReaders); + if (ret.ReturnCode != SCARD_E_TIMEOUT) + break; + if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0) + break; + } + scard_log_status_error(TAG, "SCardGetStatusChangeA", ret.ReturnCode); + + for (index = 0; index < ret.cReaders; index++) + { + const SCARD_READERSTATEA* cur = &rgReaderStates[index]; + ReaderState_Return* out = &ret.rgReaderStates[index]; + + out->dwCurrentState = cur->dwCurrentState; + out->dwEventState = cur->dwEventState; + out->cbAtr = cur->cbAtr; + CopyMemory(&(out->rgbAtr), cur->rgbAtr, sizeof(out->rgbAtr)); + } + + status = smartcard_pack_get_status_change_return(out, &ret, TRUE); +fail: + free(ret.rgReaderStates); + free(rgReaderStates); + if (status != SCARD_S_SUCCESS) + return status; + return ret.ReturnCode; +} + +static LONG smartcard_GetStatusChangeW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status = STATUS_NO_MEMORY; + UINT32 index; + DWORD dwTimeOut, x; + const DWORD dwTimeStep = 100; + GetStatusChange_Return ret = { 0 }; + GetStatusChangeW_Call* call; + LPSCARD_READERSTATEW rgReaderStates = NULL; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.getStatusChangeW; + dwTimeOut = call->dwTimeOut; + if ((dwTimeOut == INFINITE) || (dwTimeOut > SCARD_MAX_TIMEOUT)) + dwTimeOut = SCARD_MAX_TIMEOUT; + + if (call->cReaders > 0) + { + ret.cReaders = call->cReaders; + rgReaderStates = calloc(ret.cReaders, sizeof(SCARD_READERSTATEW)); + ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); + if (!rgReaderStates || !ret.rgReaderStates) + goto fail; + } + + for (x = 0; x < MAX(1, dwTimeOut); x += dwTimeStep) + { + memcpy(rgReaderStates, call->rgReaderStates, call->cReaders * sizeof(SCARD_READERSTATEW)); + { + ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeW, operation->hContext, + MIN(dwTimeOut, dwTimeStep), rgReaderStates, call->cReaders); + } + if (ret.ReturnCode != SCARD_E_TIMEOUT) + break; + if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0) + break; + } + scard_log_status_error(TAG, "SCardGetStatusChangeW", ret.ReturnCode); + + for (index = 0; index < ret.cReaders; index++) + { + const SCARD_READERSTATEW* cur = &rgReaderStates[index]; + ReaderState_Return* out = &ret.rgReaderStates[index]; + + out->dwCurrentState = cur->dwCurrentState; + out->dwEventState = cur->dwEventState; + out->cbAtr = cur->cbAtr; + CopyMemory(&(out->rgbAtr), cur->rgbAtr, sizeof(out->rgbAtr)); + } + + status = smartcard_pack_get_status_change_return(out, &ret, TRUE); +fail: + free(ret.rgReaderStates); + free(rgReaderStates); + if (status != SCARD_S_SUCCESS) + return status; + return ret.ReturnCode; +} + +static LONG smartcard_Cancel_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + ret.ReturnCode = wrap(smartcard, SCardCancel, operation->hContext); + scard_log_status_error(TAG, "SCardCancel", ret.ReturnCode); + smartcard_trace_long_return(&ret, "Cancel"); + return ret.ReturnCode; +} + +static LONG smartcard_ConnectA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + SCARDHANDLE hCard = 0; + Connect_Return ret = { 0 }; + ConnectA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.connectA; + + if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) && + (call->Common.dwShareMode != SCARD_SHARE_DIRECT)) + { + call->Common.dwPreferredProtocols = SCARD_PROTOCOL_Tx; + } + + ret.ReturnCode = wrap(smartcard, SCardConnectA, operation->hContext, (char*)call->szReader, + call->Common.dwShareMode, call->Common.dwPreferredProtocols, &hCard, + &ret.dwActiveProtocol); + smartcard_scard_context_native_to_redir(&(ret.hContext), operation->hContext); + smartcard_scard_handle_native_to_redir(&(ret.hCard), hCard); + + status = smartcard_pack_connect_return(out, &ret); + if (status != SCARD_S_SUCCESS) + goto out_fail; + + status = ret.ReturnCode; +out_fail: + + return status; +} + +static LONG smartcard_ConnectW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + SCARDHANDLE hCard = 0; + Connect_Return ret = { 0 }; + ConnectW_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.connectW; + + if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) && + (call->Common.dwShareMode != SCARD_SHARE_DIRECT)) + { + call->Common.dwPreferredProtocols = SCARD_PROTOCOL_Tx; + } + + ret.ReturnCode = wrap(smartcard, SCardConnectW, operation->hContext, (WCHAR*)call->szReader, + call->Common.dwShareMode, call->Common.dwPreferredProtocols, &hCard, + &ret.dwActiveProtocol); + smartcard_scard_context_native_to_redir(&(ret.hContext), operation->hContext); + smartcard_scard_handle_native_to_redir(&(ret.hCard), hCard); + + status = smartcard_pack_connect_return(out, &ret); + if (status != SCARD_S_SUCCESS) + goto out_fail; + + status = ret.ReturnCode; +out_fail: + + return status; +} + +static LONG smartcard_Reconnect_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + Reconnect_Return ret = { 0 }; + Reconnect_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.reconnect; + ret.ReturnCode = + wrap(smartcard, SCardReconnect, operation->hCard, call->dwShareMode, + call->dwPreferredProtocols, call->dwInitialization, &ret.dwActiveProtocol); + scard_log_status_error(TAG, "SCardReconnect", ret.ReturnCode); + status = smartcard_pack_reconnect_return(out, &ret); + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_Disconnect_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + HCardAndDisposition_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.hCardAndDisposition; + + ret.ReturnCode = wrap(smartcard, SCardDisconnect, operation->hCard, call->dwDisposition); + scard_log_status_error(TAG, "SCardDisconnect", ret.ReturnCode); + smartcard_trace_long_return(&ret, "Disconnect"); + + return ret.ReturnCode; +} + +static LONG smartcard_BeginTransaction_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + ret.ReturnCode = wrap(smartcard, SCardBeginTransaction, operation->hCard); + scard_log_status_error(TAG, "SCardBeginTransaction", ret.ReturnCode); + smartcard_trace_long_return(&ret, "BeginTransaction"); + return ret.ReturnCode; +} + +static LONG smartcard_EndTransaction_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + HCardAndDisposition_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.hCardAndDisposition; + + ret.ReturnCode = wrap(smartcard, SCardEndTransaction, operation->hCard, call->dwDisposition); + scard_log_status_error(TAG, "SCardEndTransaction", ret.ReturnCode); + smartcard_trace_long_return(&ret, "EndTransaction"); + return ret.ReturnCode; +} + +static LONG smartcard_State_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + State_Return ret = { 0 }; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + ret.cbAtrLen = SCARD_ATR_LENGTH; + ret.ReturnCode = wrap(smartcard, SCardState, operation->hCard, &ret.dwState, &ret.dwProtocol, + (BYTE*)&ret.rgAtr, &ret.cbAtrLen); + + scard_log_status_error(TAG, "SCardState", ret.ReturnCode); + status = smartcard_pack_state_return(out, &ret); + if (status != SCARD_S_SUCCESS) + return status; + + return ret.ReturnCode; +} + +static LONG smartcard_StatusA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + Status_Return ret = { 0 }; + DWORD cchReaderLen = 0; + DWORD cbAtrLen = 0; + LPSTR mszReaderNames = NULL; + Status_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.status; + + call->cbAtrLen = 32; + cbAtrLen = call->cbAtrLen; + + if (call->fmszReaderNamesIsNULL) + cchReaderLen = 0; + else + cchReaderLen = SCARD_AUTOALLOCATE; + + status = ret.ReturnCode = + wrap(smartcard, SCardStatusA, operation->hCard, + call->fmszReaderNamesIsNULL ? NULL : (LPSTR)&mszReaderNames, &cchReaderLen, + &ret.dwState, &ret.dwProtocol, cbAtrLen ? (BYTE*)&ret.pbAtr : NULL, &cbAtrLen); + + scard_log_status_error(TAG, "SCardStatusA", status); + if (status == SCARD_S_SUCCESS) + { + if (!call->fmszReaderNamesIsNULL) + ret.mszReaderNames = (BYTE*)mszReaderNames; + + ret.cBytes = cchReaderLen; + + if (call->cbAtrLen) + ret.cbAtrLen = cbAtrLen; + } + + status = smartcard_pack_status_return(out, &ret, FALSE); + + if (mszReaderNames) + wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaderNames); + + if (status != SCARD_S_SUCCESS) + return status; + return ret.ReturnCode; +} + +static LONG smartcard_StatusW_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + Status_Return ret = { 0 }; + LPWSTR mszReaderNames = NULL; + Status_Call* call; + DWORD cbAtrLen; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.status; + + /** + * [MS-RDPESC] + * According to 2.2.2.18 Status_Call cbAtrLen is unused an must be ignored upon receipt. + */ + cbAtrLen = call->cbAtrLen = 32; + + if (call->fmszReaderNamesIsNULL) + ret.cBytes = 0; + else + ret.cBytes = SCARD_AUTOALLOCATE; + + status = ret.ReturnCode = + wrap(smartcard, SCardStatusW, operation->hCard, + call->fmszReaderNamesIsNULL ? NULL : (LPWSTR)&mszReaderNames, &ret.cBytes, + &ret.dwState, &ret.dwProtocol, (BYTE*)&ret.pbAtr, &cbAtrLen); + scard_log_status_error(TAG, "SCardStatusW", status); + if (status == SCARD_S_SUCCESS) + { + if (!call->fmszReaderNamesIsNULL) + ret.mszReaderNames = (BYTE*)mszReaderNames; + + ret.cbAtrLen = cbAtrLen; + } + + /* SCardStatusW returns number of characters, we need number of bytes */ + ret.cBytes *= sizeof(WCHAR); + + status = smartcard_pack_status_return(out, &ret, TRUE); + if (status != SCARD_S_SUCCESS) + return status; + + if (mszReaderNames) + wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaderNames); + + return ret.ReturnCode; +} + +static LONG smartcard_Transmit_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + Transmit_Return ret = { 0 }; + Transmit_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.transmit; + ret.cbRecvLength = 0; + ret.pbRecvBuffer = NULL; + + if (call->cbRecvLength && !call->fpbRecvBufferIsNULL) + { + if (call->cbRecvLength >= 66560) + call->cbRecvLength = 66560; + + ret.cbRecvLength = call->cbRecvLength; + ret.pbRecvBuffer = (BYTE*)malloc(ret.cbRecvLength); + + if (!ret.pbRecvBuffer) + return STATUS_NO_MEMORY; + } + + ret.pioRecvPci = call->pioRecvPci; + ret.ReturnCode = + wrap(smartcard, SCardTransmit, operation->hCard, call->pioSendPci, call->pbSendBuffer, + call->cbSendLength, ret.pioRecvPci, ret.pbRecvBuffer, &(ret.cbRecvLength)); + + scard_log_status_error(TAG, "SCardTransmit", ret.ReturnCode); + + status = smartcard_pack_transmit_return(out, &ret); + free(ret.pbRecvBuffer); + + if (status != SCARD_S_SUCCESS) + return status; + return ret.ReturnCode; +} + +static LONG smartcard_Control_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + Control_Return ret = { 0 }; + Control_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.control; + ret.cbOutBufferSize = call->cbOutBufferSize; + ret.pvOutBuffer = (BYTE*)malloc(call->cbOutBufferSize); + + if (!ret.pvOutBuffer) + return SCARD_E_NO_MEMORY; + + ret.ReturnCode = + wrap(smartcard, SCardControl, operation->hCard, call->dwControlCode, call->pvInBuffer, + call->cbInBufferSize, ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize); + scard_log_status_error(TAG, "SCardControl", ret.ReturnCode); + status = smartcard_pack_control_return(out, &ret); + + free(ret.pvOutBuffer); + if (status != SCARD_S_SUCCESS) + return status; + return ret.ReturnCode; +} + +static LONG smartcard_GetAttrib_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + BOOL autoAllocate = FALSE; + LONG status; + DWORD cbAttrLen = 0; + LPBYTE pbAttr = NULL; + GetAttrib_Return ret = { 0 }; + const GetAttrib_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(operation); + + call = &operation->call.getAttrib; + + if (!call->fpbAttrIsNULL) + { + autoAllocate = (call->cbAttrLen == SCARD_AUTOALLOCATE) ? TRUE : FALSE; + cbAttrLen = call->cbAttrLen; + if (cbAttrLen && !autoAllocate) + { + ret.pbAttr = (BYTE*)malloc(cbAttrLen); + + if (!ret.pbAttr) + return SCARD_E_NO_MEMORY; + } + + pbAttr = autoAllocate ? (LPBYTE) & (ret.pbAttr) : ret.pbAttr; + } + + ret.ReturnCode = + wrap(smartcard, SCardGetAttrib, operation->hCard, call->dwAttrId, pbAttr, &cbAttrLen); + scard_log_status_error(TAG, "SCardGetAttrib", ret.ReturnCode); + ret.cbAttrLen = cbAttrLen; + + status = smartcard_pack_get_attrib_return(out, &ret, call->dwAttrId, call->cbAttrLen); + + if (autoAllocate) + wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbAttr); + else + free(ret.pbAttr); + return status; +} + +static LONG smartcard_SetAttrib_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + Long_Return ret = { 0 }; + SetAttrib_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(operation); + + call = &operation->call.setAttrib; + + ret.ReturnCode = wrap(smartcard, SCardSetAttrib, operation->hCard, call->dwAttrId, call->pbAttr, + call->cbAttrLen); + scard_log_status_error(TAG, "SCardSetAttrib", ret.ReturnCode); + smartcard_trace_long_return(&ret, "SetAttrib"); + + return ret.ReturnCode; +} + +static LONG smartcard_AccessStartedEvent_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status = SCARD_S_SUCCESS; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_UNUSED(operation); + + if (!smartcard->StartedEvent) + smartcard->StartedEvent = wrap(smartcard, SCardAccessStartedEvent); + + if (!smartcard->StartedEvent) + status = SCARD_E_NO_SERVICE; + + return status; +} + +static LONG smartcard_LocateCardsByATRA_Call(scard_call_context* smartcard, wStream* out, + SMARTCARD_OPERATION* operation) +{ + LONG status; + DWORD i, j, k; + GetStatusChange_Return ret = { 0 }; + LPSCARD_READERSTATEA state = NULL; + LPSCARD_READERSTATEA states = NULL; + LocateCardsByATRA_Call* call; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(operation); + + call = &operation->call.locateCardsByATRA; + states = (LPSCARD_READERSTATEA)calloc(call->cReaders, sizeof(SCARD_READERSTATEA)); + + if (!states) + return STATUS_NO_MEMORY; + + for (i = 0; i < call->cReaders; i++) + { + states[i].szReader = (LPSTR)call->rgReaderStates[i].szReader; + states[i].dwCurrentState = call->rgReaderStates[i].dwCurrentState; + states[i].dwEventState = call->rgReaderStates[i].dwEventState; + states[i].cbAtr = call->rgReaderStates[i].cbAtr; + CopyMemory(&(states[i].rgbAtr), &(call->rgReaderStates[i].rgbAtr), 36); + } + + status = ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeA, operation->hContext, + 0x000001F4, states, call->cReaders); + + scard_log_status_error(TAG, "SCardGetStatusChangeA", status); + for (i = 0; i < call->cAtrs; i++) + { + for (j = 0; j < call->cReaders; j++) + { + for (k = 0; k < call->rgAtrMasks[i].cbAtr; k++) + { + if ((call->rgAtrMasks[i].rgbAtr[k] & call->rgAtrMasks[i].rgbMask[k]) != + (states[j].rgbAtr[k] & call->rgAtrMasks[i].rgbMask[k])) + { + break; + } + + states[j].dwEventState |= SCARD_STATE_ATRMATCH; + } + } + } + + ret.cReaders = call->cReaders; + ret.rgReaderStates = NULL; + + if (ret.cReaders > 0) + ret.rgReaderStates = (ReaderState_Return*)calloc(ret.cReaders, sizeof(ReaderState_Return)); + + if (!ret.rgReaderStates) + { + free(states); + return STATUS_NO_MEMORY; + } + + for (i = 0; i < ret.cReaders; i++) + { + state = &states[i]; + ret.rgReaderStates[i].dwCurrentState = state->dwCurrentState; + ret.rgReaderStates[i].dwEventState = state->dwEventState; + ret.rgReaderStates[i].cbAtr = state->cbAtr; + CopyMemory(&(ret.rgReaderStates[i].rgbAtr), &(state->rgbAtr), + sizeof(ret.rgReaderStates[i].rgbAtr)); + } + + free(states); + + status = smartcard_pack_get_status_change_return(out, &ret, FALSE); + + free(ret.rgReaderStates); + if (status != SCARD_S_SUCCESS) + return status; + return ret.ReturnCode; +} + +LONG smartcard_irp_device_control_call(scard_call_context* smartcard, wStream* out, + UINT32* pIoStatus, SMARTCARD_OPERATION* operation) +{ + LONG result; + UINT32 offset; + UINT32 ioControlCode; + size_t outputBufferLength; + size_t objectBufferLength; + + WINPR_ASSERT(smartcard); + WINPR_ASSERT(out); + WINPR_ASSERT(pIoStatus); + WINPR_ASSERT(operation); + + ioControlCode = operation->ioControlCode; + /** + * [MS-RDPESC] 3.2.5.1: Sending Outgoing Messages: + * the output buffer length SHOULD be set to 2048 + * + * Since it's a SHOULD and not a MUST, we don't care + * about it, but we still reserve at least 2048 bytes. + */ + if (!Stream_EnsureRemainingCapacity(out, 2048)) + return SCARD_E_NO_MEMORY; + + /* Device Control Response */ + Stream_Write_UINT32(out, 0); /* OutputBufferLength (4 bytes) */ + Stream_Zero(out, SMARTCARD_COMMON_TYPE_HEADER_LENGTH); /* CommonTypeHeader (8 bytes) */ + Stream_Zero(out, SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH); /* PrivateTypeHeader (8 bytes) */ + Stream_Write_UINT32(out, 0); /* Result (4 bytes) */ + + /* Call */ + switch (ioControlCode) + { + case SCARD_IOCTL_ESTABLISHCONTEXT: + result = smartcard_EstablishContext_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_RELEASECONTEXT: + result = smartcard_ReleaseContext_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_ISVALIDCONTEXT: + result = smartcard_IsValidContext_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_LISTREADERGROUPSA: + result = smartcard_ListReaderGroupsA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_LISTREADERGROUPSW: + result = smartcard_ListReaderGroupsW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_LISTREADERSA: + result = smartcard_ListReadersA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_LISTREADERSW: + result = smartcard_ListReadersW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_INTRODUCEREADERGROUPA: + result = smartcard_IntroduceReaderGroupA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_INTRODUCEREADERGROUPW: + result = smartcard_IntroduceReaderGroupW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_FORGETREADERGROUPA: + result = smartcard_ForgetReaderA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_FORGETREADERGROUPW: + result = smartcard_ForgetReaderW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_INTRODUCEREADERA: + result = smartcard_IntroduceReaderA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_INTRODUCEREADERW: + result = smartcard_IntroduceReaderW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_FORGETREADERA: + result = smartcard_ForgetReaderA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_FORGETREADERW: + result = smartcard_ForgetReaderW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_ADDREADERTOGROUPA: + result = smartcard_AddReaderToGroupA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_ADDREADERTOGROUPW: + result = smartcard_AddReaderToGroupW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_REMOVEREADERFROMGROUPA: + result = smartcard_RemoveReaderFromGroupA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_REMOVEREADERFROMGROUPW: + result = smartcard_RemoveReaderFromGroupW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_LOCATECARDSA: + result = smartcard_LocateCardsA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_LOCATECARDSW: + result = smartcard_LocateCardsW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_GETSTATUSCHANGEA: + result = smartcard_GetStatusChangeA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_GETSTATUSCHANGEW: + result = smartcard_GetStatusChangeW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_CANCEL: + result = smartcard_Cancel_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_CONNECTA: + result = smartcard_ConnectA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_CONNECTW: + result = smartcard_ConnectW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_RECONNECT: + result = smartcard_Reconnect_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_DISCONNECT: + result = smartcard_Disconnect_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_BEGINTRANSACTION: + result = smartcard_BeginTransaction_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_ENDTRANSACTION: + result = smartcard_EndTransaction_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_STATE: + result = smartcard_State_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_STATUSA: + result = smartcard_StatusA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_STATUSW: + result = smartcard_StatusW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_TRANSMIT: + result = smartcard_Transmit_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_CONTROL: + result = smartcard_Control_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_GETATTRIB: + result = smartcard_GetAttrib_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_SETATTRIB: + result = smartcard_SetAttrib_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_ACCESSSTARTEDEVENT: + result = smartcard_AccessStartedEvent_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_LOCATECARDSBYATRA: + result = smartcard_LocateCardsByATRA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_LOCATECARDSBYATRW: + result = smartcard_LocateCardsW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_READCACHEA: + result = smartcard_ReadCacheA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_READCACHEW: + result = smartcard_ReadCacheW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_WRITECACHEA: + result = smartcard_WriteCacheA_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_WRITECACHEW: + result = smartcard_WriteCacheW_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_GETTRANSMITCOUNT: + result = smartcard_GetTransmitCount_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_RELEASETARTEDEVENT: + result = smartcard_ReleaseStartedEvent_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_GETREADERICON: + result = smartcard_GetReaderIcon_Call(smartcard, out, operation); + break; + + case SCARD_IOCTL_GETDEVICETYPEID: + result = smartcard_GetDeviceTypeId_Call(smartcard, out, operation); + break; + + default: + result = STATUS_UNSUCCESSFUL; + break; + } + + /** + * [MS-RPCE] 2.2.6.3 Primitive Type Serialization + * The type MUST be aligned on an 8-byte boundary. If the size of the + * primitive type is not a multiple of 8 bytes, the data MUST be padded. + */ + + if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && + (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT)) + { + offset = (RDPDR_DEVICE_IO_RESPONSE_LENGTH + RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH); + smartcard_pack_write_size_align(out, Stream_GetPosition(out) - offset, 8); + } + + if ((result != SCARD_S_SUCCESS) && (result != SCARD_E_TIMEOUT) && + (result != SCARD_E_NO_READERS_AVAILABLE) && (result != SCARD_E_NO_SERVICE) && + (result != SCARD_W_CACHE_ITEM_NOT_FOUND) && (result != SCARD_W_CACHE_ITEM_STALE)) + { + WLog_WARN(TAG, "IRP failure: %s (0x%08" PRIX32 "), status: %s (0x%08" PRIX32 ")", + scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, + SCardGetErrorString(result), result); + } + + *pIoStatus = STATUS_SUCCESS; + + if ((result & 0xC0000000L) == 0xC0000000L) + { + /* NTSTATUS error */ + *pIoStatus = (UINT32)result; + WLog_WARN(TAG, "IRP failure: %s (0x%08" PRIX32 "), ntstatus: 0x%08" PRIX32 "", + scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result); + } + + Stream_SealLength(out); + outputBufferLength = Stream_Length(out); + WINPR_ASSERT(outputBufferLength >= RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4U); + outputBufferLength -= (RDPDR_DEVICE_IO_RESPONSE_LENGTH + 4U); + WINPR_ASSERT(outputBufferLength >= RDPDR_DEVICE_IO_RESPONSE_LENGTH); + objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH; + WINPR_ASSERT(outputBufferLength <= UINT32_MAX); + WINPR_ASSERT(objectBufferLength <= UINT32_MAX); + Stream_SetPosition(out, RDPDR_DEVICE_IO_RESPONSE_LENGTH); + /* Device Control Response */ + Stream_Write_UINT32(out, (UINT32)outputBufferLength); /* OutputBufferLength (4 bytes) */ + smartcard_pack_common_type_header(out); /* CommonTypeHeader (8 bytes) */ + smartcard_pack_private_type_header( + out, (UINT32)objectBufferLength); /* PrivateTypeHeader (8 bytes) */ + Stream_Write_INT32(out, result); /* Result (4 bytes) */ + Stream_SetPosition(out, Stream_Length(out)); + return SCARD_S_SUCCESS; +} + +static void context_free(void* arg) +{ + struct _scard_context_element* element = arg; + if (!arg) + return; + + if (element->fn_free) + element->fn_free(element->context); + free(element); +} + +scard_call_context* smartcard_call_context_new(const rdpSettings* settings) +{ + wObject* obj; + scard_call_context* ctx; + + WINPR_ASSERT(settings); + ctx = calloc(1, sizeof(scard_call_context)); + if (!ctx) + goto fail; + + ctx->stopEvent = CreateEventA(NULL, TRUE, FALSE, NULL); + if (!ctx->stopEvent) + goto fail; + + ctx->names = LinkedList_New(); + if (!ctx->names) + goto fail; + +#if defined(WITH_SMARTCARD_EMULATE) + ctx->emulation = Emulate_New(settings); + if (!ctx->emulation) + goto fail; +#endif + + ctx->rgSCardContextList = HashTable_New(FALSE); + if (!ctx->rgSCardContextList) + goto fail; + + obj = HashTable_ValueObject(ctx->rgSCardContextList); + WINPR_ASSERT(obj); + obj->fnObjectFree = context_free; + + return ctx; +fail: + smartcard_call_context_free(ctx); + return NULL; +} + +void smartcard_call_context_free(scard_call_context* ctx) +{ + if (!ctx) + return; + + smartcard_call_context_signal_stop(ctx); + + LinkedList_Free(ctx->names); + if (ctx->StartedEvent) + { + wrap(ctx, SCardReleaseStartedEvent); + } +#if defined(WITH_SMARTCARD_EMULATE) + Emulate_Free(ctx->emulation); +#endif + HashTable_Free(ctx->rgSCardContextList); + CloseHandle(ctx->stopEvent); + free(ctx); +} + +BOOL smartcard_call_context_add(scard_call_context* ctx, const char* name) +{ + WINPR_ASSERT(ctx); + WINPR_ASSERT(name); + return LinkedList_AddLast(ctx->names, name); +} + +BOOL smartcard_call_cancel_context(scard_call_context* ctx, SCARDCONTEXT hContext) +{ + WINPR_ASSERT(ctx); + if (wrap(ctx, SCardIsValidContext, hContext) == SCARD_S_SUCCESS) + { + wrap(ctx, SCardCancel, hContext); + } + return TRUE; +} + +BOOL smartcard_call_release_context(scard_call_context* ctx, SCARDCONTEXT hContext) +{ + WINPR_ASSERT(ctx); + wrap(ctx, SCardReleaseContext, hContext); + return TRUE; +} + +BOOL smartcard_call_cancel_all_context(scard_call_context* ctx) +{ + WINPR_ASSERT(ctx); + + HashTable_Clear(ctx->rgSCardContextList); + return TRUE; +} + +BOOL smarcard_call_set_callbacks(scard_call_context* ctx, void* userdata, + void* (*fn_new)(void*, SCARDCONTEXT), void (*fn_free)(void*)) +{ + WINPR_ASSERT(ctx); + ctx->userdata = userdata; + ctx->fn_new = fn_new; + ctx->fn_free = fn_free; + return TRUE; +} + +void* smartcard_call_get_context(scard_call_context* ctx, SCARDCONTEXT hContext) +{ + struct _scard_context_element* element; + + WINPR_ASSERT(ctx); + element = HashTable_GetItemValue(ctx->rgSCardContextList, (void*)hContext); + if (!element) + return NULL; + return element->context; +} + +BOOL smartcard_call_is_configured(scard_call_context* ctx) +{ + WINPR_ASSERT(ctx); + +#if defined(WITH_SMARTCARD_EMULATE) + return Emulate_IsConfigured(ctx->emulation); +#else + return FALSE; +#endif +} + +BOOL smartcard_call_context_signal_stop(scard_call_context* ctx) +{ + WINPR_ASSERT(ctx); + if (!ctx->stopEvent) + return TRUE; + return SetEvent(ctx->stopEvent); +} diff --git a/libfreerdp/utils/smartcard_operations.c b/libfreerdp/utils/smartcard_operations.c new file mode 100644 index 000000000..0aa106aeb --- /dev/null +++ b/libfreerdp/utils/smartcard_operations.c @@ -0,0 +1,1058 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Smartcard Device Service Virtual Channel + * + * Copyright (C) Alexi Volkov 2006 + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Anthony Tong + * Copyright 2015 Thincast Technologies GmbH + * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2017 Armin Novak + * Copyright 2017 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#define TAG FREERDP_TAG("utils.smartcard.ops") + +static LONG smartcard_call_to_operation_handle(SMARTCARD_OPERATION* operation) +{ + WINPR_ASSERT(operation); + + operation->hContext = + smartcard_scard_context_native_from_redir(&(operation->call.handles.hContext)); + operation->hCard = smartcard_scard_handle_native_from_redir(&(operation->call.handles.hCard)); + + return SCARD_S_SUCCESS; +} + +static LONG smartcard_EstablishContext_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_establish_context_call(s, &operation->call.establishContext); + if (status != SCARD_S_SUCCESS) + { + return scard_log_status_error(TAG, "smartcard_unpack_establish_context_call", status); + } + + return SCARD_S_SUCCESS; +} + +static LONG smartcard_ReleaseContext_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_context_call(s, &operation->call.context, "ReleaseContext"); + if (status != SCARD_S_SUCCESS) + scard_log_status_error(TAG, "smartcard_unpack_context_call", status); + + return status; +} + +static LONG smartcard_IsValidContext_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_context_call(s, &operation->call.context, "IsValidContext"); + + return status; +} + +static LONG smartcard_ListReaderGroupsA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_list_reader_groups_call(s, &operation->call.listReaderGroups, FALSE); + + return status; +} + +static LONG smartcard_ListReaderGroupsW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_list_reader_groups_call(s, &operation->call.listReaderGroups, TRUE); + + return status; +} + +static LONG smartcard_ListReadersA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_list_readers_call(s, &operation->call.listReaders, FALSE); + + return status; +} + +static LONG smartcard_ListReadersW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_list_readers_call(s, &operation->call.listReaders, TRUE); + + return status; +} + +static LONG smartcard_context_and_two_strings_a_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = + smartcard_unpack_context_and_two_strings_a_call(s, &operation->call.contextAndTwoStringA); + + return status; +} + +static LONG smartcard_context_and_two_strings_w_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = + smartcard_unpack_context_and_two_strings_w_call(s, &operation->call.contextAndTwoStringW); + + return status; +} + +static LONG smartcard_context_and_string_a_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_context_and_string_a_call(s, &operation->call.contextAndStringA); + + return status; +} + +static LONG smartcard_context_and_string_w_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_context_and_string_w_call(s, &operation->call.contextAndStringW); + + return status; +} + +static LONG smartcard_LocateCardsA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_locate_cards_a_call(s, &operation->call.locateCardsA); + + return status; +} + +static LONG smartcard_LocateCardsW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_locate_cards_w_call(s, &operation->call.locateCardsW); + + return status; +} + +static LONG smartcard_GetStatusChangeA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_get_status_change_a_call(s, &operation->call.getStatusChangeA); + + return status; +} + +static LONG smartcard_GetStatusChangeW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_get_status_change_w_call(s, &operation->call.getStatusChangeW); + + return status; +} + +static LONG smartcard_Cancel_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_context_call(s, &operation->call.context, "Cancel"); + + return status; +} + +static LONG smartcard_ConnectA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_connect_a_call(s, &operation->call.connectA); + + return status; +} + +static LONG smartcard_ConnectW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_connect_w_call(s, &operation->call.connectW); + + return status; +} + +static LONG smartcard_Reconnect_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_reconnect_call(s, &operation->call.reconnect); + + return status; +} + +static LONG smartcard_Disconnect_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition, + "Disconnect"); + + return status; +} + +static LONG smartcard_BeginTransaction_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition, + "BeginTransaction"); + + return status; +} + +static LONG smartcard_EndTransaction_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition, + "EndTransaction"); + + return status; +} + +static LONG smartcard_State_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_state_call(s, &operation->call.state); + + return status; +} + +static LONG smartcard_StatusA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_status_call(s, &operation->call.status, FALSE); + + return status; +} + +static LONG smartcard_StatusW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_status_call(s, &operation->call.status, TRUE); + + return status; +} + +static LONG smartcard_Transmit_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_transmit_call(s, &operation->call.transmit); + + return status; +} + +static LONG smartcard_Control_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_control_call(s, &operation->call.control); + + return status; +} + +static LONG smartcard_GetAttrib_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_get_attrib_call(s, &operation->call.getAttrib); + + return status; +} + +static LONG smartcard_SetAttrib_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_set_attrib_call(s, &operation->call.setAttrib); + + return status; +} + +static LONG smartcard_AccessStartedEvent_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + if (Stream_GetRemainingLength(s) < 4) + { + WLog_WARN(TAG, "AccessStartedEvent is too short: %" PRIuz "", Stream_GetRemainingLength(s)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Read_INT32(s, operation->call.lng.LongValue); /* Unused (4 bytes) */ + + return SCARD_S_SUCCESS; +} + +static LONG smartcard_LocateCardsByATRA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_locate_cards_by_atr_a_call(s, &operation->call.locateCardsByATRA); + + return status; +} + +static LONG smartcard_LocateCardsByATRW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_locate_cards_by_atr_w_call(s, &operation->call.locateCardsByATRW); + + return status; +} + +static LONG smartcard_ReadCacheA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_read_cache_a_call(s, &operation->call.readCacheA); + + return status; +} + +static LONG smartcard_ReadCacheW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_read_cache_w_call(s, &operation->call.readCacheW); + + return status; +} + +static LONG smartcard_WriteCacheA_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_write_cache_a_call(s, &operation->call.writeCacheA); + + return status; +} + +static LONG smartcard_WriteCacheW_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_write_cache_w_call(s, &operation->call.writeCacheW); + + return status; +} + +static LONG smartcard_GetTransmitCount_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_get_transmit_count_call(s, &operation->call.getTransmitCount); + + return status; +} + +static LONG smartcard_ReleaseStartedEvent_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + WINPR_UNUSED(s); + WINPR_UNUSED(operation); + WLog_WARN(TAG, "According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules " + "SCARD_IOCTL_RELEASETARTEDEVENT is not supported"); + return SCARD_E_UNSUPPORTED_FEATURE; +} + +static LONG smartcard_GetReaderIcon_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_get_reader_icon_call(s, &operation->call.getReaderIcon); + + return status; +} + +static LONG smartcard_GetDeviceTypeId_Decode(wStream* s, SMARTCARD_OPERATION* operation) +{ + LONG status; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + status = smartcard_unpack_get_device_type_id_call(s, &operation->call.getDeviceTypeId); + + return status; +} + +LONG smartcard_irp_device_control_decode(wStream* s, UINT32 CompletionId, UINT32 FileId, + SMARTCARD_OPERATION* operation) +{ + LONG status; + UINT32 offset; + UINT32 ioControlCode; + UINT32 outputBufferLength; + UINT32 inputBufferLength; + + WINPR_ASSERT(s); + WINPR_ASSERT(operation); + + /* Device Control Request */ + + if (Stream_GetRemainingLength(s) < 32) + { + WLog_WARN(TAG, "Device Control Request is too short: %" PRIuz "", + Stream_GetRemainingLength(s)); + return SCARD_F_INTERNAL_ERROR; + } + + Stream_Read_UINT32(s, outputBufferLength); /* OutputBufferLength (4 bytes) */ + Stream_Read_UINT32(s, inputBufferLength); /* InputBufferLength (4 bytes) */ + Stream_Read_UINT32(s, ioControlCode); /* IoControlCode (4 bytes) */ + Stream_Seek(s, 20); /* Padding (20 bytes) */ + operation->ioControlCode = ioControlCode; + operation->ioControlCodeName = scard_get_ioctl_string(ioControlCode, FALSE); + + if (Stream_Length(s) != (Stream_GetPosition(s) + inputBufferLength)) + { + WLog_WARN(TAG, "InputBufferLength mismatch: Actual: %" PRIuz " Expected: %" PRIuz "", + Stream_Length(s), Stream_GetPosition(s) + inputBufferLength); + return SCARD_F_INTERNAL_ERROR; + } + + WLog_DBG(TAG, "%s (0x%08" PRIX32 ") FileId: %" PRIu32 " CompletionId: %" PRIu32 "", + scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, FileId, CompletionId); + + if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && + (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT)) + { + status = smartcard_unpack_common_type_header(s); + if (status != SCARD_S_SUCCESS) + return status; + + status = smartcard_unpack_private_type_header(s); + if (status != SCARD_S_SUCCESS) + return status; + } + + /* Decode */ + switch (ioControlCode) + { + case SCARD_IOCTL_ESTABLISHCONTEXT: + status = smartcard_EstablishContext_Decode(s, operation); + break; + + case SCARD_IOCTL_RELEASECONTEXT: + status = smartcard_ReleaseContext_Decode(s, operation); + break; + + case SCARD_IOCTL_ISVALIDCONTEXT: + status = smartcard_IsValidContext_Decode(s, operation); + break; + + case SCARD_IOCTL_LISTREADERGROUPSA: + status = smartcard_ListReaderGroupsA_Decode(s, operation); + break; + + case SCARD_IOCTL_LISTREADERGROUPSW: + status = smartcard_ListReaderGroupsW_Decode(s, operation); + break; + + case SCARD_IOCTL_LISTREADERSA: + status = smartcard_ListReadersA_Decode(s, operation); + break; + + case SCARD_IOCTL_LISTREADERSW: + status = smartcard_ListReadersW_Decode(s, operation); + break; + + case SCARD_IOCTL_INTRODUCEREADERGROUPA: + status = smartcard_context_and_string_a_Decode(s, operation); + break; + + case SCARD_IOCTL_INTRODUCEREADERGROUPW: + status = smartcard_context_and_string_w_Decode(s, operation); + break; + + case SCARD_IOCTL_FORGETREADERGROUPA: + status = smartcard_context_and_string_a_Decode(s, operation); + break; + + case SCARD_IOCTL_FORGETREADERGROUPW: + status = smartcard_context_and_string_w_Decode(s, operation); + break; + + case SCARD_IOCTL_INTRODUCEREADERA: + status = smartcard_context_and_two_strings_a_Decode(s, operation); + break; + + case SCARD_IOCTL_INTRODUCEREADERW: + status = smartcard_context_and_two_strings_w_Decode(s, operation); + break; + + case SCARD_IOCTL_FORGETREADERA: + status = smartcard_context_and_string_a_Decode(s, operation); + break; + + case SCARD_IOCTL_FORGETREADERW: + status = smartcard_context_and_string_w_Decode(s, operation); + break; + + case SCARD_IOCTL_ADDREADERTOGROUPA: + status = smartcard_context_and_two_strings_a_Decode(s, operation); + break; + + case SCARD_IOCTL_ADDREADERTOGROUPW: + status = smartcard_context_and_two_strings_w_Decode(s, operation); + break; + + case SCARD_IOCTL_REMOVEREADERFROMGROUPA: + status = smartcard_context_and_two_strings_a_Decode(s, operation); + break; + + case SCARD_IOCTL_REMOVEREADERFROMGROUPW: + status = smartcard_context_and_two_strings_w_Decode(s, operation); + break; + + case SCARD_IOCTL_LOCATECARDSA: + status = smartcard_LocateCardsA_Decode(s, operation); + break; + + case SCARD_IOCTL_LOCATECARDSW: + status = smartcard_LocateCardsW_Decode(s, operation); + break; + + case SCARD_IOCTL_GETSTATUSCHANGEA: + status = smartcard_GetStatusChangeA_Decode(s, operation); + break; + + case SCARD_IOCTL_GETSTATUSCHANGEW: + status = smartcard_GetStatusChangeW_Decode(s, operation); + break; + + case SCARD_IOCTL_CANCEL: + status = smartcard_Cancel_Decode(s, operation); + break; + + case SCARD_IOCTL_CONNECTA: + status = smartcard_ConnectA_Decode(s, operation); + break; + + case SCARD_IOCTL_CONNECTW: + status = smartcard_ConnectW_Decode(s, operation); + break; + + case SCARD_IOCTL_RECONNECT: + status = smartcard_Reconnect_Decode(s, operation); + break; + + case SCARD_IOCTL_DISCONNECT: + status = smartcard_Disconnect_Decode(s, operation); + break; + + case SCARD_IOCTL_BEGINTRANSACTION: + status = smartcard_BeginTransaction_Decode(s, operation); + break; + + case SCARD_IOCTL_ENDTRANSACTION: + status = smartcard_EndTransaction_Decode(s, operation); + break; + + case SCARD_IOCTL_STATE: + status = smartcard_State_Decode(s, operation); + break; + + case SCARD_IOCTL_STATUSA: + status = smartcard_StatusA_Decode(s, operation); + break; + + case SCARD_IOCTL_STATUSW: + status = smartcard_StatusW_Decode(s, operation); + break; + + case SCARD_IOCTL_TRANSMIT: + status = smartcard_Transmit_Decode(s, operation); + break; + + case SCARD_IOCTL_CONTROL: + status = smartcard_Control_Decode(s, operation); + break; + + case SCARD_IOCTL_GETATTRIB: + status = smartcard_GetAttrib_Decode(s, operation); + break; + + case SCARD_IOCTL_SETATTRIB: + status = smartcard_SetAttrib_Decode(s, operation); + break; + + case SCARD_IOCTL_ACCESSSTARTEDEVENT: + status = smartcard_AccessStartedEvent_Decode(s, operation); + break; + + case SCARD_IOCTL_LOCATECARDSBYATRA: + status = smartcard_LocateCardsByATRA_Decode(s, operation); + break; + + case SCARD_IOCTL_LOCATECARDSBYATRW: + status = smartcard_LocateCardsByATRW_Decode(s, operation); + break; + + case SCARD_IOCTL_READCACHEA: + status = smartcard_ReadCacheA_Decode(s, operation); + break; + + case SCARD_IOCTL_READCACHEW: + status = smartcard_ReadCacheW_Decode(s, operation); + break; + + case SCARD_IOCTL_WRITECACHEA: + status = smartcard_WriteCacheA_Decode(s, operation); + break; + + case SCARD_IOCTL_WRITECACHEW: + status = smartcard_WriteCacheW_Decode(s, operation); + break; + + case SCARD_IOCTL_GETTRANSMITCOUNT: + status = smartcard_GetTransmitCount_Decode(s, operation); + break; + + case SCARD_IOCTL_RELEASETARTEDEVENT: + status = smartcard_ReleaseStartedEvent_Decode(s, operation); + break; + + case SCARD_IOCTL_GETREADERICON: + status = smartcard_GetReaderIcon_Decode(s, operation); + break; + + case SCARD_IOCTL_GETDEVICETYPEID: + status = smartcard_GetDeviceTypeId_Decode(s, operation); + break; + + default: + status = SCARD_F_INTERNAL_ERROR; + break; + } + + smartcard_call_to_operation_handle(operation); + + if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && + (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT)) + { + offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH); + smartcard_unpack_read_size_align(s, Stream_GetPosition(s) - offset, 8); + } + + if (Stream_GetPosition(s) < Stream_Length(s)) + { + SIZE_T difference; + difference = Stream_Length(s) - Stream_GetPosition(s); + WLog_WARN(TAG, + "IRP was not fully parsed %s (%s [0x%08" PRIX32 "]): Actual: %" PRIuz + ", Expected: %" PRIuz ", Difference: %" PRIuz "", + scard_get_ioctl_string(ioControlCode, TRUE), + scard_get_ioctl_string(ioControlCode, FALSE), ioControlCode, + Stream_GetPosition(s), Stream_Length(s), difference); + winpr_HexDump(TAG, WLOG_WARN, Stream_Pointer(s), difference); + } + + if (Stream_GetPosition(s) > Stream_Length(s)) + { + SIZE_T difference; + difference = Stream_GetPosition(s) - Stream_Length(s); + WLog_WARN(TAG, + "IRP was parsed beyond its end %s (0x%08" PRIX32 "): Actual: %" PRIuz + ", Expected: %" PRIuz ", Difference: %" PRIuz "", + scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, Stream_GetPosition(s), + Stream_Length(s), difference); + } + + return status; +} + +static void free_reader_states_a(LPSCARD_READERSTATEA rgReaderStates, UINT32 cReaders) +{ + UINT32 x; + for (x = 0; x < cReaders; x++) + { + SCARD_READERSTATEA* state = &rgReaderStates[x]; + free(state->szReader); + } + + free(rgReaderStates); +} + +static void free_reader_states_w(LPSCARD_READERSTATEW rgReaderStates, UINT32 cReaders) +{ + UINT32 x; + for (x = 0; x < cReaders; x++) + { + SCARD_READERSTATEW* state = &rgReaderStates[x]; + free(state->szReader); + } + + free(rgReaderStates); +} + +void smartcard_operation_free(SMARTCARD_OPERATION* op, BOOL allocated) +{ + if (!op) + return; + switch (op->ioControlCode) + { + case SCARD_IOCTL_CANCEL: + case SCARD_IOCTL_ACCESSSTARTEDEVENT: + case SCARD_IOCTL_RELEASETARTEDEVENT: + case SCARD_IOCTL_LISTREADERGROUPSA: + case SCARD_IOCTL_LISTREADERGROUPSW: + case SCARD_IOCTL_RECONNECT: + case SCARD_IOCTL_DISCONNECT: + case SCARD_IOCTL_BEGINTRANSACTION: + case SCARD_IOCTL_ENDTRANSACTION: + case SCARD_IOCTL_STATE: + case SCARD_IOCTL_STATUSA: + case SCARD_IOCTL_STATUSW: + case SCARD_IOCTL_ESTABLISHCONTEXT: + case SCARD_IOCTL_RELEASECONTEXT: + case SCARD_IOCTL_ISVALIDCONTEXT: + case SCARD_IOCTL_GETATTRIB: + case SCARD_IOCTL_GETTRANSMITCOUNT: + break; + + case SCARD_IOCTL_LOCATECARDSA: + { + LocateCardsA_Call* call = &op->call.locateCardsA; + free(call->mszCards); + + free_reader_states_a(call->rgReaderStates, call->cReaders); + } + break; + case SCARD_IOCTL_LOCATECARDSW: + { + LocateCardsW_Call* call = &op->call.locateCardsW; + free(call->mszCards); + + free_reader_states_w(call->rgReaderStates, call->cReaders); + } + break; + + case SCARD_IOCTL_LOCATECARDSBYATRA: + { + LocateCardsByATRA_Call* call = &op->call.locateCardsByATRA; + + free_reader_states_a(call->rgReaderStates, call->cReaders); + } + break; + case SCARD_IOCTL_LOCATECARDSBYATRW: + { + LocateCardsByATRW_Call* call = &op->call.locateCardsByATRW; + free_reader_states_w(call->rgReaderStates, call->cReaders); + } + break; + case SCARD_IOCTL_FORGETREADERA: + case SCARD_IOCTL_INTRODUCEREADERGROUPA: + case SCARD_IOCTL_FORGETREADERGROUPA: + { + ContextAndStringA_Call* call = &op->call.contextAndStringA; + free(call->sz); + } + break; + + case SCARD_IOCTL_FORGETREADERW: + case SCARD_IOCTL_INTRODUCEREADERGROUPW: + case SCARD_IOCTL_FORGETREADERGROUPW: + { + ContextAndStringW_Call* call = &op->call.contextAndStringW; + free(call->sz); + } + break; + + case SCARD_IOCTL_INTRODUCEREADERA: + case SCARD_IOCTL_REMOVEREADERFROMGROUPA: + case SCARD_IOCTL_ADDREADERTOGROUPA: + + { + ContextAndTwoStringA_Call* call = &op->call.contextAndTwoStringA; + free(call->sz1); + free(call->sz2); + } + break; + + case SCARD_IOCTL_INTRODUCEREADERW: + case SCARD_IOCTL_REMOVEREADERFROMGROUPW: + case SCARD_IOCTL_ADDREADERTOGROUPW: + + { + ContextAndTwoStringW_Call* call = &op->call.contextAndTwoStringW; + free(call->sz1); + free(call->sz2); + } + break; + + case SCARD_IOCTL_LISTREADERSA: + case SCARD_IOCTL_LISTREADERSW: + { + ListReaders_Call* call = &op->call.listReaders; + free(call->mszGroups); + } + break; + case SCARD_IOCTL_GETSTATUSCHANGEA: + { + GetStatusChangeA_Call* call = &op->call.getStatusChangeA; + free_reader_states_a(call->rgReaderStates, call->cReaders); + } + break; + + case SCARD_IOCTL_GETSTATUSCHANGEW: + { + GetStatusChangeW_Call* call = &op->call.getStatusChangeW; + free_reader_states_w(call->rgReaderStates, call->cReaders); + } + break; + case SCARD_IOCTL_GETREADERICON: + { + GetReaderIcon_Call* call = &op->call.getReaderIcon; + free(call->szReaderName); + } + break; + case SCARD_IOCTL_GETDEVICETYPEID: + { + GetDeviceTypeId_Call* call = &op->call.getDeviceTypeId; + free(call->szReaderName); + } + break; + case SCARD_IOCTL_CONNECTA: + { + ConnectA_Call* call = &op->call.connectA; + free(call->szReader); + } + break; + case SCARD_IOCTL_CONNECTW: + { + ConnectW_Call* call = &op->call.connectW; + free(call->szReader); + } + break; + case SCARD_IOCTL_SETATTRIB: + free(op->call.setAttrib.pbAttr); + break; + case SCARD_IOCTL_TRANSMIT: + { + Transmit_Call* call = &op->call.transmit; + free(call->pbSendBuffer); + free(call->pioSendPci); + free(call->pioRecvPci); + } + break; + case SCARD_IOCTL_CONTROL: + { + Control_Call* call = &op->call.control; + free(call->pvInBuffer); + } + break; + case SCARD_IOCTL_READCACHEA: + { + ReadCacheA_Call* call = &op->call.readCacheA; + free(call->szLookupName); + free(call->Common.CardIdentifier); + } + break; + case SCARD_IOCTL_READCACHEW: + { + ReadCacheW_Call* call = &op->call.readCacheW; + free(call->szLookupName); + free(call->Common.CardIdentifier); + } + break; + case SCARD_IOCTL_WRITECACHEA: + { + WriteCacheA_Call* call = &op->call.writeCacheA; + free(call->szLookupName); + free(call->Common.CardIdentifier); + free(call->Common.pbData); + } + case SCARD_IOCTL_WRITECACHEW: + { + WriteCacheW_Call* call = &op->call.writeCacheW; + free(call->szLookupName); + free(call->Common.CardIdentifier); + free(call->Common.pbData); + } + break; + default: + break; + } + + { + SMARTCARD_OPERATION empty = { 0 }; + *op = empty; + } + + if (allocated) + free(op); +} diff --git a/channels/smartcard/client/smartcard_pack.c b/libfreerdp/utils/smartcard_pack.c similarity index 75% rename from channels/smartcard/client/smartcard_pack.c rename to libfreerdp/utils/smartcard_pack.c index 94a7be631..0a4e7be2d 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/libfreerdp/utils/smartcard_pack.c @@ -28,36 +28,34 @@ #include #include -#include "smartcard_pack.h" +#include +#include + +#include +#define TAG FREERDP_TAG("scard.pack") static const DWORD g_LogLevel = WLOG_DEBUG; -#define smartcard_unpack_redir_scard_context(smartcard, s, context, index) \ - smartcard_unpack_redir_scard_context_((smartcard), (s), (context), (index), __FILE__, \ - __FUNCTION__, __LINE__) -#define smartcard_unpack_redir_scard_handle(smartcard, s, context, index) \ - smartcard_unpack_redir_scard_handle_((smartcard), (s), (context), (index), __FILE__, \ - __FUNCTION__, __LINE__) +#define smartcard_unpack_redir_scard_context(s, context, index) \ + smartcard_unpack_redir_scard_context_((s), (context), (index), __FILE__, __FUNCTION__, __LINE__) +#define smartcard_unpack_redir_scard_handle(s, context, index) \ + smartcard_unpack_redir_scard_handle_((s), (context), (index), __FILE__, __FUNCTION__, __LINE__) -static LONG smartcard_unpack_redir_scard_context_(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDCONTEXT* context, UINT32* index, - const char* file, const char* function, int line); -static LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDCONTEXT* context, DWORD* index); -static LONG smartcard_unpack_redir_scard_handle_(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDHANDLE* handle, UINT32* index, - const char* file, const char* function, int line); -static LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDHANDLE* handle, DWORD* index); -static LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDCONTEXT* context); -static LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDCONTEXT* context); +static LONG smartcard_unpack_redir_scard_context_(wStream* s, REDIR_SCARDCONTEXT* context, + UINT32* index, const char* file, + const char* function, int line); +static LONG smartcard_pack_redir_scard_context(wStream* s, const REDIR_SCARDCONTEXT* context, + DWORD* index); +static LONG smartcard_unpack_redir_scard_handle_(wStream* s, REDIR_SCARDHANDLE* handle, + UINT32* index, const char* file, + const char* function, int line); +static LONG smartcard_pack_redir_scard_handle(wStream* s, const REDIR_SCARDHANDLE* handle, + DWORD* index); +static LONG smartcard_unpack_redir_scard_context_ref(wStream* s, REDIR_SCARDCONTEXT* context); +static LONG smartcard_pack_redir_scard_context_ref(wStream* s, const REDIR_SCARDCONTEXT* context); -static LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDHANDLE* handle); -static LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDHANDLE* handle); +static LONG smartcard_unpack_redir_scard_handle_ref(wStream* s, REDIR_SCARDHANDLE* handle); +static LONG smartcard_pack_redir_scard_handle_ref(wStream* s, const REDIR_SCARDHANDLE* handle); typedef enum { @@ -181,7 +179,7 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t eleme if (!r) return SCARD_E_NO_MEMORY; Stream_Read(s, r, len); - smartcard_unpack_read_size_align(NULL, s, len, 4); + smartcard_unpack_read_size_align(s, len, 4); *data = r; return STATUS_SUCCESS; } @@ -250,7 +248,7 @@ static LONG smartcard_ndr_write(wStream* s, const BYTE* data, UINT32 size, UINT3 Stream_Write(s, data, dataLen); else Stream_Zero(s, dataLen); - return smartcard_pack_write_size_align(NULL, s, len, 4); + return smartcard_pack_write_size_align(s, len, 4); } static LONG smartcard_ndr_write_state(wStream* s, const ReaderState_Return* data, UINT32 size, @@ -498,10 +496,8 @@ static void smartcard_trace_context_and_string_call_w(const char* name, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, const Context_Call* call, - const char* name) +static void smartcard_trace_context_call(const Context_Call* call, const char* name) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -512,10 +508,8 @@ static void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, const Cont WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, - const ListReaderGroups_Call* call, BOOL unicode) +static void smartcard_trace_list_reader_groups_call(const ListReaderGroups_Call* call, BOOL unicode) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -528,14 +522,12 @@ static void smartcard_trace_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, - const GetStatusChangeW_Call* call) +static void smartcard_trace_get_status_change_w_call(const GetStatusChangeW_Call* call) { UINT32 index; char* szEventState; char* szCurrentState; LPSCARD_READERSTATEW readerState; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -567,12 +559,10 @@ static void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, - const ListReaderGroups_Return* ret, +static void smartcard_trace_list_reader_groups_return(const ListReaderGroups_Return* ret, BOOL unicode) { char* mszA = NULL; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -587,11 +577,9 @@ static void smartcard_trace_list_reader_groups_return(SMARTCARD_DEVICE* smartcar free(mszA); } -static void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, - const ListReaders_Call* call, BOOL unicode) +static void smartcard_trace_list_readers_call(const ListReaders_Call* call, BOOL unicode) { char* mszGroupsA = NULL; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -610,15 +598,12 @@ static void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, free(mszGroupsA); } -static void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, - const LocateCardsByATRA_Call* call) +static void smartcard_trace_locate_cards_by_atr_a_call(const LocateCardsByATRA_Call* call) { UINT32 index; char* szEventState; char* szCurrentState; - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -650,11 +635,9 @@ static void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartca WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, - const LocateCardsA_Call* call) +static void smartcard_trace_locate_cards_a_call(const LocateCardsA_Call* call) { char buffer[8192]; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -670,10 +653,9 @@ static void smartcard_trace_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_locate_cards_return(SMARTCARD_DEVICE* smartcard, - const LocateCards_Return* ret) +static void smartcard_trace_locate_cards_return(const LocateCards_Return* ret) { - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -688,10 +670,9 @@ static void smartcard_trace_locate_cards_return(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, - const GetReaderIcon_Return* ret) +static void smartcard_trace_get_reader_icon_return(const GetReaderIcon_Return* ret) { - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -706,10 +687,9 @@ static void smartcard_trace_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, - const GetTransmitCount_Return* ret) +static void smartcard_trace_get_transmit_count_return(const GetTransmitCount_Return* ret) { - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -721,10 +701,9 @@ static void smartcard_trace_get_transmit_count_return(SMARTCARD_DEVICE* smartcar WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_read_cache_return(SMARTCARD_DEVICE* smartcard, - const ReadCache_Return* ret) +static void smartcard_trace_read_cache_return(const ReadCache_Return* ret) { - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -742,11 +721,10 @@ static void smartcard_trace_read_cache_return(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, - const LocateCardsW_Call* call) +static void smartcard_trace_locate_cards_w_call(const LocateCardsW_Call* call) { char buffer[8192]; - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -760,11 +738,9 @@ static void smartcard_trace_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, - const ListReaders_Return* ret, BOOL unicode) +static void smartcard_trace_list_readers_return(const ListReaders_Return* ret, BOOL unicode) { char* mszA = NULL; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -786,16 +762,13 @@ static void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, free(mszA); } -static void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard, - const GetStatusChange_Return* ret, +static void smartcard_trace_get_status_change_return(const GetStatusChange_Return* ret, BOOL unicode) { UINT32 index; char* szEventState; char* szCurrentState; - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -825,10 +798,8 @@ static void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard, - const ContextAndTwoStringA_Call* call) +static void smartcard_trace_context_and_two_strings_a_call(const ContextAndTwoStringA_Call* call) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -839,13 +810,11 @@ static void smartcard_trace_context_and_two_strings_a_call(SMARTCARD_DEVICE* sma WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard, - const ContextAndTwoStringW_Call* call) +static void smartcard_trace_context_and_two_strings_w_call(const ContextAndTwoStringW_Call* call) { CHAR* sz1 = NULL; CHAR* sz2 = NULL; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -861,10 +830,8 @@ static void smartcard_trace_context_and_two_strings_w_call(SMARTCARD_DEVICE* sma WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_get_transmit_count_call(SMARTCARD_DEVICE* smartcard, - const GetTransmitCount_Call* call) +static void smartcard_trace_get_transmit_count_call(const GetTransmitCount_Call* call) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -875,11 +842,10 @@ static void smartcard_trace_get_transmit_count_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_write_cache_a_call(SMARTCARD_DEVICE* smartcard, - const WriteCacheA_Call* call) +static void smartcard_trace_write_cache_a_call(const WriteCacheA_Call* call) { char buffer[1024]; - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -899,12 +865,11 @@ static void smartcard_trace_write_cache_a_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_write_cache_w_call(SMARTCARD_DEVICE* smartcard, - const WriteCacheW_Call* call) +static void smartcard_trace_write_cache_w_call(const WriteCacheW_Call* call) { char* tmp = NULL; char buffer[1024]; - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -925,11 +890,10 @@ static void smartcard_trace_write_cache_w_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_read_cache_a_call(SMARTCARD_DEVICE* smartcard, - const ReadCacheA_Call* call) +static void smartcard_trace_read_cache_a_call(const ReadCacheA_Call* call) { char buffer[1024]; - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -947,12 +911,11 @@ static void smartcard_trace_read_cache_a_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_read_cache_w_call(SMARTCARD_DEVICE* smartcard, - const ReadCacheW_Call* call) +static void smartcard_trace_read_cache_w_call(const ReadCacheW_Call* call) { char* tmp = NULL; char buffer[1024]; - WINPR_UNUSED(smartcard); + if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -972,11 +935,10 @@ static void smartcard_trace_read_cache_w_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, const Transmit_Call* call) +static void smartcard_trace_transmit_call(const Transmit_Call* call) { UINT32 cbExtraBytes; BYTE* pbExtraBytes; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1042,15 +1004,12 @@ static void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, const Tra WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, - const LocateCardsByATRW_Call* call) +static void smartcard_trace_locate_cards_by_atr_w_call(const LocateCardsByATRW_Call* call) { UINT32 index; char* szEventState; char* szCurrentState; - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1086,11 +1045,10 @@ static void smartcard_trace_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartca WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, const Transmit_Return* ret) +static void smartcard_trace_transmit_return(const Transmit_Return* ret) { UINT32 cbExtraBytes; BYTE* pbExtraBytes; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1135,10 +1093,8 @@ static void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, const T WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_control_return(SMARTCARD_DEVICE* smartcard, const Control_Return* ret) +static void smartcard_trace_control_return(const Control_Return* ret) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1162,10 +1118,8 @@ static void smartcard_trace_control_return(SMARTCARD_DEVICE* smartcard, const Co WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_control_call(SMARTCARD_DEVICE* smartcard, const Control_Call* call) +static void smartcard_trace_control_call(const Control_Call* call) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1194,10 +1148,9 @@ static void smartcard_trace_control_call(SMARTCARD_DEVICE* smartcard, const Cont WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_set_attrib_call(SMARTCARD_DEVICE* smartcard, const SetAttrib_Call* call) +static void smartcard_trace_set_attrib_call(const SetAttrib_Call* call) { char buffer[8192]; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1212,10 +1165,8 @@ static void smartcard_trace_set_attrib_call(SMARTCARD_DEVICE* smartcard, const S WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, - const GetAttrib_Return* ret, DWORD dwAttrId) +static void smartcard_trace_get_attrib_return(const GetAttrib_Return* ret, DWORD dwAttrId) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1245,10 +1196,8 @@ static void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_get_attrib_call(SMARTCARD_DEVICE* smartcard, const GetAttrib_Call* call) +static void smartcard_trace_get_attrib_call(const GetAttrib_Call* call) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1263,11 +1212,8 @@ static void smartcard_trace_get_attrib_call(SMARTCARD_DEVICE* smartcard, const G WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_status_call(SMARTCARD_DEVICE* smartcard, const Status_Call* call, - BOOL unicode) +static void smartcard_trace_status_call(const Status_Call* call, BOOL unicode) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1281,15 +1227,12 @@ static void smartcard_trace_status_call(SMARTCARD_DEVICE* smartcard, const Statu WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, const Status_Return* ret, - BOOL unicode) +static void smartcard_trace_status_return(const Status_Return* ret, BOOL unicode) { char* mszReaderNamesA = NULL; char buffer[1024]; DWORD cBytes; - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; cBytes = ret->cBytes; @@ -1315,11 +1258,10 @@ static void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, const Sta free(mszReaderNamesA); } -static void smartcard_trace_state_return(SMARTCARD_DEVICE* smartcard, const State_Return* ret) +static void smartcard_trace_state_return(const State_Return* ret) { char buffer[1024]; char* state; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1338,10 +1280,8 @@ static void smartcard_trace_state_return(SMARTCARD_DEVICE* smartcard, const Stat free(state); } -static void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard, - const Reconnect_Return* ret) +static void smartcard_trace_reconnect_return(const Reconnect_Return* ret) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1354,9 +1294,8 @@ static void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_connect_a_call(SMARTCARD_DEVICE* smartcard, const ConnectA_Call* call) +static void smartcard_trace_connect_a_call(const ConnectA_Call* call) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1373,10 +1312,9 @@ static void smartcard_trace_connect_a_call(SMARTCARD_DEVICE* smartcard, const Co WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_connect_w_call(SMARTCARD_DEVICE* smartcard, const ConnectW_Call* call) +static void smartcard_trace_connect_w_call(const ConnectW_Call* call) { char* szReaderA = NULL; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1395,12 +1333,9 @@ static void smartcard_trace_connect_w_call(SMARTCARD_DEVICE* smartcard, const Co free(szReaderA); } -static void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, - const HCardAndDisposition_Call* call, +static void smartcard_trace_hcard_and_disposition_call(const HCardAndDisposition_Call* call, const char* name) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1413,10 +1348,8 @@ static void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartca WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, - const EstablishContext_Call* call) +static void smartcard_trace_establish_context_call(const EstablishContext_Call* call) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1427,10 +1360,8 @@ static void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard, - const EstablishContext_Return* ret) +static void smartcard_trace_establish_context_return(const EstablishContext_Return* ret) { - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1443,11 +1374,8 @@ static void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard WLog_LVL(TAG, g_LogLevel, "}"); } -void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, const Long_Return* ret, - const char* name) +void smartcard_trace_long_return(const Long_Return* ret, const char* name) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1457,10 +1385,8 @@ void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, const Long_Return* WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_connect_return(SMARTCARD_DEVICE* smartcard, const Connect_Return* ret) +static void smartcard_trace_connect_return(const Connect_Return* ret) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1475,10 +1401,8 @@ static void smartcard_trace_connect_return(SMARTCARD_DEVICE* smartcard, const Co WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_reconnect_call(SMARTCARD_DEVICE* smartcard, const Reconnect_Call* call) +static void smartcard_trace_reconnect_call(const Reconnect_Call* call) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1495,11 +1419,8 @@ static void smartcard_trace_reconnect_call(SMARTCARD_DEVICE* smartcard, const Re WLog_LVL(TAG, g_LogLevel, "}"); } -static void smartcard_trace_device_type_id_return(SMARTCARD_DEVICE* smartcard, - const GetDeviceTypeId_Return* ret) +static void smartcard_trace_device_type_id_return(const GetDeviceTypeId_Return* ret) { - WINPR_UNUSED(smartcard); - if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -1511,20 +1432,19 @@ static void smartcard_trace_device_type_id_return(SMARTCARD_DEVICE* smartcard, WLog_LVL(TAG, g_LogLevel, "}"); } -static LONG smartcard_unpack_common_context_and_string_a(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDCONTEXT* phContext, +static LONG smartcard_unpack_common_context_and_string_a(wStream* s, REDIR_SCARDCONTEXT* phContext, CHAR** pszReaderName) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, phContext, &index); + status = smartcard_unpack_redir_scard_context(s, phContext, &index); if (status != SCARD_S_SUCCESS) return status; if (!smartcard_ndr_pointer_read(s, &index, NULL)) return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, phContext); + status = smartcard_unpack_redir_scard_context_ref(s, phContext); if (status != SCARD_S_SUCCESS) return status; @@ -1536,21 +1456,20 @@ static LONG smartcard_unpack_common_context_and_string_a(SMARTCARD_DEVICE* smart return SCARD_S_SUCCESS; } -static LONG smartcard_unpack_common_context_and_string_w(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDCONTEXT* phContext, +static LONG smartcard_unpack_common_context_and_string_w(wStream* s, REDIR_SCARDCONTEXT* phContext, WCHAR** pszReaderName) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, phContext, &index); + status = smartcard_unpack_redir_scard_context(s, phContext, &index); if (status != SCARD_S_SUCCESS) return status; if (!smartcard_ndr_pointer_read(s, &index, NULL)) return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, phContext); + status = smartcard_unpack_redir_scard_context_ref(s, phContext); if (status != SCARD_S_SUCCESS) return status; @@ -1562,13 +1481,12 @@ static LONG smartcard_unpack_common_context_and_string_w(SMARTCARD_DEVICE* smart return SCARD_S_SUCCESS; } -LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s) +LONG smartcard_unpack_common_type_header(wStream* s) { UINT8 version; UINT32 filler; UINT8 endianness; UINT16 commonHeaderLength; - WINPR_UNUSED(smartcard); if (Stream_GetRemainingLength(s) < 8) { @@ -1610,20 +1528,18 @@ LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s return SCARD_S_SUCCESS; } -void smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s) +void smartcard_pack_common_type_header(wStream* s) { - WINPR_UNUSED(smartcard); 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 */ } -LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s) +LONG smartcard_unpack_private_type_header(wStream* s) { UINT32 filler; UINT32 objectBufferLength; - WINPR_UNUSED(smartcard); if (Stream_GetRemainingLength(s) < 8) { @@ -1652,19 +1568,16 @@ LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* return SCARD_S_SUCCESS; } -void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, - UINT32 objectBufferLength) +void smartcard_pack_private_type_header(wStream* s, UINT32 objectBufferLength) { - WINPR_UNUSED(smartcard); Stream_Write_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */ Stream_Write_UINT32(s, 0x00000000); /* Filler (4 bytes), should be 0x00000000 */ } -LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size, - UINT32 alignment) +LONG smartcard_unpack_read_size_align(wStream* s, size_t size, UINT32 alignment) { size_t pad; - WINPR_UNUSED(smartcard); + pad = size; size = (size + alignment - 1) & ~(alignment - 1); pad = size - pad; @@ -1675,11 +1588,10 @@ LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, s return (LONG)pad; } -LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size, - UINT32 alignment) +LONG smartcard_pack_write_size_align(wStream* s, size_t size, UINT32 alignment) { size_t pad; - WINPR_UNUSED(smartcard); + pad = size; size = (size + alignment - 1) & ~(alignment - 1); pad = size - pad; @@ -1698,11 +1610,9 @@ LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, si return SCARD_S_SUCCESS; } -SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard, - REDIR_SCARDCONTEXT* context) +SCARDCONTEXT smartcard_scard_context_native_from_redir(REDIR_SCARDCONTEXT* context) { SCARDCONTEXT hContext = { 0 }; - WINPR_UNUSED(smartcard); if ((context->cbContext != sizeof(ULONG_PTR)) && (context->cbContext != 0)) { @@ -1719,20 +1629,16 @@ SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartca return hContext; } -void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard, - REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext) +void smartcard_scard_context_native_to_redir(REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext) { - WINPR_UNUSED(smartcard); ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT)); context->cbContext = sizeof(ULONG_PTR); CopyMemory(&(context->pbContext), &hContext, context->cbContext); } -SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard, - REDIR_SCARDHANDLE* handle) +SCARDHANDLE smartcard_scard_handle_native_from_redir(REDIR_SCARDHANDLE* handle) { SCARDHANDLE hCard = 0; - WINPR_UNUSED(smartcard); if (handle->cbHandle == 0) return hCard; @@ -1752,21 +1658,18 @@ SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard return hCard; } -void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle, - SCARDHANDLE hCard) +void smartcard_scard_handle_native_to_redir(REDIR_SCARDHANDLE* handle, SCARDHANDLE hCard) { - WINPR_UNUSED(smartcard); ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE)); handle->cbHandle = sizeof(ULONG_PTR); CopyMemory(&(handle->pbHandle), &hCard, handle->cbHandle); } -LONG smartcard_unpack_redir_scard_context_(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDCONTEXT* context, UINT32* index, +LONG smartcard_unpack_redir_scard_context_(wStream* s, REDIR_SCARDCONTEXT* context, UINT32* index, const char* file, const char* function, int line) { UINT32 pbContextNdrPtr; - WINPR_UNUSED(smartcard); + WINPR_UNUSED(file); ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT)); @@ -1816,11 +1719,9 @@ LONG smartcard_unpack_redir_scard_context_(SMARTCARD_DEVICE* smartcard, wStream* return SCARD_S_SUCCESS; } -LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDCONTEXT* context, DWORD* index) +LONG smartcard_pack_redir_scard_context(wStream* s, const REDIR_SCARDCONTEXT* context, DWORD* index) { const UINT32 pbContextNdrPtr = 0x00020000 + *index * 4; - WINPR_UNUSED(smartcard); if (context->cbContext != 0) { @@ -1834,11 +1735,9 @@ LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, return SCARD_S_SUCCESS; } -LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDCONTEXT* context) +LONG smartcard_unpack_redir_scard_context_ref(wStream* s, REDIR_SCARDCONTEXT* context) { UINT32 length; - WINPR_UNUSED(smartcard); if (context->cbContext == 0) return SCARD_S_SUCCESS; @@ -1880,10 +1779,9 @@ LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStre return SCARD_S_SUCCESS; } -LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDCONTEXT* context) +LONG smartcard_pack_redir_scard_context_ref(wStream* s, const REDIR_SCARDCONTEXT* context) { - WINPR_UNUSED(smartcard); + Stream_Write_UINT32(s, context->cbContext); /* Length (4 bytes) */ if (context->cbContext) @@ -1894,11 +1792,9 @@ LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream return SCARD_S_SUCCESS; } -LONG smartcard_unpack_redir_scard_handle_(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDHANDLE* handle, UINT32* index, +LONG smartcard_unpack_redir_scard_handle_(wStream* s, REDIR_SCARDHANDLE* handle, UINT32* index, const char* file, const char* function, int line) { - WINPR_UNUSED(smartcard); ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE)); if (Stream_GetRemainingLength(s) < 4) @@ -1922,11 +1818,9 @@ LONG smartcard_unpack_redir_scard_handle_(SMARTCARD_DEVICE* smartcard, wStream* return SCARD_S_SUCCESS; } -LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDHANDLE* handle, DWORD* index) +LONG smartcard_pack_redir_scard_handle(wStream* s, const REDIR_SCARDHANDLE* handle, DWORD* index) { const UINT32 pbContextNdrPtr = 0x00020000 + *index * 4; - WINPR_UNUSED(smartcard); if (handle->cbHandle != 0) { @@ -1939,11 +1833,9 @@ LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, return SCARD_S_SUCCESS; } -LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, - REDIR_SCARDHANDLE* handle) +LONG smartcard_unpack_redir_scard_handle_ref(wStream* s, REDIR_SCARDHANDLE* handle) { UINT32 length; - WINPR_UNUSED(smartcard); if (Stream_GetRemainingLength(s) < 4) { @@ -1980,10 +1872,9 @@ LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStrea return SCARD_S_SUCCESS; } -LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, - const REDIR_SCARDHANDLE* handle) +LONG smartcard_pack_redir_scard_handle_ref(wStream* s, const REDIR_SCARDHANDLE* handle) { - WINPR_UNUSED(smartcard); + Stream_Write_UINT32(s, handle->cbHandle); /* Length (4 bytes) */ if (handle->cbHandle) @@ -1992,11 +1883,8 @@ LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* return SCARD_S_SUCCESS; } -LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, - EstablishContext_Call* call) +LONG smartcard_unpack_establish_context_call(wStream* s, EstablishContext_Call* call) { - WINPR_UNUSED(smartcard); - if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "EstablishContext_Call is too short: Actual: %" PRIuz ", Expected: 4", @@ -2005,51 +1893,47 @@ LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStrea } Stream_Read_UINT32(s, call->dwScope); /* dwScope (4 bytes) */ - smartcard_trace_establish_context_call(smartcard, call); + smartcard_trace_establish_context_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const EstablishContext_Return* ret) +LONG smartcard_pack_establish_context_return(wStream* s, const EstablishContext_Return* ret) { LONG status; DWORD index = 0; - smartcard_trace_establish_context_return(smartcard, ret); + smartcard_trace_establish_context_return(ret); if (ret->ReturnCode != SCARD_S_SUCCESS) return ret->ReturnCode; - if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext), &index))) + if ((status = smartcard_pack_redir_scard_context(s, &(ret->hContext), &index))) return status; - return smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext)); + return smartcard_pack_redir_scard_context_ref(s, &(ret->hContext)); } -LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call, - const char* name) +LONG smartcard_unpack_context_call(wStream* s, Context_Call* call, const char* name) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", status); - smartcard_trace_context_call(smartcard, call, name); + smartcard_trace_context_call(call, name); return status; } -LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ListReaderGroups_Call* call, BOOL unicode) +LONG smartcard_unpack_list_reader_groups_call(wStream* s, ListReaderGroups_Call* call, BOOL unicode) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2062,23 +1946,23 @@ LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStre Stream_Read_INT32(s, call->fmszGroupsIsNULL); /* fmszGroupsIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cchGroups); /* cchGroups (4 bytes) */ - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)); + status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)); if (status != SCARD_S_SUCCESS) return status; - smartcard_trace_list_reader_groups_call(smartcard, call, unicode); + smartcard_trace_list_reader_groups_call(call, unicode); return SCARD_S_SUCCESS; } -LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const ListReaderGroups_Return* ret, BOOL unicode) +LONG smartcard_pack_list_reader_groups_return(wStream* s, const ListReaderGroups_Return* ret, + BOOL unicode) { LONG status; DWORD cBytes = ret->cBytes; UINT32 index = 0; - smartcard_trace_list_reader_groups_return(smartcard, ret, unicode); + smartcard_trace_list_reader_groups_return(ret, unicode); if (ret->ReturnCode != SCARD_S_SUCCESS) cBytes = 0; if (cBytes == SCARD_AUTOALLOCATE) @@ -2097,15 +1981,14 @@ LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStre return ret->ReturnCode; } -LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ListReaders_Call* call, BOOL unicode) +LONG smartcard_unpack_list_readers_call(wStream* s, ListReaders_Call* call, BOOL unicode) { LONG status; UINT32 index = 0; UINT32 mszGroupsNdrPtr; call->mszGroups = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2121,8 +2004,7 @@ LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, Stream_Read_INT32(s, call->fmszReadersIsNULL); /* fmszReadersIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cchReaders); /* cchReaders (4 bytes) */ - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; if (mszGroupsNdrPtr) @@ -2132,20 +2014,17 @@ LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, return status; } - smartcard_trace_list_readers_call(smartcard, call, unicode); + smartcard_trace_list_readers_call(call, unicode); return SCARD_S_SUCCESS; } -LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const ListReaders_Return* ret, BOOL unicode) +LONG smartcard_pack_list_readers_return(wStream* s, const ListReaders_Return* ret, BOOL unicode) { LONG status; UINT32 index = 0; - UINT32 size = unicode ? sizeof(WCHAR) : sizeof(CHAR); + UINT32 size = ret->cBytes; - size *= ret->cBytes; - - smartcard_trace_list_readers_return(smartcard, ret, unicode); + smartcard_trace_list_readers_return(ret, unicode); if (ret->ReturnCode != SCARD_S_SUCCESS) size = 0; @@ -2165,12 +2044,11 @@ LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, return ret->ReturnCode; } -static LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream* s, - Connect_Common_Call* common, UINT32* index) +static LONG smartcard_unpack_connect_common(wStream* s, Connect_Common_Call* common, UINT32* index) { LONG status; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(common->handles.hContext), index); + status = smartcard_unpack_redir_scard_context(s, &(common->handles.hContext), index); if (status != SCARD_S_SUCCESS) return status; @@ -2185,7 +2063,7 @@ static LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream return SCARD_S_SUCCESS; } -LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call) +LONG smartcard_unpack_connect_a_call(wStream* s, ConnectA_Call* call) { LONG status; UINT32 index = 0; @@ -2194,7 +2072,7 @@ LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co if (!smartcard_ndr_pointer_read(s, &index, NULL)) return ERROR_INVALID_DATA; - if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common), &index))) + if ((status = smartcard_unpack_connect_common(s, &(call->Common), &index))) { WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %" PRId32 "", status); return status; @@ -2204,16 +2082,15 @@ LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co if (status != SCARD_S_SUCCESS) return status; - if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, - &(call->Common.handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->Common.handles.hContext)))) WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", status); - smartcard_trace_connect_a_call(smartcard, call); + smartcard_trace_connect_a_call(call); return status; } -LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call) +LONG smartcard_unpack_connect_w_call(wStream* s, ConnectW_Call* call) { LONG status; UINT32 index = 0; @@ -2223,7 +2100,7 @@ LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co if (!smartcard_ndr_pointer_read(s, &index, NULL)) return ERROR_INVALID_DATA; - if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common), &index))) + if ((status = smartcard_unpack_connect_common(s, &(call->Common), &index))) { WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %" PRId32 "", status); return status; @@ -2233,28 +2110,26 @@ LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co if (status != SCARD_S_SUCCESS) return status; - if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, - &(call->Common.handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->Common.handles.hContext)))) WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", status); - smartcard_trace_connect_w_call(smartcard, call); + smartcard_trace_connect_w_call(call); return status; } -LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const Connect_Return* ret) +LONG smartcard_pack_connect_return(wStream* s, const Connect_Return* ret) { LONG status; DWORD index = 0; - smartcard_trace_connect_return(smartcard, ret); + smartcard_trace_connect_return(ret); - status = smartcard_pack_redir_scard_context(smartcard, s, &ret->hContext, &index); + status = smartcard_pack_redir_scard_context(s, &ret->hContext, &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_pack_redir_scard_handle(smartcard, s, &ret->hCard, &index); + status = smartcard_pack_redir_scard_handle(s, &ret->hCard, &index); if (status != SCARD_S_SUCCESS) return status; @@ -2262,22 +2137,22 @@ LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, return SCARD_E_NO_MEMORY; Stream_Write_UINT32(s, ret->dwActiveProtocol); /* dwActiveProtocol (4 bytes) */ - status = smartcard_pack_redir_scard_context_ref(smartcard, s, &ret->hContext); + status = smartcard_pack_redir_scard_context_ref(s, &ret->hContext); if (status != SCARD_S_SUCCESS) return status; - return smartcard_pack_redir_scard_handle_ref(smartcard, s, &(ret->hCard)); + return smartcard_pack_redir_scard_handle_ref(s, &(ret->hCard)); } -LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call) +LONG smartcard_unpack_reconnect_call(wStream* s, Reconnect_Call* call) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2291,26 +2166,24 @@ LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Re Stream_Read_UINT32(s, call->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */ Stream_Read_UINT32(s, call->dwInitialization); /* dwInitialization (4 bytes) */ - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) { WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", status); return status; } - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", status); - smartcard_trace_reconnect_call(smartcard, call); + smartcard_trace_reconnect_call(call); return status; } -LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const Reconnect_Return* ret) +LONG smartcard_pack_reconnect_return(wStream* s, const Reconnect_Return* ret) { - smartcard_trace_reconnect_return(smartcard, ret); + smartcard_trace_reconnect_return(ret); if (!Stream_EnsureRemainingCapacity(s, 4)) return SCARD_E_NO_MEMORY; @@ -2318,17 +2191,17 @@ LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, return ret->ReturnCode; } -LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, - HCardAndDisposition_Call* call, const char* name) +LONG smartcard_unpack_hcard_and_disposition_call(wStream* s, HCardAndDisposition_Call* call, + const char* name) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2341,25 +2214,22 @@ LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wS Stream_Read_UINT32(s, call->dwDisposition); /* dwDisposition (4 bytes) */ - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) return status; - smartcard_trace_hcard_and_disposition_call(smartcard, call, name); + smartcard_trace_hcard_and_disposition_call(call, name); return status; } -static void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, - const GetStatusChangeA_Call* call) +static void smartcard_trace_get_status_change_a_call(const GetStatusChangeA_Call* call) { UINT32 index; char* szEventState; char* szCurrentState; LPSCARD_READERSTATEA readerState; - WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -2549,15 +2419,14 @@ fail: /************************************* End Trace Functions ********************/ /******************************************************************************/ -LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetStatusChangeA_Call* call) +LONG smartcard_unpack_get_status_change_a_call(wStream* s, GetStatusChangeA_Call* call) { LONG status; UINT32 ndrPtr; UINT32 index = 0; call->rgReaderStates = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2573,8 +2442,7 @@ LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStr if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr)) return ERROR_INVALID_DATA; - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; if (ndrPtr) @@ -2584,12 +2452,11 @@ LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStr return status; } - smartcard_trace_get_status_change_a_call(smartcard, call); + smartcard_trace_get_status_change_a_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetStatusChangeW_Call* call) +LONG smartcard_unpack_get_status_change_w_call(wStream* s, GetStatusChangeW_Call* call) { UINT32 ndrPtr; LONG status; @@ -2597,7 +2464,7 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr call->rgReaderStates = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2613,8 +2480,7 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr)) return ERROR_INVALID_DATA; - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; if (ndrPtr) @@ -2624,18 +2490,18 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr return status; } - smartcard_trace_get_status_change_w_call(smartcard, call); + smartcard_trace_get_status_change_w_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetStatusChange_Return* ret, BOOL unicode) +LONG smartcard_pack_get_status_change_return(wStream* s, const GetStatusChange_Return* ret, + BOOL unicode) { LONG status; DWORD cReaders = ret->cReaders; UINT32 index = 0; - smartcard_trace_get_status_change_return(smartcard, ret, unicode); + smartcard_trace_get_status_change_return(ret, unicode); if (ret->ReturnCode != SCARD_S_SUCCESS) cReaders = 0; if (cReaders == SCARD_AUTOALLOCATE) @@ -2653,16 +2519,16 @@ LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStrea return ret->ReturnCode; } -LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call) +LONG smartcard_unpack_state_call(wStream* s, State_Call* call) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2675,23 +2541,22 @@ LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_ Stream_Read_INT32(s, call->fpbAtrIsNULL); /* fpbAtrIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cbAtrLen); /* cbAtrLen (4 bytes) */ - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) return status; return status; } -LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, const State_Return* ret) +LONG smartcard_pack_state_return(wStream* s, const State_Return* ret) { LONG status; DWORD cbAtrLen = ret->cbAtrLen; UINT32 index = 0; - smartcard_trace_state_return(smartcard, ret); + smartcard_trace_state_return(ret); if (ret->ReturnCode != SCARD_S_SUCCESS) cbAtrLen = 0; if (cbAtrLen == SCARD_AUTOALLOCATE) @@ -2708,16 +2573,15 @@ LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, const return ret->ReturnCode; } -LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call, - BOOL unicode) +LONG smartcard_unpack_status_call(wStream* s, Status_Call* call, BOOL unicode) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2731,25 +2595,23 @@ LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Statu Stream_Read_UINT32(s, call->cchReaderLen); /* cchReaderLen (4 bytes) */ Stream_Read_UINT32(s, call->cbAtrLen); /* cbAtrLen (4 bytes) */ - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) return status; - smartcard_trace_status_call(smartcard, call, unicode); + smartcard_trace_status_call(call, unicode); return status; } -LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, const Status_Return* ret, - BOOL unicode) +LONG smartcard_pack_status_return(wStream* s, const Status_Return* ret, BOOL unicode) { LONG status; UINT32 index = 0; DWORD cBytes = ret->cBytes; - smartcard_trace_status_return(smartcard, ret, unicode); + smartcard_trace_status_return(ret, unicode); if (ret->ReturnCode != SCARD_S_SUCCESS) cBytes = 0; if (cBytes == SCARD_AUTOALLOCATE) @@ -2775,16 +2637,16 @@ LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, const return ret->ReturnCode; } -LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Call* call) +LONG smartcard_unpack_get_attrib_call(wStream* s, GetAttrib_Call* call) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2798,25 +2660,23 @@ LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, G Stream_Read_INT32(s, call->fpbAttrIsNULL); /* fpbAttrIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cbAttrLen); /* cbAttrLen (4 bytes) */ - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) return status; - smartcard_trace_get_attrib_call(smartcard, call); + smartcard_trace_get_attrib_call(call); return status; } -LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetAttrib_Return* ret, DWORD dwAttrId, +LONG smartcard_pack_get_attrib_return(wStream* s, const GetAttrib_Return* ret, DWORD dwAttrId, DWORD cbAttrCallLen) { LONG status; DWORD cbAttrLen; UINT32 index = 0; - smartcard_trace_get_attrib_return(smartcard, ret, dwAttrId); + smartcard_trace_get_attrib_return(ret, dwAttrId); if (!Stream_EnsureRemainingCapacity(s, 4)) return SCARD_F_INTERNAL_ERROR; @@ -2842,7 +2702,7 @@ LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, return ret->ReturnCode; } -LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call) +LONG smartcard_unpack_control_call(wStream* s, Control_Call* call) { LONG status; UINT32 index = 0; @@ -2850,11 +2710,11 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont call->pvInBuffer = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2871,11 +2731,10 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont Stream_Read_INT32(s, call->fpvOutBufferIsNULL); /* fpvOutBufferIsNULL (4 bytes) */ Stream_Read_UINT32(s, call->cbOutBufferSize); /* cbOutBufferSize (4 bytes) */ - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) return status; if (pvInBufferNdrPtr) @@ -2885,18 +2744,17 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont return status; } - smartcard_trace_control_call(smartcard, call); + smartcard_trace_control_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const Control_Return* ret) +LONG smartcard_pack_control_return(wStream* s, const Control_Return* ret) { LONG status; DWORD cbDataLen = ret->cbOutBufferSize; UINT32 index = 0; - smartcard_trace_control_return(smartcard, ret); + smartcard_trace_control_return(ret); if (ret->ReturnCode != SCARD_S_SUCCESS) cbDataLen = 0; if (cbDataLen == SCARD_AUTOALLOCATE) @@ -2915,7 +2773,7 @@ LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, return ret->ReturnCode; } -LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call) +LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call) { LONG status; UINT32 length; @@ -2930,11 +2788,11 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra call->pioRecvPci = NULL; call->pbSendBuffer = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; @@ -2977,11 +2835,10 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra return STATUS_INVALID_PARAMETER; } - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) return status; if (ioSendPci.cbExtraBytes && !pbExtraBytesNdrPtr) @@ -3026,7 +2883,7 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra call->pioSendPci->cbPciLength = (DWORD)(ioSendPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST)); pbExtraBytes = &((BYTE*)call->pioSendPci)[sizeof(SCARD_IO_REQUEST)]; Stream_Read(s, pbExtraBytes, ioSendPci.cbExtraBytes); - smartcard_unpack_read_size_align(smartcard, s, ioSendPci.cbExtraBytes, 4); + smartcard_unpack_read_size_align(s, ioSendPci.cbExtraBytes, 4); } else { @@ -3126,7 +2983,7 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra (DWORD)(ioRecvPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST)); pbExtraBytes = &((BYTE*)call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; Stream_Read(s, pbExtraBytes, ioRecvPci.cbExtraBytes); - smartcard_unpack_read_size_align(smartcard, s, ioRecvPci.cbExtraBytes, 4); + smartcard_unpack_read_size_align(s, ioRecvPci.cbExtraBytes, 4); } else { @@ -3143,12 +3000,11 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra } } - smartcard_trace_transmit_call(smartcard, call); + smartcard_trace_transmit_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const Transmit_Return* ret) +LONG smartcard_pack_transmit_return(wStream* s, const Transmit_Return* ret) { LONG status; UINT32 index = 0; @@ -3156,7 +3012,7 @@ LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 cbRecvLength = ret->cbRecvLength; UINT32 cbRecvPci = ret->pioRecvPci ? ret->pioRecvPci->cbPciLength : 0; - smartcard_trace_transmit_return(smartcard, ret); + smartcard_trace_transmit_return(ret); if (!ret->pbRecvBuffer) cbRecvLength = 0; @@ -3195,8 +3051,7 @@ LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, return ret->ReturnCode; } -LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - LocateCardsByATRA_Call* call) +LONG smartcard_unpack_locate_cards_by_atr_a_call(wStream* s, LocateCardsByATRA_Call* call) { LONG status; UINT32 rgReaderStatesNdrPtr; @@ -3204,7 +3059,7 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS UINT32 index = 0; call->rgReaderStates = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3222,8 +3077,7 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS if (!smartcard_ndr_pointer_read(s, &index, &rgReaderStatesNdrPtr)) return ERROR_INVALID_DATA; - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs)) @@ -3249,18 +3103,17 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS return status; } - smartcard_trace_locate_cards_by_atr_a_call(smartcard, call); + smartcard_trace_locate_cards_by_atr_a_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ContextAndTwoStringA_Call* call) +LONG smartcard_unpack_context_and_two_strings_a_call(wStream* s, ContextAndTwoStringA_Call* call) { LONG status; UINT32 sz1NdrPtr, sz2NdrPtr; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3269,7 +3122,7 @@ LONG smartcard_unpack_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr)) return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->handles.hContext); + status = smartcard_unpack_redir_scard_context_ref(s, &call->handles.hContext); if (status != SCARD_S_SUCCESS) return status; @@ -3285,17 +3138,16 @@ LONG smartcard_unpack_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_context_and_two_strings_a_call(smartcard, call); + smartcard_trace_context_and_two_strings_a_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ContextAndTwoStringW_Call* call) +LONG smartcard_unpack_context_and_two_strings_w_call(wStream* s, ContextAndTwoStringW_Call* call) { LONG status; UINT32 sz1NdrPtr, sz2NdrPtr; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3304,7 +3156,7 @@ LONG smartcard_unpack_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr)) return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->handles.hContext); + status = smartcard_unpack_redir_scard_context_ref(s, &call->handles.hContext); if (status != SCARD_S_SUCCESS) return status; @@ -3320,17 +3172,16 @@ LONG smartcard_unpack_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_context_and_two_strings_w_call(smartcard, call); + smartcard_trace_context_and_two_strings_w_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - LocateCardsA_Call* call) +LONG smartcard_unpack_locate_cards_a_call(wStream* s, LocateCardsA_Call* call) { LONG status; UINT32 sz1NdrPtr, sz2NdrPtr; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3360,18 +3211,17 @@ LONG smartcard_unpack_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, wStream* if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_locate_cards_a_call(smartcard, call); + smartcard_trace_locate_cards_a_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - LocateCardsW_Call* call) +LONG smartcard_unpack_locate_cards_w_call(wStream* s, LocateCardsW_Call* call) { LONG status; UINT32 sz1NdrPtr, sz2NdrPtr; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3401,20 +3251,20 @@ LONG smartcard_unpack_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, wStream* if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_locate_cards_w_call(smartcard, call); + smartcard_trace_locate_cards_w_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_set_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, SetAttrib_Call* call) +LONG smartcard_unpack_set_attrib_call(wStream* s, SetAttrib_Call* call) { LONG status; UINT32 index = 0; UINT32 ndrPtr; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3426,11 +3276,10 @@ LONG smartcard_unpack_set_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, S if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr)) return ERROR_INVALID_DATA; - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) return status; if (ndrPtr) @@ -3441,12 +3290,11 @@ LONG smartcard_unpack_set_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, S if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_set_attrib_call(smartcard, call); + smartcard_trace_set_attrib_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - LocateCardsByATRW_Call* call) +LONG smartcard_unpack_locate_cards_by_atr_w_call(wStream* s, LocateCardsByATRW_Call* call) { LONG status; UINT32 rgReaderStatesNdrPtr; @@ -3454,7 +3302,7 @@ LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wS UINT32 index = 0; call->rgReaderStates = NULL; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3473,8 +3321,7 @@ LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wS if (!smartcard_ndr_pointer_read(s, &index, &rgReaderStatesNdrPtr)) return ERROR_INVALID_DATA; - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) return status; if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs)) @@ -3500,12 +3347,11 @@ LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wS return status; } - smartcard_trace_locate_cards_by_atr_w_call(smartcard, call); + smartcard_trace_locate_cards_by_atr_w_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ReadCacheA_Call* call) +LONG smartcard_unpack_read_cache_a_call(wStream* s, ReadCacheA_Call* call) { LONG status; UINT32 mszNdrPtr; @@ -3515,8 +3361,7 @@ LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr)) return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.handles.hContext), - &index); + status = smartcard_unpack_redir_scard_context(s, &(call->Common.handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3537,7 +3382,7 @@ LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, return status; } - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.handles.hContext); + status = smartcard_unpack_redir_scard_context_ref(s, &call->Common.handles.hContext); if (status != SCARD_S_SUCCESS) return status; @@ -3547,12 +3392,11 @@ LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_read_cache_a_call(smartcard, call); + smartcard_trace_read_cache_a_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ReadCacheW_Call* call) +LONG smartcard_unpack_read_cache_w_call(wStream* s, ReadCacheW_Call* call) { LONG status; UINT32 mszNdrPtr; @@ -3562,8 +3406,7 @@ LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr)) return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.handles.hContext), - &index); + status = smartcard_unpack_redir_scard_context(s, &(call->Common.handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3584,7 +3427,7 @@ LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, return status; } - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.handles.hContext); + status = smartcard_unpack_redir_scard_context_ref(s, &call->Common.handles.hContext); if (status != SCARD_S_SUCCESS) return status; @@ -3594,12 +3437,11 @@ LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_read_cache_w_call(smartcard, call); + smartcard_trace_read_cache_w_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_write_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - WriteCacheA_Call* call) +LONG smartcard_unpack_write_cache_a_call(wStream* s, WriteCacheA_Call* call) { LONG status; UINT32 mszNdrPtr; @@ -3610,8 +3452,7 @@ LONG smartcard_unpack_write_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr)) return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.handles.hContext), - &index); + status = smartcard_unpack_redir_scard_context(s, &(call->Common.handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3635,7 +3476,7 @@ LONG smartcard_unpack_write_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s return status; } - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.handles.hContext); + status = smartcard_unpack_redir_scard_context_ref(s, &call->Common.handles.hContext); if (status != SCARD_S_SUCCESS) return status; @@ -3655,12 +3496,11 @@ LONG smartcard_unpack_write_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_write_cache_a_call(smartcard, call); + smartcard_trace_write_cache_a_call(call); return SCARD_S_SUCCESS; } -LONG smartcard_unpack_write_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - WriteCacheW_Call* call) +LONG smartcard_unpack_write_cache_w_call(wStream* s, WriteCacheW_Call* call) { LONG status; UINT32 mszNdrPtr; @@ -3671,8 +3511,7 @@ LONG smartcard_unpack_write_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr)) return ERROR_INVALID_DATA; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.handles.hContext), - &index); + status = smartcard_unpack_redir_scard_context(s, &(call->Common.handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; @@ -3695,7 +3534,7 @@ LONG smartcard_unpack_write_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s return status; } - status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.handles.hContext); + status = smartcard_unpack_redir_scard_context_ref(s, &call->Common.handles.hContext); if (status != SCARD_S_SUCCESS) return status; @@ -3715,72 +3554,63 @@ LONG smartcard_unpack_write_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s if (status != SCARD_S_SUCCESS) return status; } - smartcard_trace_write_cache_w_call(smartcard, call); + smartcard_trace_write_cache_w_call(call); return status; } -LONG smartcard_unpack_get_transmit_count_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetTransmitCount_Call* call) +LONG smartcard_unpack_get_transmit_count_call(wStream* s, GetTransmitCount_Call* call) { LONG status; UINT32 index = 0; - status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index); + status = smartcard_unpack_redir_scard_context(s, &(call->handles.hContext), &index); if (status != SCARD_S_SUCCESS) return status; - status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index); + status = smartcard_unpack_redir_scard_handle(s, &(call->handles.hCard), &index); if (status != SCARD_S_SUCCESS) return status; - if ((status = - smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext)))) + if ((status = smartcard_unpack_redir_scard_context_ref(s, &(call->handles.hContext)))) { WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "", status); return status; } - if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard)))) + if ((status = smartcard_unpack_redir_scard_handle_ref(s, &(call->handles.hCard)))) WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", status); - smartcard_trace_get_transmit_count_call(smartcard, call); + smartcard_trace_get_transmit_count_call(call); return status; } -LONG smartcard_unpack_get_reader_icon_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetReaderIcon_Call* call) +LONG smartcard_unpack_get_reader_icon_call(wStream* s, GetReaderIcon_Call* call) { - return smartcard_unpack_common_context_and_string_w(smartcard, s, &call->handles.hContext, + return smartcard_unpack_common_context_and_string_w(s, &call->handles.hContext, &call->szReaderName); } -LONG smartcard_unpack_context_and_string_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ContextAndStringA_Call* call) +LONG smartcard_unpack_context_and_string_a_call(wStream* s, ContextAndStringA_Call* call) { - return smartcard_unpack_common_context_and_string_a(smartcard, s, &call->handles.hContext, - &call->sz); + return smartcard_unpack_common_context_and_string_a(s, &call->handles.hContext, &call->sz); } -LONG smartcard_unpack_context_and_string_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, - ContextAndStringW_Call* call) +LONG smartcard_unpack_context_and_string_w_call(wStream* s, ContextAndStringW_Call* call) { - return smartcard_unpack_common_context_and_string_w(smartcard, s, &call->handles.hContext, - &call->sz); + return smartcard_unpack_common_context_and_string_w(s, &call->handles.hContext, &call->sz); } -LONG smartcard_unpack_get_device_type_id_call(SMARTCARD_DEVICE* smartcard, wStream* s, - GetDeviceTypeId_Call* call) +LONG smartcard_unpack_get_device_type_id_call(wStream* s, GetDeviceTypeId_Call* call) { - return smartcard_unpack_common_context_and_string_w(smartcard, s, &call->handles.hContext, + return smartcard_unpack_common_context_and_string_w(s, &call->handles.hContext, &call->szReaderName); } -LONG smartcard_pack_device_type_id_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetDeviceTypeId_Return* ret) +LONG smartcard_pack_device_type_id_return(wStream* s, const GetDeviceTypeId_Return* ret) { - smartcard_trace_device_type_id_return(smartcard, ret); + smartcard_trace_device_type_id_return(ret); if (!Stream_EnsureRemainingCapacity(s, 4)) { @@ -3793,14 +3623,13 @@ LONG smartcard_pack_device_type_id_return(SMARTCARD_DEVICE* smartcard, wStream* return ret->ReturnCode; } -LONG smartcard_pack_locate_cards_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const LocateCards_Return* ret) +LONG smartcard_pack_locate_cards_return(wStream* s, const LocateCards_Return* ret) { LONG status; DWORD cbDataLen = ret->cReaders; UINT32 index = 0; - smartcard_trace_locate_cards_return(smartcard, ret); + smartcard_trace_locate_cards_return(ret); if (ret->ReturnCode != SCARD_S_SUCCESS) cbDataLen = 0; if (cbDataLen == SCARD_AUTOALLOCATE) @@ -3822,13 +3651,12 @@ LONG smartcard_pack_locate_cards_return(SMARTCARD_DEVICE* smartcard, wStream* s, return ret->ReturnCode; } -LONG smartcard_pack_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetReaderIcon_Return* ret) +LONG smartcard_pack_get_reader_icon_return(wStream* s, const GetReaderIcon_Return* ret) { LONG status; UINT32 index = 0; DWORD cbDataLen = ret->cbDataLen; - smartcard_trace_get_reader_icon_return(smartcard, ret); + smartcard_trace_get_reader_icon_return(ret); if (ret->ReturnCode != SCARD_S_SUCCESS) cbDataLen = 0; if (cbDataLen == SCARD_AUTOALLOCATE) @@ -3850,10 +3678,9 @@ LONG smartcard_pack_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, wStream* return ret->ReturnCode; } -LONG smartcard_pack_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const GetTransmitCount_Return* ret) +LONG smartcard_pack_get_transmit_count_return(wStream* s, const GetTransmitCount_Return* ret) { - smartcard_trace_get_transmit_count_return(smartcard, ret); + smartcard_trace_get_transmit_count_return(ret); if (!Stream_EnsureRemainingCapacity(s, 4)) { @@ -3866,13 +3693,12 @@ LONG smartcard_pack_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, wStre return ret->ReturnCode; } -LONG smartcard_pack_read_cache_return(SMARTCARD_DEVICE* smartcard, wStream* s, - const ReadCache_Return* ret) +LONG smartcard_pack_read_cache_return(wStream* s, const ReadCache_Return* ret) { LONG status; UINT32 index = 0; DWORD cbDataLen = ret->cbDataLen; - smartcard_trace_read_cache_return(smartcard, ret); + smartcard_trace_read_cache_return(ret); if (ret->ReturnCode != SCARD_S_SUCCESS) cbDataLen = 0;