Hardened urbdrc channel
This commit is contained in:
parent
1b7140d84e
commit
b83ab92776
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user