Hardened urbdrc channel

This commit is contained in:
David FORT 2015-07-06 16:46:21 +02:00
parent 1b7140d84e
commit b83ab92776
8 changed files with 224 additions and 157 deletions

View File

@ -223,15 +223,15 @@ static int urbdrc_process_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* da
data_read_UINT32(data + 12 + InputBufferSize, RequestId);
pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
if (pdev == NULL)
return 0;
InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
/** process */
OutputBuffer = (BYTE *)malloc(OutputBufferSize);
memset(OutputBuffer, 0, OutputBufferSize);
OutputBuffer = (BYTE *)calloc(1, OutputBufferSize);
if (!OutputBuffer)
return ERROR_OUTOFMEMORY;
switch (IoControlCode)
{
@ -280,14 +280,18 @@ static int urbdrc_process_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* da
default:
WLog_DBG(TAG, "urbdrc_process_io_control: unknown IoControlCode 0x%X", IoControlCode);
zfree(OutputBuffer);
return -1;
return ERROR_INVALID_OPERATION;
break;
}
offset = 28;
out_size = offset + OutputBufferSize;
out_data = (BYTE *) malloc(out_size);
memset(out_data, 0, out_size);
out_data = (BYTE *) calloc(1, out_size);
if (!out_data)
{
zfree(OutputBuffer);
return ERROR_OUTOFMEMORY;
}
data_write_UINT32(out_data + 0, InterfaceId); /** interface */
data_write_UINT32(out_data + 4, MessageId); /** message id */
data_write_UINT32(out_data + 8, IOCONTROL_COMPLETION); /** function id */
@ -296,7 +300,7 @@ static int urbdrc_process_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* da
data_write_UINT32(out_data + 20, OutputBufferSize); /** Information */
data_write_UINT32(out_data + 24, OutputBufferSize); /** OutputBufferSize */
for (i=0;i<OutputBufferSize;i++)
for (i = 0; i < OutputBufferSize; i++)
{
data_write_BYTE(out_data + offset, OutputBuffer[i]); /** OutputBuffer */
offset += 1;
@ -308,7 +312,7 @@ static int urbdrc_process_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* da
zfree(out_data);
zfree(OutputBuffer);
return 0;
return CHANNEL_RC_OK;
}
static int urbdrc_process_internal_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,

View File

@ -21,21 +21,15 @@
#ifndef __DATA_TRANSFER_H
#define __DATA_TRANSFER_H
#include "urbdrc_main.h"
#define DEVICE_CTX(dev) ((dev)->ctx)
#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev))
#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle))
#define ITRANSFER_CTX(transfer) \
(TRANSFER_CTX(__USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)))
void*
urbdrc_process_udev_data_transfer(void* arg);
void *urbdrc_process_udev_data_transfer(void* arg);
#endif

View File

