diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index 01eda4a31..9543cb804 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -65,6 +65,7 @@ struct _UDEVMAN IUDEVICE* head; /* head device in linked list */ IUDEVICE* tail; /* tail device in linked list */ + LPSTR cmdline_devices; UINT16 flags; UINT32 device_num; UINT32 next_device_id; @@ -575,29 +576,6 @@ static BOOL udevman_initialize(IUDEVMAN* idevman, UINT32 channelId) return TRUE; } -static void udevman_load_interface(UDEVMAN* udevman) -{ - /* standard */ - udevman->iface.free = udevman_free; - /* manage devices */ - udevman->iface.rewind = udevman_rewind; - udevman->iface.get_next = udevman_get_next; - udevman->iface.has_next = udevman_has_next; - udevman->iface.register_udevice = udevman_register_udevice; - udevman->iface.unregister_udevice = udevman_unregister_udevice; - udevman->iface.get_udevice_by_UsbDevice = udevman_get_udevice_by_UsbDevice; - /* Extension */ - udevman->iface.isAutoAdd = udevman_is_auto_add; - /* Basic state */ - BASIC_STATE_FUNC_REGISTER(device_num, 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; - udevman->iface.initialize = udevman_initialize; -} - static BOOL udevman_parse_device_id_addr(const char** str, UINT16* id1, UINT16* id2, UINT16 max, char split_sign, char delimiter) { @@ -663,7 +641,6 @@ static UINT urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args) { int status; DWORD flags; - LPSTR devices = NULL; const UINT16 mask = UDEVMAN_FLAG_ADD_BY_VID_PID | UDEVMAN_FLAG_ADD_BY_ADDR; COMMAND_LINE_ARGUMENT_A* arg; COMMAND_LINE_ARGUMENT_A urbdrc_udevman_args[] = { @@ -696,7 +673,7 @@ static UINT urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args) } CommandLineSwitchCase(arg, "dev") { - devices = arg->Value; + udevman->cmdline_devices = arg->Value; } CommandLineSwitchCase(arg, "id") { @@ -720,16 +697,47 @@ static UINT urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args) if ((udevman->flags & mask) == mask) return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; - /* Add listed devices after we know the format of addressing */ - if (devices) + return CHANNEL_RC_OK; +} + +static UINT udevman_listener_created_callback(IUDEVMAN* iudevman) +{ + UDEVMAN* udevman = (UDEVMAN*)iudevman; + + if (udevman->cmdline_devices && + !urbdrc_udevman_register_devices(udevman, udevman->cmdline_devices)) { - if (!urbdrc_udevman_register_devices(udevman, devices)) - return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + WLog_ERR(TAG, "Invalid device id: \"%s\"", udevman->cmdline_devices); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; } return CHANNEL_RC_OK; } +static void udevman_load_interface(UDEVMAN* udevman) +{ + /* standard */ + udevman->iface.free = udevman_free; + /* manage devices */ + udevman->iface.rewind = udevman_rewind; + udevman->iface.get_next = udevman_get_next; + udevman->iface.has_next = udevman_has_next; + udevman->iface.register_udevice = udevman_register_udevice; + udevman->iface.unregister_udevice = udevman_unregister_udevice; + udevman->iface.get_udevice_by_UsbDevice = udevman_get_udevice_by_UsbDevice; + /* Extension */ + udevman->iface.isAutoAdd = udevman_is_auto_add; + /* Basic state */ + BASIC_STATE_FUNC_REGISTER(device_num, 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; + udevman->iface.initialize = udevman_initialize; + udevman->iface.listener_created_callback = udevman_listener_created_callback; +} + static BOOL poll_libusb_events(UDEVMAN* udevman) { int rc = LIBUSB_SUCCESS; diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index cf5673473..201b28073 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -663,7 +663,9 @@ static UINT urbdrc_on_new_channel_connection(IWTSListenerCallback* pListenerCall */ static UINT urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) { + UINT status; URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*)pPlugin; + IUDEVMAN* udevman = urbdrc->udevman; char channelName[sizeof(URBDRC_CHANNEL_NAME)] = { URBDRC_CHANNEL_NAME }; if (!urbdrc) @@ -681,8 +683,15 @@ static UINT urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana /* [MS-RDPEUSB] 2.1 Transport defines the channel name in uppercase letters */ CharUpperA(channelName); - return pChannelMgr->CreateListener(pChannelMgr, channelName, 0, - &urbdrc->listener_callback->iface, NULL); + status = pChannelMgr->CreateListener(pChannelMgr, channelName, 0, + &urbdrc->listener_callback->iface, NULL); + if (status != CHANNEL_RC_OK) + return status; + + if (udevman->listener_created_callback) + return udevman->listener_created_callback(udevman); + + return CHANNEL_RC_OK; } /** diff --git a/channels/urbdrc/client/urbdrc_main.h b/channels/urbdrc/client/urbdrc_main.h index 749aaf872..2a750d64d 100644 --- a/channels/urbdrc/client/urbdrc_main.h +++ b/channels/urbdrc/client/urbdrc_main.h @@ -216,6 +216,7 @@ struct _IUDEVMAN void (*loading_lock)(IUDEVMAN* idevman); void (*loading_unlock)(IUDEVMAN* idevman); BOOL (*initialize)(IUDEVMAN* idevman, UINT32 channelId); + UINT (*listener_created_callback)(IUDEVMAN* idevman); IWTSPlugin* plugin; UINT32 controlChannelId;