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
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;
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);
}
}
if (!pdev)
return;
- val = 0x10 + val;
-
- if (val < 0x10)
- val += 0x10;
-
pdev->UsbDevice = val;
}
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;
}
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;
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)
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 */
for (i = 0; i < num; i++)
{
+ UINT32 id;
IUDEVICE* tdev = devArray[i];
if (udevman_get_udevice_by_addr(idevman, tdev->get_bus_number(tdev),
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)
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;
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)
{
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:
/* 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;
char* tmp;
char hardware_id[16];
const char* default_devices = "id";
- UINT32 UsbDevice = BASE_USBDEVICE_NUM;
if (!devices)
tmp = _strdup(default_devices);
&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)
{
&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);
if (!udevman)
goto fail;
+ udevman->next_device_id = BASE_USBDEVICE_NUM;
udevman->iface.plugin = pEntryPoints->plugin;
rc = libusb_init(&udevman->context);
+++ /dev/null
-/**
- * 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;
-}
+++ /dev/null
-/**
- * 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 */
#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)
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);
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;
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)
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,
{
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)
{
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;
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;
{
IUDEVICE* pdev = NULL;
URBDRC_PLUGIN* urbdrc;
- USB_SEARCHMAN* searchman;
if (!idevman)
return FALSE;
if (!urbdrc || !urbdrc->listener_callback)
return FALSE;
- searchman = urbdrc->searchman;
-
- if (!searchman)
- return FALSE;
-
idevman->loading_lock(idevman);
idevman->rewind(idevman);
#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
URBDRC_LISTENER_CALLBACK* listener_callback;
IUDEVMAN* udevman;
- USB_SEARCHMAN* searchman;
UINT32 vchannel_status;
char* subsystem;
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);
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);
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);