mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 08:24:16 +09:00
[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.
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user