channels/rdpdr: make use of MessageQueue for drive redirection
This commit is contained in:
parent
5406ebd5d8
commit
9b394a0189
@ -56,9 +56,7 @@ struct _DRIVE_DEVICE
|
|||||||
wListDictionary* files;
|
wListDictionary* files;
|
||||||
|
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
HANDLE irpEvent;
|
wMessageQueue* IrpQueue;
|
||||||
HANDLE stopEvent;
|
|
||||||
PSLIST_HEADER pIrpList;
|
|
||||||
|
|
||||||
DEVMAN* devman;
|
DEVMAN* devman;
|
||||||
};
|
};
|
||||||
@ -576,77 +574,47 @@ static void drive_process_irp(DRIVE_DEVICE* drive, IRP* irp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drive_process_irp_list(DRIVE_DEVICE* drive)
|
|
||||||
{
|
|
||||||
IRP* irp;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (WaitForSingleObject(drive->stopEvent, 0) == WAIT_OBJECT_0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
irp = (IRP*) InterlockedPopEntrySList(drive->pIrpList);
|
|
||||||
|
|
||||||
if (irp == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
drive_process_irp(drive, irp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* drive_thread_func(void* arg)
|
static void* drive_thread_func(void* arg)
|
||||||
{
|
{
|
||||||
DWORD status;
|
IRP* irp;
|
||||||
DWORD nCount;
|
wMessage message;
|
||||||
HANDLE handles[8];
|
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) arg;
|
||||||
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) arg;
|
|
||||||
|
|
||||||
nCount = 0;
|
while (1)
|
||||||
handles[nCount++] = drive->stopEvent;
|
{
|
||||||
handles[nCount++] = drive->irpEvent;
|
if (!MessageQueue_Wait(drive->IrpQueue))
|
||||||
|
break;
|
||||||
|
|
||||||
while (1)
|
if (!MessageQueue_Peek(drive->IrpQueue, &message, TRUE))
|
||||||
{
|
break;
|
||||||
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
|
||||||
|
|
||||||
if (WaitForSingleObject(drive->stopEvent, 0) == WAIT_OBJECT_0)
|
if (message.id == WMQ_QUIT)
|
||||||
{
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResetEvent(drive->irpEvent);
|
irp = (IRP*) message.wParam;
|
||||||
drive_process_irp_list(drive);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExitThread(0);
|
if (irp)
|
||||||
return NULL;
|
drive_process_irp(drive, irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExitThread(0);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drive_irp_request(DEVICE* device, IRP* irp)
|
static void drive_irp_request(DEVICE* device, IRP* irp)
|
||||||
{
|
{
|
||||||
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device;
|
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device;
|
||||||
|
MessageQueue_Post(drive->IrpQueue, NULL, 0, (void*) irp, NULL);
|
||||||
InterlockedPushEntrySList(drive->pIrpList, &(irp->ItemEntry));
|
|
||||||
|
|
||||||
SetEvent(drive->irpEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drive_free(DEVICE* device)
|
static void drive_free(DEVICE* device)
|
||||||
{
|
{
|
||||||
IRP* irp;
|
|
||||||
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device;
|
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device;
|
||||||
|
|
||||||
SetEvent(drive->stopEvent);
|
MessageQueue_PostQuit(drive->IrpQueue, 0);
|
||||||
WaitForSingleObject(drive->thread, INFINITE);
|
WaitForSingleObject(drive->thread, INFINITE);
|
||||||
|
|
||||||
CloseHandle(drive->thread);
|
CloseHandle(drive->thread);
|
||||||
CloseHandle(drive->irpEvent);
|
|
||||||
CloseHandle(drive->stopEvent);
|
|
||||||
|
|
||||||
while ((irp = (IRP*) InterlockedPopEntrySList(drive->pIrpList)) != NULL)
|
|
||||||
irp->Discard(irp);
|
|
||||||
|
|
||||||
_aligned_free(drive->pIrpList);
|
|
||||||
|
|
||||||
ListDictionary_Free(drive->files);
|
ListDictionary_Free(drive->files);
|
||||||
|
|
||||||
@ -693,11 +661,7 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
|
|||||||
drive->files = ListDictionary_New(TRUE);
|
drive->files = ListDictionary_New(TRUE);
|
||||||
ListDictionary_Object(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free;
|
ListDictionary_Object(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free;
|
||||||
|
|
||||||
drive->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
|
drive->IrpQueue = MessageQueue_New();
|
||||||
InitializeSListHead(drive->pIrpList);
|
|
||||||
|
|
||||||
drive->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
||||||
drive->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
||||||
drive->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL);
|
drive->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL);
|
||||||
|
|
||||||
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) drive);
|
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) drive);
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#include <freerdp/utils/list.h>
|
#include <freerdp/utils/list.h>
|
||||||
#include <freerdp/utils/debug.h>
|
#include <freerdp/utils/debug.h>
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
|
|
||||||
#include <freerdp/channels/rdpdr.h>
|
#include <freerdp/channels/rdpdr.h>
|
||||||
|
|
||||||
@ -229,7 +228,7 @@ static void smartcard_irp_complete(IRP* irp)
|
|||||||
* to be in this file so that "smartcard_irp_request()" can reference it.
|
* to be in this file so that "smartcard_irp_request()" can reference it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
|
DEBUG_SCARD("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
|
||||||
|
|
||||||
pos = Stream_GetPosition(irp->output);
|
pos = Stream_GetPosition(irp->output);
|
||||||
Stream_SetPosition(irp->output, 12);
|
Stream_SetPosition(irp->output, 12);
|
||||||
@ -246,8 +245,7 @@ static void smartcard_irp_complete(IRP* irp)
|
|||||||
|
|
||||||
if (!duplicate)
|
if (!duplicate)
|
||||||
{
|
{
|
||||||
svc_plugin_send(irp->devman->plugin, irp->output);
|
irp->Complete(irp);
|
||||||
irp->output = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End TS Client defect workaround. */
|
/* End TS Client defect workaround. */
|
||||||
|
Loading…
Reference in New Issue
Block a user