@ -29,12 +29,9 @@ static void isoch_queue_rewind(ISOCH_CALLBACK_QUEUE* queue)
queue->curr = queue->head;
}
static int isoch_queue_has_next(ISOCH_CALLBACK_QUEUE* queue)
static BOOL isoch_queue_has_next(ISOCH_CALLBACK_QUEUE* queue)
{
if (queue->curr == NULL)
return 0;
else
return 1;
return (queue->curr != NULL);
}
static ISOCH_CALLBACK_DATA* isoch_queue_get_next(ISOCH_CALLBACK_QUEUE* queue)
@ -51,13 +48,10 @@ static ISOCH_CALLBACK_DATA* isoch_queue_register_data(ISOCH_CALLBACK_QUEUE* queu
{
ISOCH_CALLBACK_DATA* isoch;
isoch = (ISOCH_CALLBACK_DATA*) malloc(sizeof(ISOCH_CALLBACK_DATA));
isoch = (ISOCH_CALLBACK_DATA*) calloc(1, sizeof(ISOCH_CALLBACK_DATA));
if (!isoch)
return NULL;
isoch->prev = NULL;
isoch->next = NULL;
isoch->out_data = NULL;
isoch->out_size = 0;
isoch->device = dev;
isoch->callback = callback;
@ -89,48 +83,50 @@ static int isoch_queue_unregister_data(ISOCH_CALLBACK_QUEUE* queue, ISOCH_CALLBA
queue->rewind(queue);
while (queue->has_next(queue) != 0)
while (queue->has_next(queue))
{
p = queue->get_next(queue);
if (p == isoch) /* data exists */
if (p != isoch)
continue;
/* data exists */
/* set previous data to point to next data */
if (isoch->prev != NULL)
{
/* set previous data to point to next data */
if (isoch->prev != NULL)
{
/* unregistered data is not the head */
p = (ISOCH_CALLBACK_DATA*)isoch->prev;
p->next = isoch->next;
}
else
{
/* unregistered data is the head, update head */
queue->head = (ISOCH_CALLBACK_DATA*)isoch->next;
}
/* set next data to point to previous data */
if (isoch->next != NULL)
{
/* unregistered data is not the tail */
p = (ISOCH_CALLBACK_DATA*)isoch->next;
p->prev = isoch->prev;
}
else
{
/* unregistered data is the tail, update tail */
queue->tail = (ISOCH_CALLBACK_DATA*)isoch->prev;
}
queue->isoch_num--;
/* free data info */
isoch->out_data = NULL;
if (isoch) zfree(isoch);
return 1; /* unregistration successful */
/* unregistered data is not the head */
p = (ISOCH_CALLBACK_DATA*)isoch->prev;
p->next = isoch->next;
}
else
{
/* unregistered data is the head, update head */
queue->head = (ISOCH_CALLBACK_DATA*)isoch->next;
}
/* set next data to point to previous data */
if (isoch->next != NULL)
{
/* unregistered data is not the tail */
p = (ISOCH_CALLBACK_DATA*)isoch->next;
p->prev = isoch->prev;
}
else
{
/* unregistered data is the tail, update tail */
queue->tail = (ISOCH_CALLBACK_DATA*)isoch->prev;
}
queue->isoch_num--;
/* free data info */
isoch->out_data = NULL;
if (isoch)
zfree(isoch);
return 1; /* unregistration successful */
}
/* if we reach this point, the isoch wasn't found */
@ -167,11 +163,9 @@ ISOCH_CALLBACK_QUEUE* isoch_queue_new()
{
ISOCH_CALLBACK_QUEUE* queue;
queue = (ISOCH_CALLBACK_QUEUE*) malloc(sizeof(ISOCH_CALLBACK_QUEUE));
queue->isoch_num = 0;
queue->curr = NULL;
queue->head = NULL;
queue->tail = NULL;
queue = (ISOCH_CALLBACK_QUEUE*) calloc(1, sizeof(ISOCH_CALLBACK_QUEUE));
if (!queue)
return NULL;
pthread_mutex_init(&queue->isoch_loading, NULL);

View File

@ -52,7 +52,7 @@ struct _ISOCH_CALLBACK_QUEUE
/* Isochronous queue service */
void (*rewind) (ISOCH_CALLBACK_QUEUE * queue);
int (*has_next) (ISOCH_CALLBACK_QUEUE * queue);
BOOL (*has_next) (ISOCH_CALLBACK_QUEUE * queue);
int (*unregister_data) (ISOCH_CALLBACK_QUEUE* queue, ISOCH_CALLBACK_DATA* isoch);
ISOCH_CALLBACK_DATA *(*get_next) (ISOCH_CALLBACK_QUEUE * queue);
ISOCH_CALLBACK_DATA *(*register_data) (ISOCH_CALLBACK_QUEUE* queue,

View File

@ -589,6 +589,8 @@ int freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS p
libusb_init(NULL);
udevman = (PUDEVMAN) malloc(sizeof(UDEVMAN));
if (!udevman)
return -1;
udevman->device_num = 0;
udevman->idev = NULL;
udevman->head = NULL;

View File

@ -52,14 +52,14 @@ static USB_SEARCHDEV* searchman_get_next(USB_SEARCHMAN* searchman)
return search;
}
static int searchman_list_add(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct)
static BOOL searchman_list_add(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct)
{
USB_SEARCHDEV* search;
search = (USB_SEARCHDEV*) malloc(sizeof(USB_SEARCHDEV));
search = (USB_SEARCHDEV*) calloc(1, sizeof(USB_SEARCHDEV));
if (!search)
return FALSE;
search->prev = NULL;
search->next = NULL;
search->idVendor = idVendor;
search->idProduct = idProduct;
@ -78,7 +78,7 @@ static int searchman_list_add(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16
}
searchman->usb_numbers += 1;
return 1;
return TRUE;
}
static int searchman_list_remove(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct)
@ -135,14 +135,19 @@ static int searchman_list_remove(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT
return 0;
}
static void searchman_start(USB_SEARCHMAN* self, void* func)
static BOOL searchman_start(USB_SEARCHMAN* self, void* func)
{
pthread_t thread;
/* create search thread */
pthread_create(&thread, 0, func, self);
pthread_detach(thread);
self->strated = 1;
if (pthread_create(&thread, 0, func, self) != 0)
return FALSE;
if (pthread_detach(thread) != 0)
return FALSE;
self->started = 1;
return TRUE;
}
/* close thread */
@ -189,14 +194,10 @@ USB_SEARCHMAN* searchman_new(void * urbdrc, UINT32 UsbDevice)
int ret;
USB_SEARCHMAN* searchman;
searchman = (USB_SEARCHMAN*) malloc(sizeof(USB_SEARCHMAN));
searchman = (USB_SEARCHMAN*) calloc(1, sizeof(USB_SEARCHMAN));
if (!searchman)
return NULL;
searchman->idev = NULL;
searchman->head = NULL;
searchman->tail = NULL;
searchman->usb_numbers = 0;
searchman->urbdrc = urbdrc;
searchman->UsbDevice = UsbDevice;
@ -218,14 +219,18 @@ USB_SEARCHMAN* searchman_new(void * urbdrc, UINT32 UsbDevice)
searchman->close = searchman_close;
searchman->free = searchman_free;
searchman->strated = 0;
searchman->started = 0;
searchman->term_event = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!searchman->term_event)
goto out_error_event;
sem_init(&searchman->sem_term, 0, 0);
if (sem_init(&searchman->sem_term, 0, 0) < 0)
goto out_error_sem;
return searchman;
out_error_sem:
CloseHandle(searchman->term_event);
out_error_event:
pthread_mutex_destroy(&searchman->mutex);
out_error_mutex:

View File

@ -47,7 +47,7 @@ struct _USB_SEARCHMAN
pthread_mutex_t mutex;
HANDLE term_event;
sem_t sem_term;
int strated;
int started;
/* for urbdrc channel call back */
void* urbdrc;
@ -57,11 +57,11 @@ struct _USB_SEARCHMAN
/* show all device in the list */
void (*show) (USB_SEARCHMAN* self);
/* start searchman */
void (*start) (USB_SEARCHMAN* self, void * func);
BOOL (*start) (USB_SEARCHMAN* self, void * func);
/* close searchman */
void (*close) (USB_SEARCHMAN* self);
/* add a new usb device for search */
int (*add) (USB_SEARCHMAN* seachman, UINT16 idVendor, UINT16 idProduct);
BOOL (*add) (USB_SEARCHMAN* seachman, UINT16 idVendor, UINT16 idProduct);
/* remove a usb device from list */
int (*remove) (USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct);
/* check list has next device*/

View File

@ -169,7 +169,6 @@ static int func_instance_id_generate(IUDEVICE* pdev, char* strInstanceId)
{
UINT8 instanceId[17];
memset(instanceId, 0, 17);
ZeroMemory(instanceId, sizeof(instanceId));
snprintf((char*)instanceId, sizeof(instanceId), "\\%s", pdev->getPath(pdev));
@ -223,31 +222,36 @@ static void func_lock_isoch_mutex(TRANSFER_DATA* transfer_data)
#endif
static int urbdrc_process_capability_request(URBDRC_CHANNEL_CALLBACK* callback, char* data, UINT32 data_sizem, UINT32 MessageId)
static WIN32ERROR urbdrc_process_capability_request(URBDRC_CHANNEL_CALLBACK* callback, char* data, UINT32 data_sizem, UINT32 MessageId)
{
UINT32 InterfaceId;
UINT32 Version;
UINT32 out_size;
char * out_data;
WIN32ERROR ret;
WLog_VRB(TAG, "");
data_read_UINT32(data + 0, Version);
InterfaceId = ((STREAM_ID_NONE<<30) | CAPABILITIES_NEGOTIATOR);
out_size = 16;
out_data = (char *) malloc(out_size);
memset(out_data, 0, out_size);
out_data = (char *) calloc(1, out_size);
if (!out_data)
return ERROR_OUTOFMEMORY;
data_write_UINT32(out_data + 0, InterfaceId); /* interface id */
data_write_UINT32(out_data + 4, MessageId); /* message id */
data_write_UINT32(out_data + 8, Version); /* usb protocol version */
data_write_UINT32(out_data + 12, 0x00000000); /* HRESULT */
callback->channel->Write(callback->channel, out_size, (BYTE*) out_data, NULL);
ret = callback->channel->Write(callback->channel, out_size, (BYTE*) out_data, NULL);
zfree(out_data);
return 0;
return ret;
}
static int urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, char* data, UINT32 data_sizem, UINT32 MessageId)
static WIN32ERROR urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, char* data, UINT32 data_sizem, UINT32 MessageId)
{
UINT32 InterfaceId;
UINT32 out_size;
@ -255,6 +259,8 @@ static int urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, char
UINT32 MinorVersion;
UINT32 Capabilities;
char* out_data;
WIN32ERROR ret;
WLog_VRB(TAG, "");
data_read_UINT32(data + 0, MajorVersion);
data_read_UINT32(data + 4, MinorVersion);
@ -263,8 +269,9 @@ static int urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, char
InterfaceId = ((STREAM_ID_PROXY<<30) | CLIENT_CHANNEL_NOTIFICATION);
out_size = 24;
out_data = (char*) malloc(out_size);
memset(out_data, 0, out_size);
out_data = (char*) calloc(1, out_size);
if (!out_data)
return ERROR_OUTOFMEMORY;
data_write_UINT32(out_data + 0, InterfaceId); /* interface id */
data_write_UINT32(out_data + 4, MessageId); /* message id */
@ -272,10 +279,10 @@ static int urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, char
data_write_UINT32(out_data + 12, MajorVersion);
data_write_UINT32(out_data + 16, MinorVersion);
data_write_UINT32(out_data + 20, Capabilities); /* capabilities version */
callback->channel->Write(callback->channel, out_size, (BYTE *)out_data, NULL);
ret = callback->channel->Write(callback->channel, out_size, (BYTE *)out_data, NULL);
zfree(out_data);
return 0;
return ret;
}
static int urdbrc_send_virtual_channel_add(IWTSVirtualChannel* channel, UINT32 MessageId)
@ -303,7 +310,7 @@ static int urdbrc_send_virtual_channel_add(IWTSVirtualChannel* channel, UINT32 M
return 0;
}
static int urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVICE* pdev)
static WIN32ERROR urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVICE* pdev)
{
char* out_data;
UINT32 InterfaceId;
@ -313,6 +320,9 @@ static int urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVIC
char strInstanceId[DEVICE_INSTANCE_STR_SIZE];
char* composite_str = "USB\\COMPOSITE";
int size, out_offset, cchCompatIds, bcdUSB;
ISOCH_CALLBACK_QUEUE *cb_queue;
WIN32ERROR ret;
WLog_VRB(TAG, "");
InterfaceId = ((STREAM_ID_PROXY<<30) | CLIENT_DEVICE_SINK);
@ -321,7 +331,10 @@ static int urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVIC
#if ISOCH_FIFO
/* create/initial isoch queue */
pdev->set_isoch_queue(pdev, (void *)isoch_queue_new());
cb_queue = isoch_queue_new();
if (!cb_queue)
return ERROR_OUTOFMEMORY;
pdev->set_isoch_queue(pdev, (void *)cb_queue);
#endif
func_hardware_id_format(pdev, HardwareIds);
@ -345,11 +358,12 @@ static int urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVIC
4 + (cchCompatIds) * 2 +
(strlen(strContainerId) + 1) * 2 + 4 + 28;
out_data = (char*) malloc(size);
memset(out_data, 0, size);
out_data = (char *)calloc(1, size);
if (!out_data)
return ERROR_OUTOFMEMORY;
data_write_UINT32(out_data + 0, InterfaceId); /* interface */
data_write_UINT32(out_data + 4, 0); /* message id */
/* data_write_UINT32(out_data + 4, 0);*/ /* message id */
data_write_UINT32(out_data + 8, ADD_DEVICE); /* function id */
data_write_UINT32(out_data + 12, 0x00000001); /* NumUsbDevice */
data_write_UINT32(out_data + 16, pdev->get_UsbDevice(pdev)); /* UsbDevice */
@ -363,7 +377,7 @@ static int urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVIC
out_offset = fun_device_string_send_set(out_data, out_offset, HardwareIds[0]);
/* HardwareIds 2 */
out_offset = fun_device_string_send_set(out_data, out_offset, HardwareIds[1]);
data_write_UINT16(out_data + out_offset, 0x0000); /* add "\0" */
/*data_write_UINT16(out_data + out_offset, 0x0000);*/ /* add "\0" */
out_offset += 2;
data_write_UINT32(out_data + out_offset, cchCompatIds); /* cchCompatIds */
@ -378,7 +392,7 @@ static int urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVIC
if (pdev->isCompositeDevice(pdev))
out_offset = fun_device_string_send_set(out_data, out_offset, composite_str);
data_write_UINT16(out_data + out_offset, 0x0000); /* add "\0" */
/*data_write_UINT16(out_data + out_offset, 0x0000);*/ /* add "\0" */
out_offset += 2;
data_write_UINT32(out_data + out_offset, 0x00000027); /* cchContainerId */
@ -404,18 +418,18 @@ static int urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVIC
data_write_UINT32(out_data + out_offset + 24, 0x50); /* NoAckIsochWriteJitterBufferSizeInMs, >=10 or <=512 */
out_offset += 28;
callback->channel->Write(callback->channel, out_offset, (BYTE *)out_data, NULL);
ret = callback->channel->Write(callback->channel, out_offset, (BYTE *)out_data, NULL);
zfree(out_data);
return 0;
return ret;
}
static int urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, char* pBuffer, UINT32 cbSize)
static WIN32ERROR urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, char* pBuffer, UINT32 cbSize)
{
UINT32 MessageId;
UINT32 FunctionId;
int error = 0;
WIN32ERROR error = CHANNEL_RC_OK;
data_read_UINT32(pBuffer + 0, MessageId);
data_read_UINT32(pBuffer + 4, FunctionId);
@ -428,7 +442,7 @@ static int urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, char*
default:
WLog_ERR(TAG, "unknown FunctionId 0x%X", FunctionId);
error = 1;
error = ERROR_NOT_FOUND;
break;
}
@ -686,7 +700,11 @@ void* urbdrc_new_device_create(void* arg)
{
case INIT_CHANNEL_IN:
urbdrc->first_channel_id = ChannelId;
searchman->start(searchman, urbdrc_search_usb_device);
if (!searchman->start(searchman, urbdrc_search_usb_device))
{
WLog_ERR(TAG, "unable to start searchman thread");
return 0;
}
for (i = 0; i < udevman->get_device_num(udevman); i++)
error = urdbrc_send_virtual_channel_add(callback->channel, MessageId);
@ -736,11 +754,12 @@ void* urbdrc_new_device_create(void* arg)
return 0;
}
static int urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callback, char* pBuffer, UINT32 cbSize)
static WIN32ERROR urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callback, char* pBuffer, UINT32 cbSize)
{
int i, error = 0;
int i;
UINT32 MessageId;
UINT32 FunctionId;
WIN32ERROR error = CHANNEL_RC_OK;
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) callback->plugin;
data_read_UINT32(pBuffer + 0, MessageId);
@ -754,24 +773,36 @@ static int urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callback
case RIMCALL_RELEASE:
WLog_VRB(TAG, "recv RIMCALL_RELEASE");
pthread_t thread;
pthread_t thread;
TRANSFER_DATA* transfer_data;
transfer_data = (TRANSFER_DATA*)malloc(sizeof(TRANSFER_DATA));
if (!transfer_data)
return ERROR_OUTOFMEMORY;
transfer_data->callback = callback;
transfer_data->urbdrc = urbdrc;
transfer_data->udevman = urbdrc->udevman;
transfer_data->urbdrc = urbdrc;
transfer_data->cbSize = cbSize;
transfer_data->pBuffer = (BYTE*) malloc((cbSize));
if (!transfer_data->pBuffer)
{
free(transfer_data);
return ERROR_OUTOFMEMORY;
}
for (i = 0; i < (cbSize); i++)
{
transfer_data->pBuffer[i] = pBuffer[i];
}
pthread_create(&thread, 0, urbdrc_new_device_create, transfer_data);
if (pthread_create(&thread, 0, urbdrc_new_device_create, transfer_data) != 0)
{
free(transfer_data->pBuffer);
free(transfer_data);
return ERROR_INVALID_OPERATION;
}
pthread_detach(thread);
break;
@ -783,7 +814,7 @@ static int urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callback
return error;
}
static int urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream* data)
static WIN32ERROR urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream* data)
{
URBDRC_CHANNEL_CALLBACK* callback = (URBDRC_CHANNEL_CALLBACK*) pChannelCallback;
URBDRC_PLUGIN* urbdrc;
@ -791,7 +822,7 @@ static int urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
UINT32 InterfaceTemp;
UINT32 InterfaceId;
UINT32 Mask;
int error = 0;
WIN32ERROR error = CHANNEL_RC_OK;
char* pBuffer = (char*)Stream_Pointer(data);
UINT32 cbSize = Stream_GetRemainingLength(data);
@ -828,12 +859,11 @@ static int urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
pthread_t thread;
TRANSFER_DATA* transfer_data;
transfer_data = (TRANSFER_DATA*) malloc(sizeof(TRANSFER_DATA));
if (transfer_data == NULL)
transfer_data = (TRANSFER_DATA *)malloc(sizeof(TRANSFER_DATA));
if (!transfer_data)
{
WLog_ERR(TAG, "transfer_data is NULL!!");
return 0;
WLog_ERR(TAG, "transfer_data is NULL!!");
return ERROR_OUTOFMEMORY;
}
transfer_data->callback = callback;
@ -842,6 +872,11 @@ static int urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
transfer_data->cbSize = cbSize - 4;
transfer_data->UsbDevice = InterfaceId;
transfer_data->pBuffer = (BYTE *)malloc((cbSize - 4));
if (!transfer_data->pBuffer)
{
free(transfer_data);
return ERROR_OUTOFMEMORY;
}
memcpy(transfer_data->pBuffer, pBuffer + 4, (cbSize - 4));
@ -854,19 +889,22 @@ static int urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
#endif
error = pthread_create(&thread, 0, urbdrc_process_udev_data_transfer, transfer_data);
if (error < 0)
if (error != 0)
{
WLog_ERR(TAG, "Create Data Transfer Thread got error = %d", error);
else
pthread_detach(thread);
free(transfer_data->pBuffer);
free(transfer_data);
return ERROR_INVALID_OPERATION;
}
pthread_detach(thread);
break;
}
return 0;
}
static int urbdrc_on_close(IWTSVirtualChannelCallback * pChannelCallback)
static WIN32ERROR urbdrc_on_close(IWTSVirtualChannelCallback * pChannelCallback)
{
URBDRC_CHANNEL_CALLBACK* callback = (URBDRC_CHANNEL_CALLBACK*) pChannelCallback;
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) callback->plugin;
@ -902,17 +940,19 @@ static int urbdrc_on_close(IWTSVirtualChannelCallback * pChannelCallback)
zfree(callback);
WLog_DBG(TAG, "success");
return 0;
return CHANNEL_RC_OK;
}
static int urbdrc_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
static WIN32ERROR urbdrc_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
IWTSVirtualChannel * pChannel, BYTE* pData, int* pbAccept, IWTSVirtualChannelCallback** ppCallback)
{
URBDRC_LISTENER_CALLBACK* listener_callback = (URBDRC_LISTENER_CALLBACK*) pListenerCallback;
URBDRC_CHANNEL_CALLBACK* callback;
WLog_VRB(TAG, "");
callback = (URBDRC_CHANNEL_CALLBACK*) malloc(sizeof(URBDRC_CHANNEL_CALLBACK));
memset(callback, 0, sizeof(URBDRC_CHANNEL_CALLBACK));
callback = (URBDRC_CHANNEL_CALLBACK*) calloc(1, sizeof(URBDRC_CHANNEL_CALLBACK));
if (!callback)
return ERROR_OUTOFMEMORY;
callback->iface.OnDataReceived = urbdrc_on_data_received;
callback->iface.OnClose = urbdrc_on_close;
@ -921,17 +961,19 @@ static int urbdrc_on_new_channel_connection(IWTSListenerCallback* pListenerCallb
callback->channel = pChannel;
*ppCallback = (IWTSVirtualChannelCallback*) callback;
return 0;
return CHANNEL_RC_OK;
}
static int urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
static WIN32ERROR urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
{
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) pPlugin;
IUDEVMAN* udevman = NULL;
USB_SEARCHMAN* searchman = NULL;
WLog_VRB(TAG, "");
urbdrc->listener_callback = (URBDRC_LISTENER_CALLBACK*) malloc(sizeof(URBDRC_LISTENER_CALLBACK));
memset(urbdrc->listener_callback, 0, sizeof(URBDRC_LISTENER_CALLBACK));
urbdrc->listener_callback = (URBDRC_LISTENER_CALLBACK*) calloc(1, sizeof(URBDRC_LISTENER_CALLBACK));
if (!urbdrc->listener_callback)
return CHANNEL_RC_NO_MEMORY;
urbdrc->listener_callback->iface.OnNewChannelConnection = urbdrc_on_new_channel_connection;
urbdrc->listener_callback->plugin = pPlugin;
@ -940,17 +982,24 @@ static int urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
/* Init searchman */
udevman = urbdrc->udevman;
searchman = searchman_new((void*) urbdrc, udevman->get_defUsbDevice(udevman));
if (!searchman)
{
free(urbdrc->listener_callback);
urbdrc->listener_callback = NULL;
return CHANNEL_RC_NO_MEMORY;
}
urbdrc->searchman = searchman;
return pChannelMgr->CreateListener(pChannelMgr, "URBDRC", 0,
(IWTSListenerCallback*) urbdrc->listener_callback, NULL);
}
static int urbdrc_plugin_terminated(IWTSPlugin* pPlugin)
static WIN32ERROR urbdrc_plugin_terminated(IWTSPlugin* pPlugin)
{
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) pPlugin;
IUDEVMAN* udevman = urbdrc->udevman;
USB_SEARCHMAN* searchman = urbdrc->searchman;
WLog_VRB(TAG, "");
if (searchman)
@ -959,7 +1008,7 @@ static int urbdrc_plugin_terminated(IWTSPlugin* pPlugin)
searchman->close(searchman);
/* free searchman */
if (searchman->strated)
if (searchman->started)
{
struct timespec ts;
ts.tv_sec = time(NULL)+10;
@ -983,7 +1032,7 @@ static int urbdrc_plugin_terminated(IWTSPlugin* pPlugin)
if(urbdrc)
zfree(urbdrc);
return 0;
return CHANNEL_RC_OK;
}
static void urbdrc_register_udevman_addin(IWTSPlugin* pPlugin, IUDEVMAN* udevman)
@ -1001,15 +1050,14 @@ static void urbdrc_register_udevman_addin(IWTSPlugin* pPlugin, IUDEVMAN* udevman
urbdrc->udevman = udevman;
}
static int urbdrc_load_udevman_addin(IWTSPlugin* pPlugin, const char* name, ADDIN_ARGV* args)
static WIN32ERROR urbdrc_load_udevman_addin(IWTSPlugin* pPlugin, const char* name, ADDIN_ARGV* args)
{
PFREERDP_URBDRC_DEVICE_ENTRY entry;
FREERDP_URBDRC_SERVICE_ENTRY_POINTS entryPoints;
entry = (PFREERDP_URBDRC_DEVICE_ENTRY) freerdp_load_channel_addin_entry("urbdrc", (LPSTR) name, NULL, 0);
if (entry == NULL)
return FALSE;
if (!entry)
return ERROR_INVALID_OPERATION;
entryPoints.plugin = pPlugin;
entryPoints.pRegisterUDEVMAN = urbdrc_register_udevman_addin;
@ -1018,16 +1066,17 @@ static int urbdrc_load_udevman_addin(IWTSPlugin* pPlugin, const char* name, ADDI
if (entry(&entryPoints) != 0)
{
WLog_ERR(TAG, "%s entry returns error.", name);
return FALSE;
return ERROR_INVALID_OPERATION;
}
return TRUE;
return CHANNEL_RC_OK;
}
void urbdrc_set_subsystem(URBDRC_PLUGIN* urbdrc, char* subsystem)
BOOL urbdrc_set_subsystem(URBDRC_PLUGIN* urbdrc, char* subsystem)
{
free(urbdrc->subsystem);
urbdrc->subsystem = _strdup(subsystem);
return (urbdrc->subsystem != NULL);
}
COMMAND_LINE_ARGUMENT_A urbdrc_args[] =
@ -1037,7 +1086,7 @@ COMMAND_LINE_ARGUMENT_A urbdrc_args[] =
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args)
static WIN32ERROR urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args)
{
int status;
DWORD flags;
@ -1047,6 +1096,8 @@ static void urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args)
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
urbdrc_args, flags, urbdrc, NULL, NULL);
if (status < 0)
return ERROR_INVALID_DATA;
arg = urbdrc_args;
@ -1063,7 +1114,8 @@ static void urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args)
}
CommandLineSwitchCase(arg, "sys")
{
urbdrc_set_subsystem(urbdrc, arg->Value);
if (!urbdrc_set_subsystem(urbdrc, arg->Value))
return ERROR_OUTOFMEMORY;
}
CommandLineSwitchDefault(arg)
{
@ -1073,15 +1125,16 @@ static void urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args)
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
return CHANNEL_RC_OK;
}
#ifdef STATIC_CHANNELS
#define DVCPluginEntry urbdrc_DVCPluginEntry
#endif
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
WIN32ERROR DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
int status = 0;
WIN32ERROR status = 0;
ADDIN_ARGV* args;
URBDRC_PLUGIN* urbdrc;
@ -1090,8 +1143,9 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
if (urbdrc == NULL)
{
urbdrc = (URBDRC_PLUGIN*) malloc(sizeof(URBDRC_PLUGIN));
ZeroMemory(urbdrc, sizeof(URBDRC_PLUGIN));
urbdrc = (URBDRC_PLUGIN*) calloc(1, sizeof(URBDRC_PLUGIN));
if (!urbdrc)
return CHANNEL_RC_NO_MEMORY;
urbdrc->iface.Initialize = urbdrc_plugin_initialize;
urbdrc->iface.Connected = NULL;
@ -1101,15 +1155,29 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
urbdrc->vchannel_status = INIT_CHANNEL_IN;
status = pEntryPoints->RegisterPlugin(pEntryPoints, "urbdrc", (IWTSPlugin*) urbdrc);
if (status != CHANNEL_RC_OK)
goto error_register;
}
if (status == 0)
urbdrc_process_addin_args(urbdrc, args);
status = urbdrc_process_addin_args(urbdrc, args);
if (status != CHANNEL_RC_OK)
{
/* TODO: we should unregister the plugin ? */
WLog_ERR(TAG, "error processing arguments");
//return status;
}
if (!urbdrc->subsystem)
urbdrc_set_subsystem(urbdrc, "libusb");
urbdrc_load_udevman_addin((IWTSPlugin*) urbdrc, urbdrc->subsystem, args);
if (!urbdrc->subsystem && !urbdrc_set_subsystem(urbdrc, "libusb"))
{
/* TODO: we should unregister the plugin ? */
WLog_ERR(TAG, "error setting subsystem");
return ERROR_OUTOFMEMORY;
}
return urbdrc_load_udevman_addin((IWTSPlugin*) urbdrc, urbdrc->subsystem, args);
error_register:
free(urbdrc);
return status;
}