diff --git a/channels/rdpdr/client/irp.c b/channels/rdpdr/client/irp.c index ff433159f..54a81e6b1 100644 --- a/channels/rdpdr/client/irp.c +++ b/channels/rdpdr/client/irp.c @@ -47,14 +47,20 @@ static void irp_free(IRP* irp) static void irp_complete(IRP* irp) { int pos; + rdpdrPlugin* rdpdr; - pos = (int) Stream_GetPosition(irp->output); - Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4); - Stream_Write_UINT32(irp->output, irp->IoStatus); /* IoStatus (4 bytes) */ - Stream_SetPosition(irp->output, pos); + rdpdr = (rdpdrPlugin*) irp->devman->plugin; - rdpdr_send((rdpdrPlugin*) irp->devman->plugin, irp->output); - irp->output = NULL; + if (irp->sequenceId == rdpdr->sequenceId) + { + pos = (int) Stream_GetPosition(irp->output); + Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4); + Stream_Write_UINT32(irp->output, irp->IoStatus); /* IoStatus (4 bytes) */ + Stream_SetPosition(irp->output, pos); + + rdpdr_send((rdpdrPlugin*) irp->devman->plugin, irp->output); + irp->output = NULL; + } irp_free(irp); } @@ -64,6 +70,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s) IRP* irp; DEVICE* device; UINT32 DeviceId; + rdpdrPlugin* rdpdr; Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */ device = devman_get_device_by_id(devman, DeviceId); @@ -71,6 +78,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s) if (!device) return NULL; + rdpdr = (rdpdrPlugin*) devman->plugin; + irp = (IRP*) _aligned_malloc(sizeof(IRP), MEMORY_ALLOCATION_ALIGNMENT); ZeroMemory(irp, sizeof(IRP)); @@ -96,5 +105,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s) irp->thread = NULL; irp->cancelled = FALSE; + irp->sequenceId = rdpdr->sequenceId; + return irp; } diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index fd027a6c6..2c9fe5350 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -517,6 +517,8 @@ static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s Stream_Read_UINT16(s, rdpdr->versionMajor); Stream_Read_UINT16(s, rdpdr->versionMinor); Stream_Read_UINT32(s, rdpdr->clientID); + + rdpdr->sequenceId++; } static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr) @@ -1034,6 +1036,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) strcpy(rdpdr->channelDef.name, "rdpdr"); + rdpdr->sequenceId = 0; + CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle, diff --git a/channels/rdpdr/client/rdpdr_main.h b/channels/rdpdr/client/rdpdr_main.h index 94da4227e..c29846c80 100644 --- a/channels/rdpdr/client/rdpdr_main.h +++ b/channels/rdpdr/client/rdpdr_main.h @@ -53,6 +53,8 @@ struct rdpdr_plugin UINT16 clientID; char computerName[256]; + UINT32 sequenceId; + /* hotplug support */ HANDLE hotplugThread; #ifdef _WIN32 diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index da7e67fbb..8e259d5ed 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -62,7 +62,6 @@ static void smartcard_free(DEVICE* device) static void smartcard_init(DEVICE* device) { - IRP* irp; int index; int keyCount; ULONG_PTR* pKeys; @@ -70,22 +69,6 @@ static void smartcard_init(DEVICE* device) SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; - if (ListDictionary_Count(smartcard->rgOutstandingMessages) > 0) - { - pKeys = NULL; - keyCount = ListDictionary_GetKeys(smartcard->rgOutstandingMessages, &pKeys); - - for (index = 0; index < keyCount; index++) - { - irp = (IRP*) ListDictionary_GetItemValue(smartcard->rgOutstandingMessages, (void*) pKeys[index]); - - if (irp) - irp->cancelled = TRUE; - } - - free(pKeys); - } - /** * On protocol termination, the following actions are performed: * For each context in rgSCardContextList, SCardCancel is called causing all outstanding messages to be processed. @@ -116,10 +99,7 @@ void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) key = (void*) (size_t) irp->CompletionId; ListDictionary_Remove(smartcard->rgOutstandingMessages, key); - if (!irp->cancelled) - irp->Complete(irp); - else - irp->Discard(irp); + irp->Complete(irp); } void* smartcard_process_irp_worker_proc(IRP* irp) diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index 8cc455b89..c10a5fa9f 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -349,6 +349,7 @@ struct _IRP HANDLE thread; BOOL cancelled; + UINT32 sequenceId; }; struct _DEVMAN