From 43f30eb03c7cce2c59da1998e989ffd82bf7eab1 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 20 Feb 2026 10:00:21 +0100 Subject: [PATCH] [channels,smartcard] refactor channel handling * Eliminate global sSmartcard instance * Add logging to device create/init/destroy * Add logging to context create/destroy * Do not release context when a device is initialized. --- channels/smartcard/client/smartcard_main.c | 161 ++++++++++----------- 1 file changed, 73 insertions(+), 88 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 1c315b930..2bbc378a4 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -45,8 +45,6 @@ typedef struct 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, BOOL* handled); @@ -178,9 +176,9 @@ static void smartcard_operation_queue_free(void* obj) static void* smartcard_context_new(void* smartcard, SCARDCONTEXT hContext) { - SMARTCARD_CONTEXT* pContext = NULL; - pContext = (SMARTCARD_CONTEXT*)calloc(1, sizeof(SMARTCARD_CONTEXT)); + SMARTCARD_CONTEXT* pContext = (SMARTCARD_CONTEXT*)calloc(1, sizeof(SMARTCARD_CONTEXT)); + WLog_VRB(TAG, "smartcard context create %p", (const void*)pContext); if (!pContext) { WLog_ERR(TAG, "calloc failed!"); @@ -221,6 +219,7 @@ void smartcard_context_free(void* pCtx) { SMARTCARD_CONTEXT* pContext = pCtx; + WLog_VRB(TAG, "smartcard context destroy %p", pCtx); if (!pContext) return; @@ -243,11 +242,6 @@ void smartcard_context_free(void* pCtx) free(pContext); } -static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) -{ - smartcard_call_cancel_all_context(smartcard->callctx); -} - static UINT smartcard_free_(SMARTCARD_DEVICE* smartcard) { if (!smartcard) @@ -276,6 +270,7 @@ static UINT smartcard_free(DEVICE* device) { SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(device); + WLog_VRB(TAG, "smartcard device destroy: %p", (const void*)smartcard); if (!smartcard) return ERROR_INVALID_PARAMETER; @@ -283,7 +278,7 @@ static UINT smartcard_free(DEVICE* device) * Calling smartcard_release_all_contexts to unblock all operations waiting for transactions * to unlock. */ - smartcard_release_all_contexts(smartcard); + smartcard_call_cancel_all_context(smartcard->callctx); /* Stopping all threads and cancelling all IRPs */ @@ -298,9 +293,6 @@ static UINT smartcard_free(DEVICE* device) } } - if (sSmartcard == smartcard) - sSmartcard = NULL; - return smartcard_free_(smartcard); } @@ -318,10 +310,10 @@ static UINT smartcard_init(DEVICE* device) { SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(device); + WLog_VRB(TAG, "smartcard device init %p", (const void*)smartcard); if (!smartcard) return ERROR_INVALID_PARAMETER; - smartcard_release_all_contexts(smartcard); return CHANNEL_RC_OK; } @@ -636,84 +628,78 @@ static void smartcard_free_irp(void* obj) */ FREERDP_ENTRY_POINT(UINT VCAPITYPE DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)) { - SMARTCARD_DEVICE* smartcard = NULL; size_t length = 0; UINT error = CHANNEL_RC_NO_MEMORY; - if (!sSmartcard) + SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*)calloc(1, sizeof(SMARTCARD_DEVICE)); + WLog_VRB(TAG, "smartcard device create: %p", (const void*)smartcard); + if (!smartcard) { - smartcard = (SMARTCARD_DEVICE*)calloc(1, sizeof(SMARTCARD_DEVICE)); - - if (!smartcard) - { - WLog_ERR(TAG, "calloc failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - smartcard->device.type = RDPDR_DTYP_SMARTCARD; - smartcard->device.name = "SCARD"; - smartcard->device.IRPRequest = smartcard_irp_request; - smartcard->device.Init = smartcard_init; - smartcard->device.Free = smartcard_free; - smartcard->rdpcontext = pEntryPoints->rdpcontext; - length = strlen(smartcard->device.name); - smartcard->device.data = Stream_New(NULL, length + 1); - - if (!smartcard->device.data) - { - WLog_ERR(TAG, "Stream_New failed!"); - goto fail; - } - - Stream_Write(smartcard->device.data, "SCARD", 6); - smartcard->IrpQueue = MessageQueue_New(NULL); - - if (!smartcard->IrpQueue) - { - WLog_ERR(TAG, "MessageQueue_New failed!"); - goto fail; - } - - wObject* obj = MessageQueue_Object(smartcard->IrpQueue); - WINPR_ASSERT(obj); - obj->fnObjectFree = smartcard_free_irp; - - smartcard->rgOutstandingMessages = ListDictionary_New(TRUE); - - if (!smartcard->rgOutstandingMessages) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - goto fail; - } - - smartcard->callctx = smartcard_call_context_new(smartcard->rdpcontext->settings); - if (!smartcard->callctx) - goto fail; - - 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!"); - goto fail; - } - - smartcard->thread = - CreateThread(NULL, 0, smartcard_thread_func, smartcard, CREATE_SUSPENDED, NULL); - - if (!smartcard->thread) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - error = ERROR_INTERNAL_ERROR; - goto fail; - } - - ResumeThread(smartcard->thread); + WLog_ERR(TAG, "calloc failed!"); + return CHANNEL_RC_NO_MEMORY; } - else - smartcard = sSmartcard; + + smartcard->device.type = RDPDR_DTYP_SMARTCARD; + smartcard->device.name = "SCARD"; + smartcard->device.IRPRequest = smartcard_irp_request; + smartcard->device.Init = smartcard_init; + smartcard->device.Free = smartcard_free; + smartcard->rdpcontext = pEntryPoints->rdpcontext; + length = strlen(smartcard->device.name); + smartcard->device.data = Stream_New(NULL, length + 1); + + if (!smartcard->device.data) + { + WLog_ERR(TAG, "Stream_New failed!"); + goto fail; + } + + Stream_Write(smartcard->device.data, "SCARD", 6); + smartcard->IrpQueue = MessageQueue_New(NULL); + + if (!smartcard->IrpQueue) + { + WLog_ERR(TAG, "MessageQueue_New failed!"); + goto fail; + } + + wObject* obj = MessageQueue_Object(smartcard->IrpQueue); + WINPR_ASSERT(obj); + obj->fnObjectFree = smartcard_free_irp; + + smartcard->rgOutstandingMessages = ListDictionary_New(TRUE); + + if (!smartcard->rgOutstandingMessages) + { + WLog_ERR(TAG, "ListDictionary_New failed!"); + goto fail; + } + + smartcard->callctx = smartcard_call_context_new(smartcard->rdpcontext->settings); + if (!smartcard->callctx) + goto fail; + + 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!"); + goto fail; + } + + smartcard->thread = + CreateThread(NULL, 0, smartcard_thread_func, smartcard, CREATE_SUSPENDED, NULL); + + if (!smartcard->thread) + { + WLog_ERR(TAG, "CreateThread failed!"); + error = ERROR_INTERNAL_ERROR; + goto fail; + } + + ResumeThread(smartcard->thread); if (pEntryPoints->device->Name) { @@ -721,7 +707,6 @@ FREERDP_ENTRY_POINT(UINT VCAPITYPE DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POIN goto fail; } - sSmartcard = smartcard; return CHANNEL_RC_OK; fail: smartcard_free_(smartcard);