Cleaned up USB redirection
* Removed obsolete searchman * Unified device add and virtual channel add * Unified device id generation
This commit is contained in:
parent
acb77391a2
commit
1b1ab01e43
@ -18,9 +18,7 @@
|
||||
|
||||
define_channel_client("urbdrc")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
searchman.c
|
||||
searchman.h
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
data_transfer.c
|
||||
data_transfer.h
|
||||
urbdrc_main.c
|
||||
|
@ -1037,8 +1037,7 @@ static void libusb_udev_channel_closed(IUDEVICE* idev)
|
||||
UDEVICE* pdev = (UDEVICE*)idev;
|
||||
if (pdev)
|
||||
{
|
||||
const UINT16 idVendor = (UINT16)idev->query_device_descriptor(idev, ID_VENDOR);
|
||||
const UINT16 idProduct = (UINT16)idev->query_device_descriptor(idev, ID_PRODUCT);
|
||||
URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
|
||||
const uint8_t busNr = idev->get_bus_number(idev);
|
||||
const uint8_t devNr = idev->get_dev_number(idev);
|
||||
IWTSVirtualChannel* channel = NULL;
|
||||
@ -1051,14 +1050,10 @@ static void libusb_udev_channel_closed(IUDEVICE* idev)
|
||||
|
||||
if (channel)
|
||||
{
|
||||
URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
|
||||
USB_SEARCHMAN* searchman = urbdrc->searchman;
|
||||
|
||||
/* Notify the server the device is no longer available. */
|
||||
channel->Write(channel, 0, NULL, NULL);
|
||||
urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr);
|
||||
searchman->add(searchman, idVendor, idProduct);
|
||||
}
|
||||
urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1381,11 +1376,6 @@ static void udev_set_UsbDevice(IUDEVICE* idev, UINT32 val)
|
||||
if (!pdev)
|
||||
return;
|
||||
|
||||
val = 0x10 + val;
|
||||
|
||||
if (val < 0x10)
|
||||
val += 0x10;
|
||||
|
||||
pdev->UsbDevice = val;
|
||||
}
|
||||
|
||||
|
@ -64,10 +64,10 @@ struct _UDEVMAN
|
||||
IUDEVICE* head; /* head device in linked list */
|
||||
IUDEVICE* tail; /* tail device in linked list */
|
||||
|
||||
UINT32 defUsbDevice;
|
||||
UINT16 flags;
|
||||
UINT32 device_num;
|
||||
int sem_timeout;
|
||||
UINT32 next_device_id;
|
||||
UINT32 channel_id;
|
||||
|
||||
HANDLE devman_loading;
|
||||
libusb_context* context;
|
||||
@ -131,8 +131,7 @@ static IUDEVICE* udevman_get_udevice_by_addr(IUDEVMAN* idevman, BYTE bus_number,
|
||||
}
|
||||
|
||||
static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number,
|
||||
UINT32 UsbDevice, UINT16 idVendor, UINT16 idProduct,
|
||||
int flag)
|
||||
UINT16 idVendor, UINT16 idProduct, UINT32 flag)
|
||||
{
|
||||
UDEVMAN* udevman = (UDEVMAN*)idevman;
|
||||
IUDEVICE* pdev = NULL;
|
||||
@ -149,14 +148,16 @@ static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE
|
||||
if (pdev != NULL)
|
||||
return 0;
|
||||
|
||||
if (flag == UDEVMAN_FLAG_ADD_BY_ADDR)
|
||||
if (flag & UDEVMAN_FLAG_ADD_BY_ADDR)
|
||||
{
|
||||
UINT32 id;
|
||||
IUDEVICE* tdev = udev_new_by_addr(urbdrc, udevman->context, bus_number, dev_number);
|
||||
|
||||
if (tdev == NULL)
|
||||
return 0;
|
||||
|
||||
tdev->set_UsbDevice(tdev, UsbDevice);
|
||||
id = idevman->get_next_device_id(idevman);
|
||||
tdev->set_UsbDevice(tdev, id);
|
||||
idevman->loading_lock(idevman);
|
||||
|
||||
if (udevman->head == NULL)
|
||||
@ -176,7 +177,7 @@ static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE
|
||||
udevman->device_num += 1;
|
||||
idevman->loading_unlock(idevman);
|
||||
}
|
||||
else if (flag == UDEVMAN_FLAG_ADD_BY_VID_PID)
|
||||
else if (flag & UDEVMAN_FLAG_ADD_BY_VID_PID)
|
||||
{
|
||||
addnum = 0;
|
||||
/* register all device that match pid vid */
|
||||
@ -184,6 +185,7 @@ static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
UINT32 id;
|
||||
IUDEVICE* tdev = devArray[i];
|
||||
|
||||
if (udevman_get_udevice_by_addr(idevman, tdev->get_bus_number(tdev),
|
||||
@ -194,7 +196,8 @@ static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE
|
||||
continue;
|
||||
}
|
||||
|
||||
tdev->set_UsbDevice(tdev, UsbDevice);
|
||||
id = idevman->get_next_device_id(idevman);
|
||||
tdev->set_UsbDevice(tdev, id);
|
||||
idevman->loading_lock(idevman);
|
||||
|
||||
if (udevman->head == NULL)
|
||||
@ -291,28 +294,6 @@ static BOOL udevman_unregister_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL udevman_cancel_all_device_requests(IUDEVMAN* idevman)
|
||||
{
|
||||
if (!idevman)
|
||||
return FALSE;
|
||||
|
||||
idevman->loading_lock(idevman);
|
||||
idevman->rewind(idevman);
|
||||
|
||||
while (idevman->has_next(idevman))
|
||||
{
|
||||
UDEVICE* dev = (UDEVICE*)idevman->get_next(idevman);
|
||||
|
||||
if (!dev)
|
||||
continue;
|
||||
dev->iface.cancel_all_transfer_request(&dev->iface);
|
||||
}
|
||||
|
||||
idevman->loading_unlock(idevman);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL udevman_unregister_all_udevices(IUDEVMAN* idevman)
|
||||
{
|
||||
UDEVMAN* udevman = (UDEVMAN*)idevman;
|
||||
@ -484,9 +465,19 @@ static void udevman_loading_unlock(IUDEVMAN* idevman)
|
||||
ReleaseMutex(udevman->devman_loading);
|
||||
}
|
||||
|
||||
BASIC_STATE_FUNC_DEFINED(defUsbDevice, UINT32)
|
||||
BASIC_STATE_FUNC_DEFINED(device_num, UINT32)
|
||||
BASIC_STATE_FUNC_DEFINED(sem_timeout, int)
|
||||
|
||||
static UINT32 udevman_get_next_device_id(IUDEVMAN* idevman)
|
||||
{
|
||||
UDEVMAN* udevman = (UDEVMAN*)idevman;
|
||||
return udevman->next_device_id++;
|
||||
}
|
||||
|
||||
static void udevman_set_next_device_id(IUDEVMAN* idevman, UINT32 _t)
|
||||
{
|
||||
UDEVMAN* udevman = (UDEVMAN*)idevman;
|
||||
udevman->next_device_id = _t;
|
||||
}
|
||||
|
||||
static void udevman_free(IUDEVMAN* idevman)
|
||||
{
|
||||
@ -632,7 +623,8 @@ static int hotplug_callback(struct libusb_context* ctx, struct libusb_device* de
|
||||
switch (event)
|
||||
{
|
||||
case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
|
||||
add_device(idevman, bus, addr, desc.idVendor, desc.idProduct);
|
||||
if (idevman->isAutoAdd(idevman))
|
||||
add_device(idevman, DEVICE_ADD_FLAG_ALL, bus, addr, desc.idVendor, desc.idProduct);
|
||||
break;
|
||||
|
||||
case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
|
||||
@ -671,9 +663,9 @@ static void udevman_load_interface(UDEVMAN* udevman)
|
||||
/* Extension */
|
||||
udevman->iface.isAutoAdd = udevman_is_auto_add;
|
||||
/* Basic state */
|
||||
BASIC_STATE_FUNC_REGISTER(defUsbDevice, udevman);
|
||||
BASIC_STATE_FUNC_REGISTER(device_num, udevman);
|
||||
BASIC_STATE_FUNC_REGISTER(sem_timeout, udevman);
|
||||
BASIC_STATE_FUNC_REGISTER(next_device_id, udevman);
|
||||
|
||||
/* control semaphore or mutex lock */
|
||||
udevman->iface.loading_lock = udevman_loading_lock;
|
||||
udevman->iface.loading_unlock = udevman_loading_unlock;
|
||||
@ -688,7 +680,6 @@ static BOOL urbdrc_udevman_register_devices(UDEVMAN* udevman, const char* device
|
||||
char* tmp;
|
||||
char hardware_id[16];
|
||||
const char* default_devices = "id";
|
||||
UINT32 UsbDevice = BASE_USBDEVICE_NUM;
|
||||
|
||||
if (!devices)
|
||||
tmp = _strdup(default_devices);
|
||||
@ -711,8 +702,8 @@ static BOOL urbdrc_udevman_register_devices(UDEVMAN* udevman, const char* device
|
||||
&idProduct, ':'))
|
||||
goto fail;
|
||||
|
||||
success = udevman->iface.register_udevice((IUDEVMAN*)udevman, 0, 0, UsbDevice, idVendor,
|
||||
idProduct, UDEVMAN_FLAG_ADD_BY_VID_PID);
|
||||
success = add_device(&udevman->iface, DEVICE_ADD_FLAG_VENDOR | DEVICE_ADD_FLAG_PRODUCT,
|
||||
0, 0, idVendor, idProduct);
|
||||
}
|
||||
else if (udevman->flags & UDEVMAN_FLAG_ADD_BY_ADDR)
|
||||
{
|
||||
@ -722,15 +713,11 @@ static BOOL urbdrc_udevman_register_devices(UDEVMAN* udevman, const char* device
|
||||
&dev_number, ':'))
|
||||
goto fail;
|
||||
|
||||
success = udevman->iface.register_udevice((IUDEVMAN*)udevman, bus_number, dev_number,
|
||||
UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR);
|
||||
success = add_device(&udevman->iface, DEVICE_ADD_FLAG_BUS | DEVICE_ADD_FLAG_DEV,
|
||||
bus_number, dev_number, 0, 0);
|
||||
}
|
||||
|
||||
if (success)
|
||||
UsbDevice++;
|
||||
}
|
||||
|
||||
udevman->defUsbDevice = UsbDevice;
|
||||
rc = TRUE;
|
||||
fail:
|
||||
free(tmp);
|
||||
@ -865,6 +852,7 @@ int freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS p
|
||||
if (!udevman)
|
||||
goto fail;
|
||||
|
||||
udevman->next_device_id = BASE_USBDEVICE_NUM;
|
||||
udevman->iface.plugin = pEntryPoints->plugin;
|
||||
rc = libusb_init(&udevman->context);
|
||||
|
||||
|
@ -1,207 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RemoteFX USB Redirection
|
||||
*
|
||||
* Copyright 2012 Atrust corp.
|
||||
* Copyright 2012 Alfred Liu <alfred.liu@atruscorp.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#include "searchman.h"
|
||||
#include "urbdrc_main.h"
|
||||
|
||||
static void searchman_rewind(USB_SEARCHMAN* searchman)
|
||||
{
|
||||
searchman->idev = searchman->head;
|
||||
}
|
||||
|
||||
static USB_SEARCHDEV* searchman_get_next(USB_SEARCHMAN* searchman)
|
||||
{
|
||||
USB_SEARCHDEV* search;
|
||||
if (!searchman)
|
||||
return NULL;
|
||||
|
||||
search = searchman->idev;
|
||||
if (!search)
|
||||
return NULL;
|
||||
|
||||
searchman->idev = (USB_SEARCHDEV*)searchman->idev->next;
|
||||
return search;
|
||||
}
|
||||
|
||||
static USB_SEARCHDEV* searchman_get_by_vid_pid(USB_SEARCHMAN* searchman, UINT16 idVendor,
|
||||
UINT16 idProduct)
|
||||
{
|
||||
USB_SEARCHDEV* dev;
|
||||
if (!searchman)
|
||||
return NULL;
|
||||
|
||||
searchman->rewind(searchman);
|
||||
|
||||
while ((dev = searchman->get_next(searchman)) != NULL)
|
||||
{
|
||||
if ((dev->idVendor == idVendor) && (dev->idProduct == idProduct))
|
||||
{
|
||||
WLog_VRB(TAG, "Searchman Find Device: %04" PRIx16 ":%04" PRIx16 "", dev->idVendor,
|
||||
dev->idProduct);
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL searchman_list_add(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct)
|
||||
{
|
||||
USB_SEARCHDEV* search;
|
||||
search = (USB_SEARCHDEV*)calloc(1, sizeof(USB_SEARCHDEV));
|
||||
|
||||
if (!search)
|
||||
return FALSE;
|
||||
|
||||
search->idVendor = idVendor;
|
||||
search->idProduct = idProduct;
|
||||
|
||||
if (searchman->head == NULL)
|
||||
{
|
||||
/* linked list is empty */
|
||||
searchman->head = search;
|
||||
searchman->tail = search;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* append device to the end of the linked list */
|
||||
searchman->tail->next = (void*)search;
|
||||
search->prev = (void*)searchman->tail;
|
||||
searchman->tail = search;
|
||||
}
|
||||
|
||||
searchman->usb_numbers += 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int searchman_list_remove(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct)
|
||||
{
|
||||
USB_SEARCHDEV* search;
|
||||
USB_SEARCHDEV* point;
|
||||
searchman_rewind(searchman);
|
||||
|
||||
while ((point = searchman_get_next(searchman)) != NULL)
|
||||
{
|
||||
if ((point->idVendor == idVendor) && (point->idProduct == idProduct))
|
||||
{
|
||||
/* set previous device to point to next device */
|
||||
search = point;
|
||||
|
||||
if (search->prev != NULL)
|
||||
{
|
||||
/* unregistered device is not the head */
|
||||
point = (USB_SEARCHDEV*)search->prev;
|
||||
point->next = search->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unregistered device is the head, update head */
|
||||
searchman->head = (USB_SEARCHDEV*)search->next;
|
||||
}
|
||||
|
||||
/* set next device to point to previous device */
|
||||
|
||||
if (search->next != NULL)
|
||||
{
|
||||
/* unregistered device is not the tail */
|
||||
point = (USB_SEARCHDEV*)search->next;
|
||||
point->prev = search->prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unregistered device is the tail, update tail */
|
||||
searchman->tail = (USB_SEARCHDEV*)search->prev;
|
||||
}
|
||||
|
||||
searchman->usb_numbers--;
|
||||
free(search);
|
||||
return 1; /* unregistration successful */
|
||||
}
|
||||
}
|
||||
|
||||
/* if we reach this point, the device wasn't found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void searchman_list_show(USB_SEARCHMAN* self)
|
||||
{
|
||||
int num = 0;
|
||||
USB_SEARCHDEV* usb;
|
||||
URBDRC_PLUGIN* urbdrc;
|
||||
|
||||
if (!self || !self->urbdrc)
|
||||
return;
|
||||
|
||||
urbdrc = self->urbdrc;
|
||||
WLog_Print(urbdrc->log, WLOG_DEBUG, "=========== Usb Search List =========");
|
||||
self->rewind(self);
|
||||
|
||||
while ((usb = self->get_next(self)) != NULL)
|
||||
{
|
||||
WLog_Print(urbdrc->log, WLOG_DEBUG, " USB %d: ", num++);
|
||||
WLog_Print(urbdrc->log, WLOG_DEBUG, " idVendor: 0x%04" PRIX16 "", usb->idVendor);
|
||||
WLog_Print(urbdrc->log, WLOG_DEBUG, " idProduct: 0x%04" PRIX16 "", usb->idProduct);
|
||||
}
|
||||
|
||||
WLog_Print(urbdrc->log, WLOG_DEBUG, "================= END ===============");
|
||||
}
|
||||
|
||||
void searchman_free(USB_SEARCHMAN* self)
|
||||
{
|
||||
USB_SEARCHDEV* dev;
|
||||
|
||||
while (self->head != NULL)
|
||||
{
|
||||
dev = (USB_SEARCHDEV*)self->head;
|
||||
self->remove(self, dev->idVendor, dev->idProduct);
|
||||
}
|
||||
|
||||
/* free searchman */
|
||||
free(self);
|
||||
}
|
||||
|
||||
USB_SEARCHMAN* searchman_new(void* urbdrc, UINT32 UsbDevice)
|
||||
{
|
||||
USB_SEARCHMAN* searchman;
|
||||
searchman = (USB_SEARCHMAN*)calloc(1, sizeof(USB_SEARCHMAN));
|
||||
|
||||
if (!searchman)
|
||||
return NULL;
|
||||
|
||||
searchman->urbdrc = urbdrc;
|
||||
searchman->UsbDevice = UsbDevice;
|
||||
/* load service */
|
||||
searchman->add = searchman_list_add;
|
||||
searchman->remove = searchman_list_remove;
|
||||
searchman->rewind = searchman_rewind;
|
||||
searchman->get_next = searchman_get_next;
|
||||
searchman->show = searchman_list_show;
|
||||
searchman->get_next_by_vid_pid = searchman_get_by_vid_pid;
|
||||
searchman->free = searchman_free;
|
||||
return searchman;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RemoteFX USB Redirection
|
||||
*
|
||||
* Copyright 2012 Atrust corp.
|
||||
* Copyright 2012 Alfred Liu <alfred.liu@atruscorp.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CHANNEL_URBDRC_CLIENT_SEARCHMAN_H
|
||||
#define FREERDP_CHANNEL_URBDRC_CLIENT_SEARCHMAN_H
|
||||
|
||||
#include "urbdrc_types.h"
|
||||
|
||||
typedef struct _USB_SEARCHDEV USB_SEARCHDEV;
|
||||
|
||||
struct _USB_SEARCHDEV
|
||||
{
|
||||
void* inode;
|
||||
void* prev;
|
||||
void* next;
|
||||
UINT16 idVendor;
|
||||
UINT16 idProduct;
|
||||
};
|
||||
|
||||
typedef struct _USB_SEARCHMAN USB_SEARCHMAN;
|
||||
|
||||
struct _USB_SEARCHMAN
|
||||
{
|
||||
int usb_numbers;
|
||||
UINT32 UsbDevice;
|
||||
USB_SEARCHDEV* idev; /* iterator device */
|
||||
USB_SEARCHDEV* head; /* head device in linked list */
|
||||
USB_SEARCHDEV* tail; /* tail device in linked list */
|
||||
|
||||
/* for urbdrc channel call back */
|
||||
void* urbdrc;
|
||||
|
||||
/* load service */
|
||||
void (*rewind)(USB_SEARCHMAN* seachman);
|
||||
/* show all device in the list */
|
||||
void (*show)(USB_SEARCHMAN* self);
|
||||
/* add a new usb device for search */
|
||||
BOOL (*add)(USB_SEARCHMAN* seachman, UINT16 idVendor, UINT16 idProduct);
|
||||
/* remove a usb device from list */
|
||||
int (*remove)(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct);
|
||||
/* get the device from list*/
|
||||
USB_SEARCHDEV* (*get_next)(USB_SEARCHMAN* seachman);
|
||||
/* get the device by vendor and product */
|
||||
USB_SEARCHDEV* (*get_next_by_vid_pid)(USB_SEARCHMAN* seachman, UINT16 idVendor,
|
||||
UINT16 idProduct);
|
||||
/* free! */
|
||||
void (*free)(USB_SEARCHMAN* searchman);
|
||||
};
|
||||
|
||||
USB_SEARCHMAN* searchman_new(void* urbdrc, UINT32 UsbDevice);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_URBDRC_CLIENT_SEARCHMAN_H */
|
@ -40,7 +40,7 @@
|
||||
#include "urbdrc_types.h"
|
||||
#include "urbdrc_main.h"
|
||||
#include "data_transfer.h"
|
||||
#include "searchman.h"
|
||||
|
||||
#include <urbdrc_helpers.h>
|
||||
|
||||
static BOOL Stream_Write_UTF16_String_From_Utf8(wStream* s, const char* utf8, size_t len)
|
||||
@ -408,13 +408,39 @@ static UINT urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, wStr
|
||||
return error;
|
||||
}
|
||||
|
||||
static BOOL urbdrc_announce_devices(IUDEVMAN* udevman)
|
||||
{
|
||||
UINT error = ERROR_SUCCESS;
|
||||
|
||||
udevman->loading_lock(udevman);
|
||||
udevman->rewind(udevman);
|
||||
|
||||
while (udevman->has_next(udevman))
|
||||
{
|
||||
IUDEVICE* pdev = udevman->get_next(udevman);
|
||||
|
||||
if (!pdev->isAlreadySend(pdev))
|
||||
{
|
||||
const UINT32 deviceId = pdev->get_UsbDevice(pdev);
|
||||
UINT error =
|
||||
urdbrc_send_virtual_channel_add(udevman->plugin, get_channel(udevman), deviceId);
|
||||
|
||||
if (error != ERROR_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
udevman->loading_unlock(udevman);
|
||||
|
||||
return error == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT urbdrc_device_control_channel(URBDRC_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*)callback->plugin;
|
||||
IUDEVMAN* udevman = urbdrc->udevman;
|
||||
IWTSVirtualChannel* channel = callback->channel;
|
||||
IUDEVICE* pdev = NULL;
|
||||
UINT32 i = 0;
|
||||
BOOL found = FALSE;
|
||||
UINT error = ERROR_INTERNAL_ERROR;
|
||||
UINT32 channelId = callback->channel_mgr->GetChannelId(channel);
|
||||
@ -426,13 +452,8 @@ static UINT urbdrc_device_control_channel(URBDRC_CHANNEL_CALLBACK* callback, wSt
|
||||
error = ERROR_SUCCESS;
|
||||
udevman->initialize(udevman, channelId);
|
||||
|
||||
for (i = 0; i < udevman->get_device_num(udevman); i++)
|
||||
{
|
||||
error = urdbrc_send_virtual_channel_add(callback->plugin, callback->channel, i);
|
||||
|
||||
if (error != ERROR_SUCCESS)
|
||||
goto fail;
|
||||
}
|
||||
if (!urbdrc_announce_devices(udevman))
|
||||
goto fail;
|
||||
|
||||
urbdrc->vchannel_status = INIT_CHANNEL_OUT;
|
||||
break;
|
||||
@ -635,8 +656,6 @@ static UINT urbdrc_on_new_channel_connection(IWTSListenerCallback* pListenerCall
|
||||
static UINT urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
||||
{
|
||||
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*)pPlugin;
|
||||
IUDEVMAN* udevman = NULL;
|
||||
USB_SEARCHMAN* searchman = NULL;
|
||||
char channelName[sizeof(URBDRC_CHANNEL_NAME)] = { URBDRC_CHANNEL_NAME };
|
||||
|
||||
if (!urbdrc)
|
||||
@ -651,18 +670,7 @@ static UINT urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana
|
||||
urbdrc->listener_callback->iface.OnNewChannelConnection = urbdrc_on_new_channel_connection;
|
||||
urbdrc->listener_callback->plugin = pPlugin;
|
||||
urbdrc->listener_callback->channel_mgr = pChannelMgr;
|
||||
/* 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;
|
||||
/* [MS-RDPEUSB] 2.1 Transport defines the channel name in uppercase letters */
|
||||
CharUpperA(channelName);
|
||||
return pChannelMgr->CreateListener(pChannelMgr, channelName, 0,
|
||||
@ -678,20 +686,11 @@ static UINT urbdrc_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
{
|
||||
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*)pPlugin;
|
||||
IUDEVMAN* udevman;
|
||||
USB_SEARCHMAN* searchman;
|
||||
|
||||
if (!urbdrc)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
udevman = urbdrc->udevman;
|
||||
searchman = urbdrc->searchman;
|
||||
|
||||
if (searchman)
|
||||
{
|
||||
/* close searchman */
|
||||
searchman->free(searchman);
|
||||
searchman = NULL;
|
||||
}
|
||||
|
||||
if (udevman)
|
||||
{
|
||||
@ -804,13 +803,12 @@ static UINT urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, const ADDIN_ARGV* a
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
BOOL add_device(IUDEVMAN* idevman, BYTE busnum, BYTE devnum, UINT16 idVendor, UINT16 idProduct)
|
||||
BOOL add_device(IUDEVMAN* idevman, UINT32 flags, BYTE busnum, BYTE devnum, UINT16 idVendor,
|
||||
UINT16 idProduct)
|
||||
{
|
||||
USB_SEARCHDEV* sdev = NULL;
|
||||
size_t success = 0;
|
||||
BOOL found = FALSE;
|
||||
URBDRC_PLUGIN* urbdrc;
|
||||
USB_SEARCHMAN* searchman;
|
||||
UINT32 mask, regflags = 0;
|
||||
|
||||
if (!idevman)
|
||||
return FALSE;
|
||||
@ -820,33 +818,19 @@ BOOL add_device(IUDEVMAN* idevman, BYTE busnum, BYTE devnum, UINT16 idVendor, UI
|
||||
if (!urbdrc || !urbdrc->listener_callback)
|
||||
return FALSE;
|
||||
|
||||
searchman = urbdrc->searchman;
|
||||
mask = (DEVICE_ADD_FLAG_VENDOR | DEVICE_ADD_FLAG_PRODUCT);
|
||||
if ((flags & mask) == mask)
|
||||
regflags |= UDEVMAN_FLAG_ADD_BY_VID_PID;
|
||||
mask = (DEVICE_ADD_FLAG_BUS | DEVICE_ADD_FLAG_DEV);
|
||||
if ((flags & mask) == mask)
|
||||
regflags |= UDEVMAN_FLAG_ADD_BY_ADDR;
|
||||
|
||||
if (!searchman)
|
||||
return FALSE;
|
||||
success = idevman->register_udevice(idevman, busnum, devnum, idVendor, idProduct, regflags);
|
||||
|
||||
sdev = searchman->get_next_by_vid_pid(searchman, idVendor, idProduct);
|
||||
|
||||
if (!sdev && idevman->isAutoAdd(idevman))
|
||||
if ((success > 0) && (flags & DEVICE_ADD_FLAG_REGISTER))
|
||||
{
|
||||
WLog_Print(urbdrc->log, WLOG_TRACE, "Auto Find Device: %04x:%04x ", idVendor, idProduct);
|
||||
found = TRUE;
|
||||
}
|
||||
|
||||
if (sdev || found)
|
||||
{
|
||||
success = idevman->register_udevice(idevman, busnum, devnum, searchman->UsbDevice, 0, 0,
|
||||
UDEVMAN_FLAG_ADD_BY_ADDR);
|
||||
}
|
||||
|
||||
if (success > 0)
|
||||
{
|
||||
searchman->UsbDevice++;
|
||||
urdbrc_send_virtual_channel_add(idevman->plugin, get_channel(idevman),
|
||||
5 + searchman->UsbDevice);
|
||||
|
||||
if (sdev)
|
||||
searchman->remove(searchman, sdev->idVendor, sdev->idProduct);
|
||||
if (!urbdrc_announce_devices(idevman))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -856,7 +840,6 @@ BOOL del_device(IUDEVMAN* idevman, BYTE busnum, BYTE devnum, UINT16 idVendor, UI
|
||||
{
|
||||
IUDEVICE* pdev = NULL;
|
||||
URBDRC_PLUGIN* urbdrc;
|
||||
USB_SEARCHMAN* searchman;
|
||||
|
||||
if (!idevman)
|
||||
return FALSE;
|
||||
@ -866,11 +849,6 @@ BOOL del_device(IUDEVMAN* idevman, BYTE busnum, BYTE devnum, UINT16 idVendor, UI
|
||||
if (!urbdrc || !urbdrc->listener_callback)
|
||||
return FALSE;
|
||||
|
||||
searchman = urbdrc->searchman;
|
||||
|
||||
if (!searchman)
|
||||
return FALSE;
|
||||
|
||||
idevman->loading_lock(idevman);
|
||||
idevman->rewind(idevman);
|
||||
|
||||
|
@ -24,8 +24,6 @@
|
||||
#include <winpr/pool.h>
|
||||
#include <freerdp/channels/log.h>
|
||||
|
||||
#include "searchman.h"
|
||||
|
||||
#define DEVICE_HARDWARE_ID_SIZE 32
|
||||
#define DEVICE_COMPATIBILITY_ID_SIZE 36
|
||||
#define DEVICE_INSTANCE_STR_SIZE 37
|
||||
@ -82,7 +80,6 @@ struct _URBDRC_PLUGIN
|
||||
URBDRC_LISTENER_CALLBACK* listener_callback;
|
||||
|
||||
IUDEVMAN* udevman;
|
||||
USB_SEARCHMAN* searchman;
|
||||
UINT32 vchannel_status;
|
||||
char* subsystem;
|
||||
|
||||
@ -204,8 +201,8 @@ struct _IUDEVMAN
|
||||
void (*rewind)(IUDEVMAN* idevman);
|
||||
BOOL (*has_next)(IUDEVMAN* idevman);
|
||||
BOOL (*unregister_udevice)(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number);
|
||||
size_t (*register_udevice)(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number,
|
||||
UINT32 UsbDevice, UINT16 idVendor, UINT16 idProduct, int flag);
|
||||
size_t (*register_udevice)(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number, UINT16 idVendor,
|
||||
UINT16 idProduct, UINT32 flag);
|
||||
IUDEVICE* (*get_next)(IUDEVMAN* idevman);
|
||||
IUDEVICE* (*get_udevice_by_UsbDevice)(IUDEVMAN* idevman, UINT32 UsbDevice);
|
||||
|
||||
@ -213,9 +210,8 @@ struct _IUDEVMAN
|
||||
int (*isAutoAdd)(IUDEVMAN* idevman);
|
||||
|
||||
/* Basic state */
|
||||
BASIC_DEVMAN_STATE_DEFINED(defUsbDevice, UINT32);
|
||||
BASIC_DEVMAN_STATE_DEFINED(device_num, UINT32);
|
||||
BASIC_DEVMAN_STATE_DEFINED(sem_timeout, int);
|
||||
BASIC_DEVMAN_STATE_DEFINED(next_device_id, UINT32);
|
||||
|
||||
/* control semaphore or mutex lock */
|
||||
void (*loading_lock)(IUDEVMAN* idevman);
|
||||
@ -226,8 +222,20 @@ struct _IUDEVMAN
|
||||
UINT32 controlChannelId;
|
||||
};
|
||||
|
||||
FREERDP_API BOOL add_device(IUDEVMAN* idevman, BYTE busnum, BYTE devnum, UINT16 idVendor,
|
||||
UINT16 idProduct);
|
||||
enum
|
||||
{
|
||||
DEVICE_ADD_FLAG_BUS,
|
||||
DEVICE_ADD_FLAG_DEV,
|
||||
DEVICE_ADD_FLAG_VENDOR,
|
||||
DEVICE_ADD_FLAG_PRODUCT,
|
||||
DEVICE_ADD_FLAG_REGISTER
|
||||
} device_add_flag_t;
|
||||
#define DEVICE_ADD_FLAG_ALL \
|
||||
(DEVICE_ADD_FLAG_BUS | DEVICE_ADD_FLAG_DEV | DEVICE_ADD_FLAG_VENDOR | \
|
||||
DEVICE_ADD_FLAG_PRODUCT | DEVICE_ADD_FLAG_REGISTER)
|
||||
|
||||
FREERDP_API BOOL add_device(IUDEVMAN* idevman, UINT32 flags, BYTE busnum, BYTE devnum,
|
||||
UINT16 idVendor, UINT16 idProduct);
|
||||
FREERDP_API BOOL del_device(IUDEVMAN* idevman, BYTE busnum, BYTE devnum, UINT16 idVendor,
|
||||
UINT16 idProduct);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user