mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 00:14:11 +09:00
Merge pull request #12340 from akallabeth/smartcard-stop-fix
Smartcard stop fix
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);
|
||||
@@ -76,7 +74,6 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg)
|
||||
{
|
||||
SMARTCARD_CONTEXT* pContext = (SMARTCARD_CONTEXT*)arg;
|
||||
DWORD nCount = 0;
|
||||
LONG status = 0;
|
||||
DWORD waitStatus = 0;
|
||||
HANDLE hEvents[2] = { 0 };
|
||||
wMessage message = { 0 };
|
||||
@@ -113,7 +110,7 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg)
|
||||
if (!MessageQueue_Peek(pContext->IrpQueue, &message, TRUE))
|
||||
{
|
||||
WLog_ERR(TAG, "MessageQueue_Peek failed!");
|
||||
status = ERROR_INTERNAL_ERROR;
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -127,14 +124,17 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg)
|
||||
BOOL handled = FALSE;
|
||||
WINPR_ASSERT(smartcard);
|
||||
|
||||
if ((status = smartcard_irp_device_control_call(
|
||||
smartcard->callctx, element->irp->output, &element->irp->IoStatus,
|
||||
&element->operation)))
|
||||
const LONG status =
|
||||
smartcard_irp_device_control_call(smartcard->callctx, element->irp->output,
|
||||
&element->irp->IoStatus, &element->operation);
|
||||
if (status)
|
||||
{
|
||||
element->irp->Discard(element->irp);
|
||||
smartcard_operation_free(&element->operation, TRUE);
|
||||
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %" PRId32 "",
|
||||
status);
|
||||
WLog_ERR(TAG,
|
||||
"smartcard_irp_device_control_call failed with error %s [%" PRId32 "]",
|
||||
NtStatus2Tag(status), status);
|
||||
error = (UINT)status;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -145,17 +145,18 @@ static DWORD WINAPI smartcard_context_thread(LPVOID arg)
|
||||
|
||||
if (error)
|
||||
{
|
||||
WLog_ERR(TAG, "Queue_Enqueue failed!");
|
||||
WLog_ERR(TAG, "smartcard_complete_irp failed with %s [%" PRIu32 "]",
|
||||
WTSErrorToString(error), error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status && smartcard->rdpcontext)
|
||||
if (error && smartcard->rdpcontext)
|
||||
setChannelError(smartcard->rdpcontext, error, "smartcard_context_thread reported an error");
|
||||
|
||||
ExitThread((uint32_t)status);
|
||||
ExitThread(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -178,9 +179,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 +222,7 @@ void smartcard_context_free(void* pCtx)
|
||||
{
|
||||
SMARTCARD_CONTEXT* pContext = pCtx;
|
||||
|
||||
WLog_VRB(TAG, "smartcard context destroy %p", pCtx);
|
||||
if (!pContext)
|
||||
return;
|
||||
|
||||
@@ -243,11 +245,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 +273,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 +281,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 +296,6 @@ static UINT smartcard_free(DEVICE* device)
|
||||
}
|
||||
}
|
||||
|
||||
if (sSmartcard == smartcard)
|
||||
sSmartcard = NULL;
|
||||
|
||||
return smartcard_free_(smartcard);
|
||||
}
|
||||
|
||||
@@ -318,10 +313,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 +631,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 +710,6 @@ FREERDP_ENTRY_POINT(UINT VCAPITYPE DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POIN
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sSmartcard = smartcard;
|
||||
return CHANNEL_RC_OK;
|
||||
fail:
|
||||
smartcard_free_(smartcard);
|
||||
|
||||
@@ -581,8 +581,7 @@ static UINT urb_select_configuration(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* c
|
||||
/* [MS-RDPEUSB[ 2.2.10.3 TS_URB_SELECT_INTERFACE_RESULT */
|
||||
static UINT urb_select_interface_result(GENERIC_CHANNEL_CALLBACK* callback, UINT32 RequestId,
|
||||
UINT32 InterfaceId, UINT32 MessageId,
|
||||
MSUSB_INTERFACE_DESCRIPTOR* MsInterface,
|
||||
UINT32 ConfigurationHandle)
|
||||
MSUSB_INTERFACE_DESCRIPTOR* MsInterface)
|
||||
{
|
||||
WINPR_ASSERT(callback);
|
||||
WINPR_ASSERT(MsInterface);
|
||||
@@ -681,8 +680,7 @@ static UINT urb_select_interface(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callb
|
||||
if (noAck)
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
return urb_select_interface_result(callback, RequestId, InterfaceId, MessageId, MsInterface,
|
||||
ConfigurationHandle);
|
||||
return urb_select_interface_result(callback, RequestId, InterfaceId, MessageId, MsInterface);
|
||||
}
|
||||
|
||||
static UINT urb_control_transfer(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, wStream* s,
|
||||
|
||||
@@ -325,28 +325,29 @@ bool sdlDispContext::updateMonitors(SDL_EventType type, SDL_DisplayID displayID)
|
||||
|
||||
bool sdlDispContext::handleEvent(const SDL_DisplayEvent& ev)
|
||||
{
|
||||
const auto cat = SDL_LOG_CATEGORY_APPLICATION;
|
||||
switch (ev.type)
|
||||
{
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
SDL_Log("A new display with id %u was connected", ev.displayID);
|
||||
SDL_LogDebug(cat, "A new display with id %u was connected", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
SDL_Log("The display with id %u was disconnected", ev.displayID);
|
||||
SDL_LogDebug(cat, "The display with id %u was disconnected", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION:
|
||||
SDL_Log("The orientation of display with id %u was changed", ev.displayID);
|
||||
SDL_LogDebug(cat, "The orientation of display with id %u was changed", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_MOVED:
|
||||
SDL_Log("The display with id %u was moved", ev.displayID);
|
||||
SDL_LogDebug(cat, "The display with id %u was moved", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
|
||||
SDL_Log("The display with id %u changed scale", ev.displayID);
|
||||
SDL_LogDebug(cat, "The display with id %u changed scale", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
|
||||
SDL_Log("The display with id %u changed mode", ev.displayID);
|
||||
SDL_LogDebug(cat, "The display with id %u changed mode", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
|
||||
SDL_Log("The display with id %u changed desktop mode", ev.displayID);
|
||||
SDL_LogDebug(cat, "The display with id %u changed desktop mode", ev.displayID);
|
||||
return updateMonitors(ev.type, ev.displayID);
|
||||
default:
|
||||
return true;
|
||||
|
||||
@@ -466,11 +466,12 @@ static void SDLCALL winpr_LogOutputFunction(void* userdata, int category, SDL_Lo
|
||||
|
||||
static void sdl_quit()
|
||||
{
|
||||
const auto cat = SDL_LOG_CATEGORY_APPLICATION;
|
||||
SDL_Event ev = {};
|
||||
ev.type = SDL_EVENT_QUIT;
|
||||
if (!SDL_PushEvent(&ev))
|
||||
{
|
||||
SDL_Log("An error occurred: %s", SDL_GetError());
|
||||
SDL_LogError(cat, "An error occurred: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,23 +480,24 @@ static void SDLCALL rdp_file_cb(void* userdata, const char* const* filelist,
|
||||
{
|
||||
auto rdp = static_cast<std::string*>(userdata);
|
||||
|
||||
const auto cat = SDL_LOG_CATEGORY_APPLICATION;
|
||||
if (!filelist)
|
||||
{
|
||||
SDL_Log("An error occurred: %s", SDL_GetError());
|
||||
SDL_LogError(cat, "An error occurred: %s", SDL_GetError());
|
||||
sdl_quit();
|
||||
return;
|
||||
}
|
||||
else if (!*filelist)
|
||||
{
|
||||
SDL_Log("The user did not select any file.");
|
||||
SDL_Log("Most likely, the dialog was canceled.");
|
||||
SDL_LogError(cat, "The user did not select any file.");
|
||||
SDL_LogError(cat, "Most likely, the dialog was canceled.");
|
||||
sdl_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
while (*filelist)
|
||||
{
|
||||
SDL_Log("Full path to selected file: '%s'", *filelist);
|
||||
SDL_LogError(cat, "Full path to selected file: '%s'", *filelist);
|
||||
*rdp = *filelist;
|
||||
filelist++;
|
||||
}
|
||||
|
||||
@@ -311,19 +311,23 @@ rdpMonitor SdlWindow::query(SDL_Window* window, SDL_DisplayID id, bool forceAsPr
|
||||
monitor.attributes.physicalWidth = WINPR_ASSERTING_INT_CAST(uint32_t, r.w);
|
||||
monitor.attributes.physicalHeight = WINPR_ASSERTING_INT_CAST(uint32_t, r.h);
|
||||
|
||||
SDL_Log("monitor.orig_screen %" PRIu32, monitor.orig_screen);
|
||||
SDL_Log("monitor.x %" PRId32, monitor.x);
|
||||
SDL_Log("monitor.y %" PRId32, monitor.y);
|
||||
SDL_Log("monitor.width %" PRId32, monitor.width);
|
||||
SDL_Log("monitor.height %" PRId32, monitor.height);
|
||||
SDL_Log("monitor.is_primary %" PRIu32, monitor.is_primary);
|
||||
SDL_Log("monitor.attributes.desktopScaleFactor %" PRIu32,
|
||||
monitor.attributes.desktopScaleFactor);
|
||||
SDL_Log("monitor.attributes.deviceScaleFactor %" PRIu32, monitor.attributes.deviceScaleFactor);
|
||||
SDL_Log("monitor.attributes.orientation %s",
|
||||
freerdp_desktop_rotation_flags_to_string(monitor.attributes.orientation));
|
||||
SDL_Log("monitor.attributes.physicalWidth %" PRIu32, monitor.attributes.physicalWidth);
|
||||
SDL_Log("monitor.attributes.physicalHeight %" PRIu32, monitor.attributes.physicalHeight);
|
||||
const auto cat = SDL_LOG_CATEGORY_APPLICATION;
|
||||
SDL_LogDebug(cat, "monitor.orig_screen %" PRIu32, monitor.orig_screen);
|
||||
SDL_LogDebug(cat, "monitor.x %" PRId32, monitor.x);
|
||||
SDL_LogDebug(cat, "monitor.y %" PRId32, monitor.y);
|
||||
SDL_LogDebug(cat, "monitor.width %" PRId32, monitor.width);
|
||||
SDL_LogDebug(cat, "monitor.height %" PRId32, monitor.height);
|
||||
SDL_LogDebug(cat, "monitor.is_primary %" PRIu32, monitor.is_primary);
|
||||
SDL_LogDebug(cat, "monitor.attributes.desktopScaleFactor %" PRIu32,
|
||||
monitor.attributes.desktopScaleFactor);
|
||||
SDL_LogDebug(cat, "monitor.attributes.deviceScaleFactor %" PRIu32,
|
||||
monitor.attributes.deviceScaleFactor);
|
||||
SDL_LogDebug(cat, "monitor.attributes.orientation %s",
|
||||
freerdp_desktop_rotation_flags_to_string(monitor.attributes.orientation));
|
||||
SDL_LogDebug(cat, "monitor.attributes.physicalWidth %" PRIu32,
|
||||
monitor.attributes.physicalWidth);
|
||||
SDL_LogDebug(cat, "monitor.attributes.physicalHeight %" PRIu32,
|
||||
monitor.attributes.physicalHeight);
|
||||
return monitor;
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ static LONG smartcard_EstablishContext_Call(scard_call_context* smartcard, wStre
|
||||
|
||||
if (!HashTable_Insert(smartcard->rgSCardContextList, key, (void*)pContext))
|
||||
{
|
||||
WLog_Print(smartcard->log, WLOG_ERROR, "ListDictionary_Add failed!");
|
||||
WLog_Print(smartcard->log, WLOG_ERROR, "HashTable_Insert failed!");
|
||||
context_free(pContext);
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
@@ -2053,6 +2053,7 @@ BOOL smartcard_call_cancel_all_context(scard_call_context* ctx)
|
||||
{
|
||||
WINPR_ASSERT(ctx);
|
||||
|
||||
smartcard_call_context_signal_stop(ctx, FALSE);
|
||||
HashTable_Clear(ctx->rgSCardContextList);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user