From 4eb5b8e349e91b497f0b00759a898d66d3b73d7c Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 14 Nov 2017 16:10:52 +0100 Subject: [PATCH] Replaced atoi --- channels/audin/client/audin_main.c | 21 +- channels/audin/client/oss/audin_oss.c | 13 +- channels/rdpsnd/client/oss/rdpsnd_oss.c | 45 +- channels/rdpsnd/client/rdpsnd_main.c | 43 +- channels/urbdrc/client/libusb/libusb_udevice.c | 734 +++++++++++++------------ channels/urbdrc/client/libusb/libusb_udevman.c | 132 ++--- channels/urbdrc/client/urbdrc_main.c | 678 ++++++++++++----------- client/common/cmdline.c | 281 ++++++++-- client/common/compatibility.c | 88 ++- client/common/file.c | 18 +- client/iOS/FreeRDP/ios_freerdp.m | 2 + libfreerdp/codec/test/TestFreeRDPCodecPlanar.c | 1 - libfreerdp/common/assistance.c | 200 ++++--- libfreerdp/core/gateway/http.c | 51 +- libfreerdp/core/listener.c | 37 +- libfreerdp/core/proxy.c | 12 +- libfreerdp/crypto/tls.c | 23 +- libfreerdp/locale/keyboard_sun.c | 28 +- rdtk/librdtk/rdtk_font.c | 93 +++- server/Sample/sfreerdp.c | 8 +- server/Windows/cli/wfreerdp.c | 39 +- server/shadow/shadow_server.c | 47 +- winpr/include/winpr/crt.h | 59 +- winpr/libwinpr/clipboard/synthetic.c | 262 ++++----- winpr/libwinpr/registry/registry_reg.c | 72 ++- winpr/libwinpr/smartcard/smartcard_pcsc.c | 29 +- winpr/libwinpr/utils/ini.c | 142 ++--- winpr/libwinpr/utils/test/TestCmdLine.c | 28 +- winpr/tools/hash-cli/hash.c | 17 +- winpr/tools/makecert/makecert.c | 37 +- 30 files changed, 1839 insertions(+), 1401 deletions(-) diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 5ee2fea..4ea1a23 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -24,6 +24,7 @@ #include "config.h" #endif +#include #include #include #include @@ -763,6 +764,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args) return FALSE; arg = audin_args; + errno = 0; do { @@ -788,15 +790,28 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args) } CommandLineSwitchCase(arg, "format") { - audin->fixed_format = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT16_MAX)) + return FALSE; + + audin->fixed_format = val; } CommandLineSwitchCase(arg, "rate") { - audin->fixed_rate = atoi(arg->Value); + long val = strtol(arg->Value, NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return FALSE; + + audin->fixed_rate = val; } CommandLineSwitchCase(arg, "channel") { - audin->fixed_channel = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT16_MAX)) + audin->fixed_channel = val; } CommandLineSwitchDefault(arg) { diff --git a/channels/audin/client/oss/audin_oss.c b/channels/audin/client/oss/audin_oss.c index 9e166b0..5642f60 100644 --- a/channels/audin/client/oss/audin_oss.c +++ b/channels/audin/client/oss/audin_oss.c @@ -471,6 +471,7 @@ static UINT audin_oss_parse_addin_args(AudinOSSDevice* device, ADDIN_ARGV* args) return ERROR_INVALID_PARAMETER; arg = audin_oss_args; + errno = 0; do { @@ -488,7 +489,17 @@ static UINT audin_oss_parse_addin_args(AudinOSSDevice* device, ADDIN_ARGV* args) return CHANNEL_RC_NO_MEMORY; } - oss->dev_unit = strtol(str_num, &eptr, 10); + { + long val = strtol(str_num, &eptr, 10); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + { + free(str_num); + return CHANNEL_RC_NULL_DATA; + } + + oss->dev_unit = val; + } if (oss->dev_unit < 0 || *eptr != '\0') oss->dev_unit = -1; diff --git a/channels/rdpsnd/client/oss/rdpsnd_oss.c b/channels/rdpsnd/client/oss/rdpsnd_oss.c index 5209969..9a9d103 100644 --- a/channels/rdpsnd/client/oss/rdpsnd_oss.c +++ b/channels/rdpsnd/client/oss/rdpsnd_oss.c @@ -82,22 +82,25 @@ static int rdpsnd_oss_get_format(AUDIO_FORMAT* format) switch (format->wFormatTag) { case WAVE_FORMAT_PCM: - switch (format->wBitsPerSample) { case 8: return AFMT_S8; + case 16: return AFMT_S16_LE; } break; + case WAVE_FORMAT_ALAW: return AFMT_A_LAW; #if 0 /* This does not work on my desktop. */ + case WAVE_FORMAT_MULAW: return AFMT_MU_LAW; #endif + case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_DVI_ADPCM: return AFMT_S16_LE; @@ -117,20 +120,19 @@ static BOOL rdpsnd_oss_format_supported(rdpsndDevicePlugin* device, AUDIO_FORMAT switch (format->wFormatTag) { case WAVE_FORMAT_PCM: - if (format->cbSize != 0 || - format->nSamplesPerSec > 48000 || - (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || - (format->nChannels != 1 && format->nChannels != 2)) + format->nSamplesPerSec > 48000 || + (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || + (format->nChannels != 1 && format->nChannels != 2)) return FALSE; break; + case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_DVI_ADPCM: - if (format->nSamplesPerSec > 48000 || - format->wBitsPerSample != 4 || - (format->nChannels != 1 && format->nChannels != 2)) + format->wBitsPerSample != 4 || + (format->nChannels != 1 && format->nChannels != 2)) return FALSE; break; @@ -379,17 +381,19 @@ static BOOL rdpsnd_oss_wave_decode(rdpsndDevicePlugin* device, RDPSND_WAVE* wave { case WAVE_FORMAT_ADPCM: oss->dsp_context->decode_ms_adpcm(oss->dsp_context, - wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); + wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); wave->length = oss->dsp_context->adpcm_size; wave->data = oss->dsp_context->adpcm_buffer; break; + case WAVE_FORMAT_DVI_ADPCM: oss->dsp_context->decode_ima_adpcm(oss->dsp_context, - wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); + wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); wave->length = oss->dsp_context->adpcm_size; wave->data = oss->dsp_context->adpcm_buffer; break; } + return TRUE; } @@ -442,12 +446,14 @@ static int rdpsnd_oss_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* a COMMAND_LINE_ARGUMENT_A* arg; rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; - status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, rdpsnd_oss_args, flags, oss, NULL, NULL); + status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, rdpsnd_oss_args, flags, + oss, NULL, NULL); if (status < 0) return status; arg = rdpsnd_oss_args; + errno = 0; do { @@ -458,10 +464,21 @@ static int rdpsnd_oss_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* a CommandLineSwitchCase(arg, "dev") { str_num = _strdup(arg->Value); + if (!str_num) return ERROR_OUTOFMEMORY; - oss->dev_unit = strtol(str_num, &eptr, 10); + { + long val = strtol(str_num, &eptr, 10); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + { + free(str_num); + return CHANNEL_RC_NULL_DATA; + } + + oss->dev_unit = val; + } if (oss->dev_unit < 0 || *eptr != '\0') oss->dev_unit = -1; @@ -491,8 +508,10 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p ADDIN_ARGV* args; rdpsndOssPlugin* oss; oss = (rdpsndOssPlugin*)calloc(1, sizeof(rdpsndOssPlugin)); + if (!oss) return CHANNEL_RC_NO_MEMORY; + oss->device.Open = rdpsnd_oss_open; oss->device.FormatSupported = rdpsnd_oss_format_supported; oss->device.SetFormat = rdpsnd_oss_set_format; @@ -508,6 +527,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p args = pEntryPoints->args; rdpsnd_oss_parse_addin_args((rdpsndDevicePlugin*)oss, args); oss->dsp_context = freerdp_dsp_context_new(); + if (!oss->dsp_context) { free(oss); @@ -515,6 +535,5 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p } pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)oss); - return CHANNEL_RC_OK; } diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 172128d..fe727ba 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -224,8 +225,8 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) return; rdpsnd->ClientFormats = (AUDIO_FORMAT*) calloc( - rdpsnd->NumberOfServerFormats, - sizeof(AUDIO_FORMAT)); + rdpsnd->NumberOfServerFormats, + sizeof(AUDIO_FORMAT)); if (!rdpsnd->ClientFormats) return; @@ -871,6 +872,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) return CHANNEL_RC_INITIALIZATION_ERROR; arg = rdpsnd_args; + errno = 0; do { @@ -890,23 +892,43 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) } CommandLineSwitchCase(arg, "format") { - rdpsnd->fixedFormat = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT16_MAX)) + return CHANNEL_RC_INITIALIZATION_ERROR; + + rdpsnd->fixedFormat = val; } CommandLineSwitchCase(arg, "rate") { - rdpsnd->fixedRate = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return CHANNEL_RC_INITIALIZATION_ERROR; + + rdpsnd->fixedRate = val; } CommandLineSwitchCase(arg, "channel") { - rdpsnd->fixedChannel = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT16_MAX)) + return CHANNEL_RC_INITIALIZATION_ERROR; + + rdpsnd->fixedChannel = val; } CommandLineSwitchCase(arg, "latency") { - rdpsnd->latency = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return CHANNEL_RC_INITIALIZATION_ERROR; + + rdpsnd->latency = val; } CommandLineSwitchCase(arg, "quality") { - int wQualityMode = DYNAMIC_QUALITY; + long wQualityMode = DYNAMIC_QUALITY; if (_stricmp(arg->Value, "dynamic") == 0) wQualityMode = DYNAMIC_QUALITY; @@ -915,7 +937,12 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) else if (_stricmp(arg->Value, "high") == 0) wQualityMode = HIGH_QUALITY; else - wQualityMode = atoi(arg->Value); + { + wQualityMode = strtol(arg->Value, NULL, 0); + + if (errno != 0) + return CHANNEL_RC_INITIALIZATION_ERROR; + } if ((wQualityMode < 0) || (wQualityMode > 2)) wQualityMode = DYNAMIC_QUALITY; diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c index 55bd543..94e1d04 100644 --- a/channels/urbdrc/client/libusb/libusb_udevice.c +++ b/channels/urbdrc/client/libusb/libusb_udevice.c @@ -26,31 +26,33 @@ #include #endif +#include + #include "libusb_udevice.h" #define BASIC_STATE_FUNC_DEFINED(_arg, _type) \ -static _type udev_get_##_arg (IUDEVICE* idev) \ -{ \ - UDEVICE* pdev = (UDEVICE*) idev; \ - return pdev->_arg; \ -} \ -static void udev_set_##_arg (IUDEVICE* idev, _type _t) \ -{ \ - UDEVICE* pdev = (UDEVICE*) idev; \ - pdev->_arg = _t; \ -} + static _type udev_get_##_arg (IUDEVICE* idev) \ + { \ + UDEVICE* pdev = (UDEVICE*) idev; \ + return pdev->_arg; \ + } \ + static void udev_set_##_arg (IUDEVICE* idev, _type _t) \ + { \ + UDEVICE* pdev = (UDEVICE*) idev; \ + pdev->_arg = _t; \ + } #define BASIC_POINT_FUNC_DEFINED(_arg, _type) \ -static _type udev_get_p_##_arg (IUDEVICE* idev) \ -{ \ - UDEVICE* pdev = (UDEVICE*) idev; \ - return pdev->_arg; \ -} \ -static void udev_set_p_##_arg (IUDEVICE* idev, _type _t) \ -{ \ - UDEVICE* pdev = (UDEVICE*) idev; \ - pdev->_arg = _t; \ -} + static _type udev_get_p_##_arg (IUDEVICE* idev) \ + { \ + UDEVICE* pdev = (UDEVICE*) idev; \ + return pdev->_arg; \ + } \ + static void udev_set_p_##_arg (IUDEVICE* idev, _type _t) \ + { \ + UDEVICE* pdev = (UDEVICE*) idev; \ + pdev->_arg = _t; \ + } #define BASIC_STATE_FUNC_REGISTER(_arg, _dev) \ _dev->iface.get_##_arg = udev_get_##_arg; \ @@ -70,11 +72,10 @@ struct _ISO_USER_DATA UINT32 start_frame; }; -static int get_next_timeout(libusb_context *ctx, struct timeval *tv, struct timeval *out) +static int get_next_timeout(libusb_context* ctx, struct timeval* tv, struct timeval* out) { int r; struct timeval timeout; - r = libusb_get_next_timeout(ctx, &timeout); if (r) @@ -93,39 +94,36 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv, struct time { *out = *tv; } + return 0; } -/* +/* * a simple wrapper to implement libusb_handle_events_timeout_completed * function in libusb library git tree (1.0.9 later) */ -static int handle_events_completed(libusb_context *ctx, int *completed) +static int handle_events_completed(libusb_context* ctx, int* completed) { struct timeval tv; - tv.tv_sec = 60; tv.tv_usec = 0; - #ifdef HAVE_NEW_LIBUSB return libusb_handle_events_timeout_completed(ctx, &tv, completed); #else int r; struct timeval poll_timeout; - r = get_next_timeout(ctx, &tv, &poll_timeout); - retry: + if (libusb_try_lock_events(ctx) == 0) { if (completed == NULL || !*completed) { /* we obtained the event lock: do our own event handling */ - WLog_DBG(TAG,"doing our own event handling"); + WLog_DBG(TAG, "doing our own event handling"); r = libusb_handle_events_locked(ctx, &tv); } libusb_unlock_events(ctx); - return r; } @@ -141,13 +139,12 @@ retry: /* we hit a race: whoever was event handling earlier finished in the * time it took us to reach this point. try the cycle again. */ libusb_unlock_event_waiters(ctx); - WLog_DBG(TAG,"event handler was active but went away, retrying"); + WLog_DBG(TAG, "event handler was active but went away, retrying"); goto retry; } - WLog_DBG(TAG,"another thread is doing event handling"); + WLog_DBG(TAG, "another thread is doing event handling"); r = libusb_wait_for_event(ctx, &poll_timeout); - already_done: libusb_unlock_event_waiters(ctx); @@ -163,10 +160,11 @@ already_done: { return 0; } + #endif /* HAVE_NEW_LIBUSE */ } -static void func_iso_callback(struct libusb_transfer *transfer) +static void func_iso_callback(struct libusb_transfer* transfer) { ISO_USER_DATA* iso_user_data = (ISO_USER_DATA*) transfer->user_data; BYTE* data = iso_user_data->IsoPacket; @@ -175,30 +173,31 @@ static void func_iso_callback(struct libusb_transfer *transfer) UINT32 index = 0; UINT32 i, act_len; BYTE* b; - *completed = 1; - /* Fixme: currently fill the dummy frame number, tt needs to be + + /* Fixme: currently fill the dummy frame number, tt needs to be * filled a real frame number */ // urbdrc_get_mstime(iso_user_data->start_frame); if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && (!iso_user_data->noack)) { - for (i = 0; i < transfer->num_iso_packets; i++) + for (i = 0; i < transfer->num_iso_packets; i++) { act_len = transfer->iso_packet_desc[i].actual_length; data_write_UINT32(data + offset, index); data_write_UINT32(data + offset + 4, act_len); - data_write_UINT32(data + offset + 8, - transfer->iso_packet_desc[i].status); + data_write_UINT32(data + offset + 8, + transfer->iso_packet_desc[i].status); offset += 12; - if (transfer->iso_packet_desc[i].status == USBD_STATUS_SUCCESS) + if (transfer->iso_packet_desc[i].status == USBD_STATUS_SUCCESS) { b = libusb_get_iso_packet_buffer_simple(transfer, i); - if (act_len > 0) + if (act_len > 0) { if (iso_user_data->output_data + index != b) memcpy(iso_user_data->output_data + index, b, act_len); + index += act_len; } else @@ -206,19 +205,20 @@ static void func_iso_callback(struct libusb_transfer *transfer) //WLog_ERR(TAG, "actual length %"PRIu32"", act_len); //exit(EXIT_FAILURE); } - } - else + } + else { iso_user_data->error_count++; //print_transfer_status(transfer->iso_packet_desc[i].status); } } + transfer->actual_length = index; iso_user_data->iso_status = 1; } else if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && (iso_user_data->noack)) { - /* This situation occurs when we do not need to + /* This situation occurs when we do not need to * return any packet */ iso_user_data->iso_status = 1; } @@ -230,14 +230,13 @@ static void func_iso_callback(struct libusb_transfer *transfer) } static const LIBUSB_ENDPOINT_DESCEIPTOR* func_get_ep_desc(LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig, - MSUSB_CONFIG_DESCRIPTOR* MsConfig, UINT32 EndpointAddress) + MSUSB_CONFIG_DESCRIPTOR* MsConfig, UINT32 EndpointAddress) { BYTE alt; int inum, pnum; MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces; const LIBUSB_INTERFACE* interface; const LIBUSB_ENDPOINT_DESCEIPTOR* endpoint; - MsInterfaces = MsConfig->MsInterfaces; interface = LibusbConfig->interface; @@ -245,7 +244,7 @@ static const LIBUSB_ENDPOINT_DESCEIPTOR* func_get_ep_desc(LIBUSB_CONFIG_DESCRIPT { alt = MsInterfaces[inum]->AlternateSetting; endpoint = interface[inum].altsetting[alt].endpoint; - + for (pnum = 0; pnum < MsInterfaces[inum]->NumberOfPipes; pnum++) { if (endpoint[pnum].bEndpointAddress == EndpointAddress) @@ -258,9 +257,9 @@ static const LIBUSB_ENDPOINT_DESCEIPTOR* func_get_ep_desc(LIBUSB_CONFIG_DESCRIPT return NULL; } -static void func_bulk_transfer_cb(struct libusb_transfer *transfer) +static void func_bulk_transfer_cb(struct libusb_transfer* transfer) { - int *completed = transfer->user_data; + int* completed = transfer->user_data; *completed = 1; /* caller interprets results and frees transfer */ } @@ -275,7 +274,7 @@ static int func_set_usbd_status(UDEVICE* pdev, UINT32* status, int err_result) case LIBUSB_ERROR_IO: *status = USBD_STATUS_STALL_PID; - WLog_ERR(TAG,"LIBUSB_ERROR_IO!!"); + WLog_ERR(TAG, "LIBUSB_ERROR_IO!!"); break; case LIBUSB_ERROR_INVALID_PARAM: @@ -288,14 +287,16 @@ static int func_set_usbd_status(UDEVICE* pdev, UINT32* status, int err_result) case LIBUSB_ERROR_NO_DEVICE: *status = USBD_STATUS_DEVICE_GONE; + if (pdev) { if (!(pdev->status & URBDRC_DEVICE_NOT_FOUND)) { pdev->status |= URBDRC_DEVICE_NOT_FOUND; - WLog_WARN(TAG,"LIBUSB_ERROR_NO_DEVICE!!"); + WLog_WARN(TAG, "LIBUSB_ERROR_NO_DEVICE!!"); } } + break; case LIBUSB_ERROR_NOT_FOUND: @@ -343,7 +344,7 @@ static int func_set_usbd_status(UDEVICE* pdev, UINT32* status, int err_result) } static void func_iso_data_init(ISO_USER_DATA* iso_user_data, UINT32 numPacket, UINT32 buffsize, - UINT32 noAck, BYTE* isoPacket, BYTE * buffer) + UINT32 noAck, BYTE* isoPacket, BYTE* buffer) { /* init struct iso_user_data */ iso_user_data->IsoPacket = isoPacket; @@ -354,13 +355,14 @@ static void func_iso_data_init(ISO_USER_DATA* iso_user_data, UINT32 numPacket, U urbdrc_get_mstime(iso_user_data->start_frame); } -static int func_config_release_all_interface(LIBUSB_DEVICE_HANDLE* libusb_handle, UINT32 NumInterfaces) +static int func_config_release_all_interface(LIBUSB_DEVICE_HANDLE* libusb_handle, + UINT32 NumInterfaces) { int i, ret; for (i = 0; i < NumInterfaces; i++) { - ret = libusb_release_interface (libusb_handle, i); + ret = libusb_release_interface(libusb_handle, i); if (ret < 0) { @@ -445,7 +447,7 @@ static void print_status(enum libusb_transfer_status status) case LIBUSB_TRANSFER_NO_DEVICE: WLog_ERR(TAG, "Transfer status: LIBUSB_TRANSFER_NO_DEVICE"); break; - case LIBUSB_TRANSFER_OVERFLOW: + case LIBUSB_TRANSFER_OVERFLOW: WLog_ERR(TAG, "Transfer status: LIBUSB_TRANSFER_OVERFLOW"); break; default: @@ -459,18 +461,16 @@ static LIBUSB_DEVICE* udev_get_libusb_dev(int bus_number, int dev_number) { ssize_t i, total_device; LIBUSB_DEVICE** libusb_list; - - total_device = libusb_get_device_list(NULL, &libusb_list); + total_device = libusb_get_device_list(NULL, &libusb_list); for (i = 0; i < total_device; i++) { if ((bus_number == libusb_get_bus_number(libusb_list[i])) && - (dev_number == libusb_get_device_address(libusb_list[i]))) + (dev_number == libusb_get_device_address(libusb_list[i]))) return libusb_list[i]; } libusb_free_device_list(libusb_list, 1); - return NULL; } @@ -478,9 +478,7 @@ static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(LIBUSB_DEVICE* libusb_dev) { int ret; LIBUSB_DEVICE_DESCRIPTOR* descriptor; - descriptor = (LIBUSB_DEVICE_DESCRIPTOR*) malloc(sizeof(LIBUSB_DEVICE_DESCRIPTOR)); - ret = libusb_get_device_descriptor(libusb_dev, descriptor); if (ret < 0) @@ -489,40 +487,47 @@ static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(LIBUSB_DEVICE* libusb_dev) free(descriptor); return NULL; } - + return descriptor; } /* Get HUB handle */ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) -static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) { +static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) +{ int error; ssize_t i, total_device, ports_cnt; uint8_t port_numbers[16]; - LIBUSB_DEVICE **libusb_list; - + LIBUSB_DEVICE** libusb_list; total_device = libusb_get_device_list(NULL, &libusb_list); /* Look for device. */ error = -1; + for (i = 0; i < total_device; i ++) { if ((bus_number != libusb_get_bus_number(libusb_list[i])) || (dev_number != libusb_get_device_address(libusb_list[i]))) continue; + error = libusb_open(libusb_list[i], &pdev->hub_handle); + if (error < 0) { - WLog_ERR(TAG,"libusb_open error: %i - %s", error, libusb_strerror(error)); + WLog_ERR(TAG, "libusb_open error: %i - %s", error, libusb_strerror(error)); break; } + /* get port number */ error = libusb_get_port_numbers(libusb_list[i], port_numbers, sizeof(port_numbers)); libusb_close(pdev->hub_handle); + if (error < 1) - { /* Prevent open hub, treat as error. */ - WLog_ERR(TAG,"libusb_get_port_numbers error: %i - %s", error, libusb_strerror(error)); + { + /* Prevent open hub, treat as error. */ + WLog_ERR(TAG, "libusb_get_port_numbers error: %i - %s", error, libusb_strerror(error)); break; } + pdev->port_number = port_numbers[(error - 1)]; error = 0; WLog_DBG(TAG, " Port: %d", pdev->port_number); @@ -531,26 +536,33 @@ static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_numb WLog_DBG(TAG, " DevPath: %s", pdev->path); break; } + /* Look for device hub. */ if (error == 0) { error = -1; + for (i = 0; i < total_device; i ++) { if ((bus_number != libusb_get_bus_number(libusb_list[i])) || (1 != libusb_get_device_address(libusb_list[i]))) /* Root hub allways first on bus. */ continue; + WLog_DBG(TAG, " Open hub: %"PRIu16"", bus_number); error = libusb_open(libusb_list[i], &pdev->hub_handle); + if (error < 0) - WLog_ERR(TAG,"libusb_open error: %i - %s", error, libusb_strerror(error)); + WLog_ERR(TAG, "libusb_open error: %i - %s", error, libusb_strerror(error)); + break; } } + libusb_free_device_list(libusb_list, 1); if (error < 0) return -1; + WLog_DBG(TAG, "libusb_open success!"); return 0; } @@ -563,12 +575,11 @@ static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_numb struct udev_list_entry* devices; struct udev_list_entry* dev_list_entry; struct udev_device* dev; - LIBUSB_DEVICE* libusb_dev; + LIBUSB_DEVICE* libusb_dev; int hub_found = 0; - int hub_bus = 0; - int hub_dev = 0; + unsigned long hub_bus = 0; + unsigned long hub_dev = 0; int error = 0; - udev = udev_new(); if (!udev) @@ -582,27 +593,33 @@ static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_numb udev_enumerate_add_match_property(enumerate, "DEVTYPE", "usb_device"); udev_enumerate_scan_devices(enumerate); devices = udev_enumerate_get_list_entry(enumerate); - - udev_list_entry_foreach(dev_list_entry, devices) + udev_list_entry_foreach(dev_list_entry, devices) { - const char * path; - + const char* path; + errno = 0; path = udev_list_entry_get_name(dev_list_entry); dev = udev_device_new_from_syspath(udev, path); if (!dev) continue; - int tmp_b = atoi(udev_device_get_property_value(dev,"BUSNUM")); - int tmp_d = atoi(udev_device_get_property_value(dev,"DEVNUM")); + unsigned long tmp_b, tmp_d; + tmp_b = strtoul(udev_device_get_property_value(dev, "BUSNUM"), NULL, 0); + + if (errno != 0) + continue; + + tmp_d = strtoul(udev_device_get_property_value(dev, "DEVNUM"), NULL, 0); + + if (errno != 0) + continue; if (bus_number == tmp_b && dev_number == tmp_d) { /* get port number */ - char *p1, *p2; + char* p1, *p2; const char* sysfs_path = - udev_device_get_property_value(dev,"DEVPATH"); - + udev_device_get_property_value(dev, "DEVPATH"); p1 = (char*) sysfs_path; do @@ -611,23 +628,29 @@ static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_numb p1 = strchr(p2, '.'); } while (p1 != NULL); - + if ((p2 - sysfs_path) < (strlen(sysfs_path) - 2)) { p1 = (char*) sysfs_path; do { - p2 = p1 + 1; p1 = strchr(p2, '-'); } while (p1 != NULL); } - pdev->port_number = atoi(p2); - WLog_DBG(TAG, " Port: %d", pdev->port_number); + errno = 0; + { + unsigned long val = strtoul(p2, NULL, 0); + + if ((errno != 0) || (val == 0) || (val > UINT16_MAX)) + continue; + pdev->port_number = val; + } + WLog_DBG(TAG, " Port: %d", pdev->port_number); /* get device path */ p1 = (char*) sysfs_path; @@ -640,31 +663,30 @@ static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_numb memset(pdev->path, 0, 17); strcpy(pdev->path, p2); - WLog_DBG(TAG," DevPath: %s", pdev->path); - + WLog_DBG(TAG, " DevPath: %s", pdev->path); /* query parent hub info */ dev = udev_device_get_parent(dev); if (dev != NULL) { hub_found = 1; - hub_bus = atoi(udev_device_get_property_value(dev,"BUSNUM")); - hub_dev = atoi(udev_device_get_property_value(dev,"DEVNUM")); + hub_bus = strtoul(udev_device_get_property_value(dev, "BUSNUM"), NULL, 0); + hub_dev = strtoul(udev_device_get_property_value(dev, "DEVNUM"), NULL, 0); WLog_DBG(TAG, " Hub BUS/DEV: %d %d", hub_bus, hub_dev); } udev_device_unref(dev); break; } + udev_device_unref(dev); } - udev_enumerate_unref(enumerate); udev_unref(udev); if (!hub_found) { - WLog_WARN(TAG,"hub was not found!"); + WLog_WARN(TAG, "hub was not found!"); return -1; } @@ -673,20 +695,19 @@ static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_numb if (libusb_dev == NULL) { - WLog_DBG(TAG,"get hub libusb_dev fail!"); + WLog_DBG(TAG, "get hub libusb_dev fail!"); return -1; } - error = libusb_open (libusb_dev, &pdev->hub_handle); + error = libusb_open(libusb_dev, &pdev->hub_handle); if (error < 0) { - WLog_DBG(TAG,"libusb_open error!"); + WLog_DBG(TAG, "libusb_open error!"); return -1; } - WLog_DBG(TAG,"libusb_open success!"); - + WLog_DBG(TAG, "libusb_open success!"); /* Success! */ return 0; } @@ -698,7 +719,6 @@ static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BY UDEVICE* pdev = (UDEVICE*) idev; MSUSB_CONFIG_DESCRIPTOR* MsConfig; MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces; - MsConfig = pdev->MsConfig; if (MsConfig) @@ -710,23 +730,24 @@ static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BY diff = 0; } } - + if (diff) { error = libusb_set_interface_alt_setting(pdev->libusb_handle, - InterfaceNumber, AlternateSetting); + InterfaceNumber, AlternateSetting); if (error < 0) { WLog_ERR(TAG, "Set interface altsetting get error num %d", - error); - } + error); + } } return error; } -static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsConfig) +static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* idev, + MSUSB_CONFIG_DESCRIPTOR* MsConfig) { UDEVICE* pdev = (UDEVICE*) idev; MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces; @@ -741,17 +762,18 @@ static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* id const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint; BYTE LibusbNumEndpoint; int inum = 0, pnum = 0, MsOutSize = 0; - LibusbConfig = pdev->LibusbConfig; + if (LibusbConfig->bNumInterfaces != MsConfig->NumInterfaces) { WLog_ERR(TAG, "Select Configuration: Libusb NumberInterfaces(%"PRIu8") is different " - "with MsConfig NumberInterfaces(%"PRIu32")", - LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces); + "with MsConfig NumberInterfaces(%"PRIu32")", + LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces); } /* replace MsPipes for libusb */ MsInterfaces = MsConfig->MsInterfaces; + for (inum = 0; inum < MsConfig->NumInterfaces; inum++) { MsInterface = MsInterfaces[inum]; @@ -763,7 +785,7 @@ static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* id for (pnum = 0; pnum < LibusbNumEndpoint; pnum++) { - t_MsPipe = (MSUSB_PIPE_DESCRIPTOR *) malloc (sizeof(MSUSB_PIPE_DESCRIPTOR)); + t_MsPipe = (MSUSB_PIPE_DESCRIPTOR*) malloc(sizeof(MSUSB_PIPE_DESCRIPTOR)); memset(t_MsPipe, 0, sizeof(MSUSB_PIPE_DESCRIPTOR)); if (pnum < MsInterface->NumberOfPipes && MsInterface->MsPipes) @@ -779,18 +801,18 @@ static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* id t_MsPipe->MaximumTransferSize = 0xffffffff; t_MsPipe->PipeFlags = 0; } - + t_MsPipe->PipeHandle = 0; t_MsPipe->bEndpointAddress = 0; t_MsPipe->bInterval = 0; t_MsPipe->PipeType = 0; t_MsPipe->InitCompleted = 0; - t_MsPipes[pnum] = t_MsPipe; } msusb_mspipes_replace(MsInterface, t_MsPipes, LibusbNumEndpoint); } + /* setup configuration */ MsOutSize = 8; /* ConfigurationHandle: 4 bytes @@ -799,37 +821,36 @@ static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* id * || bus_number | dev_number | bConfigurationValue || * --------------------------------------------------------------- * ***********************/ - MsConfig->ConfigurationHandle = MsConfig->bConfigurationValue | - (pdev->bus_number << 24) | - (pdev->dev_number << 16); - + MsConfig->ConfigurationHandle = MsConfig->bConfigurationValue | + (pdev->bus_number << 24) | + (pdev->dev_number << 16); MsInterfaces = MsConfig->MsInterfaces; + for (inum = 0; inum < MsConfig->NumInterfaces; inum++) { MsOutSize += 16; MsInterface = MsInterfaces[inum]; /* get libusb's interface */ LibusbInterface = &LibusbConfig->interface[MsInterface->InterfaceNumber]; - LibusbAltsetting = &LibusbInterface->altsetting[MsInterface->AlternateSetting]; + LibusbAltsetting = &LibusbInterface->altsetting[MsInterface->AlternateSetting]; /* InterfaceHandle: 4 bytes * --------------------------------------------------------------- * ||<<< 1 byte >>>|<<< 1 byte >>>|<<< 1 byte >>>|<<< 1 byte >>>|| * || bus_number | dev_number | altsetting | interfaceNum || * --------------------------------------------------------------- * ***********************/ - MsInterface->InterfaceHandle = LibusbAltsetting->bInterfaceNumber - | (LibusbAltsetting->bAlternateSetting << 8) - | (pdev->dev_number << 16) - | (pdev->bus_number << 24); - + MsInterface->InterfaceHandle = LibusbAltsetting->bInterfaceNumber + | (LibusbAltsetting->bAlternateSetting << 8) + | (pdev->dev_number << 16) + | (pdev->bus_number << 24); MsInterface->Length = 16 + (MsInterface->NumberOfPipes * 20); MsInterface->bInterfaceClass = LibusbAltsetting->bInterfaceClass; MsInterface->bInterfaceSubClass = LibusbAltsetting->bInterfaceSubClass; MsInterface->bInterfaceProtocol = LibusbAltsetting->bInterfaceProtocol; MsInterface->InitCompleted = 1; - MsPipes = MsInterface->MsPipes; LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; + for (pnum = 0; pnum < LibusbNumEndpoint; pnum++) { MsOutSize += 20; @@ -842,16 +863,18 @@ static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* id * || bus_number | dev_number | bEndpointAddress || * --------------------------------------------------------------- * ***********************/ - MsPipe->PipeHandle = LibusbEndpoint->bEndpointAddress - | (pdev->dev_number << 16) - | (pdev->bus_number << 24); + MsPipe->PipeHandle = LibusbEndpoint->bEndpointAddress + | (pdev->dev_number << 16) + | (pdev->bus_number << 24); /* count endpoint max packet size */ int max = LibusbEndpoint->wMaxPacketSize & 0x07ff; BYTE attr = LibusbEndpoint->bmAttributes; + if ((attr & 0x3) == 1 || (attr & 0x3) == 3) { max *= (1 + ((LibusbEndpoint->wMaxPacketSize >> 11) & 3)); } + MsPipe->MaximumPacketSize = max; MsPipe->bEndpointAddress = LibusbEndpoint->bEndpointAddress; MsPipe->bInterval = LibusbEndpoint->bInterval; @@ -859,6 +882,7 @@ static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* id MsPipe->InitCompleted = 1; } } + MsConfig->MsOutSize = MsOutSize; MsConfig->InitCompleted = 1; @@ -875,30 +899,35 @@ static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* id static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfigurationValue) { UDEVICE* pdev = (UDEVICE*) idev; - MSUSB_CONFIG_DESCRIPTOR * MsConfig = pdev->MsConfig; - LIBUSB_DEVICE_HANDLE * libusb_handle = pdev->libusb_handle; - LIBUSB_DEVICE * libusb_dev = pdev->libusb_dev; - LIBUSB_CONFIG_DESCRIPTOR ** LibusbConfig = &pdev->LibusbConfig; + MSUSB_CONFIG_DESCRIPTOR* MsConfig = pdev->MsConfig; + LIBUSB_DEVICE_HANDLE* libusb_handle = pdev->libusb_handle; + LIBUSB_DEVICE* libusb_dev = pdev->libusb_dev; + LIBUSB_CONFIG_DESCRIPTOR** LibusbConfig = &pdev->LibusbConfig; int ret = 0; - if (MsConfig->InitCompleted){ + if (MsConfig->InitCompleted) + { func_config_release_all_interface(libusb_handle, (*LibusbConfig)->bNumInterfaces); } + /* The configuration value -1 is mean to put the device in unconfigured state. */ if (bConfigurationValue == 0) - ret = libusb_set_configuration(libusb_handle, -1); + ret = libusb_set_configuration(libusb_handle, -1); else - ret = libusb_set_configuration(libusb_handle, bConfigurationValue); + ret = libusb_set_configuration(libusb_handle, bConfigurationValue); - if (ret < 0){ + if (ret < 0) + { WLog_ERR(TAG, "libusb_set_configuration: ERROR number %d!!", ret); func_claim_all_interface(libusb_handle, (*LibusbConfig)->bNumInterfaces); return -1; } else { - ret = libusb_get_active_config_descriptor (libusb_dev, LibusbConfig); - if (ret < 0){ + ret = libusb_get_active_config_descriptor(libusb_dev, LibusbConfig); + + if (ret < 0) + { WLog_ERR(TAG, "libusb_get_config_descriptor_by_value: ERROR number %d!!", ret); func_claim_all_interface(libusb_handle, (*LibusbConfig)->bNumInterfaces); return -1; @@ -906,41 +935,41 @@ static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfiguratio } func_claim_all_interface(libusb_handle, (*LibusbConfig)->bNumInterfaces); - return 0; } static int libusb_udev_control_pipe_request(IUDEVICE* idev, UINT32 RequestId, - UINT32 EndpointAddress, UINT32* UsbdStatus, int command) + UINT32 EndpointAddress, UINT32* UsbdStatus, int command) { int error = 0; UDEVICE* pdev = (UDEVICE*) idev; + /* pdev->request_queue->register_request(pdev->request_queue, RequestId, NULL, 0); */ - switch (command){ + switch (command) + { case PIPE_CANCEL: /** cancel bulk or int transfer */ idev->cancel_all_transfer_request(idev); - //dummy_wait_s_obj(1); /** set feature to ep (set halt)*/ - error = libusb_control_transfer(pdev->libusb_handle, - LIBUSB_ENDPOINT_OUT | LIBUSB_RECIPIENT_ENDPOINT, - LIBUSB_REQUEST_SET_FEATURE, - ENDPOINT_HALT, - EndpointAddress, - NULL, - 0, - 1000); + error = libusb_control_transfer(pdev->libusb_handle, + LIBUSB_ENDPOINT_OUT | LIBUSB_RECIPIENT_ENDPOINT, + LIBUSB_REQUEST_SET_FEATURE, + ENDPOINT_HALT, + EndpointAddress, + NULL, + 0, + 1000); break; + case PIPE_RESET: idev->cancel_all_transfer_request(idev); - error = libusb_clear_halt(pdev->libusb_handle, EndpointAddress); - //func_set_usbd_status(pdev, UsbdStatus, error); break; + default: error = -0xff; break; @@ -955,42 +984,46 @@ static int libusb_udev_control_pipe_request(IUDEVICE* idev, UINT32 RequestId, } static int libusb_udev_control_query_device_text(IUDEVICE* idev, UINT32 TextType, - UINT32 LocaleId, - UINT32 * BufferSize, - BYTE * Buffer) + UINT32 LocaleId, + UINT32* BufferSize, + BYTE* Buffer) { UDEVICE* pdev = (UDEVICE*) idev; - LIBUSB_DEVICE_DESCRIPTOR * devDescriptor = pdev->devDescriptor; - char * strDesc = "Generic Usb String"; + LIBUSB_DEVICE_DESCRIPTOR* devDescriptor = pdev->devDescriptor; + char* strDesc = "Generic Usb String"; char deviceLocation[25]; BYTE bus_number; BYTE device_address; int ret = 0, i = 0; - switch (TextType){ + switch (TextType) + { case DeviceTextDescription: - ret = libusb_get_string_descriptor (pdev->libusb_handle, - devDescriptor->iProduct, - LocaleId, - Buffer, - *BufferSize); + ret = libusb_get_string_descriptor(pdev->libusb_handle, + devDescriptor->iProduct, + LocaleId, + Buffer, + *BufferSize); - for(i = 0; i < ret; i++) + for (i = 0; i < ret; i++) { - Buffer[i] = Buffer[i+2]; + Buffer[i] = Buffer[i + 2]; } + ret -= 2; - - if (ret <= 0 || ret < 4){ - WLog_DBG(TAG,"libusb_get_string_descriptor: " - "ERROR num %d, iProduct: %"PRIu8"!", ret, devDescriptor->iProduct); + + if (ret <= 0 || ret < 4) + { + WLog_DBG(TAG, "libusb_get_string_descriptor: " + "ERROR num %d, iProduct: %"PRIu8"!", ret, devDescriptor->iProduct); memcpy(Buffer, strDesc, strlen(strDesc)); Buffer[strlen(strDesc)] = '\0'; - *BufferSize = (strlen((char *)Buffer)) * 2; - for (i = strlen((char *)Buffer); i > 0; i--) + *BufferSize = (strlen((char*)Buffer)) * 2; + + for (i = strlen((char*)Buffer); i > 0; i--) { - Buffer[i*2] = Buffer[i]; - Buffer[(i*2)-1] = 0; + Buffer[i * 2] = Buffer[i]; + Buffer[(i * 2) - 1] = 0; } } else @@ -999,20 +1032,24 @@ static int libusb_udev_control_query_device_text(IUDEVICE* idev, UINT32 TextType } break; + case DeviceTextLocationInformation: bus_number = libusb_get_bus_number(pdev->libusb_dev); device_address = libusb_get_device_address(pdev->libusb_dev); sprintf(deviceLocation, "Port_#%04"PRIu8".Hub_#%04"PRIu8"", device_address, bus_number); - for(i=0;irequest_queue->register_request(pdev->request_queue, RequestId, NULL, 0); */ memset(ms_string_desc, 0, 0x13); - error = libusb_control_transfer(pdev->libusb_handle, - LIBUSB_ENDPOINT_IN | Recipient, - LIBUSB_REQUEST_GET_DESCRIPTOR, - 0x03ee, - 0, - ms_string_desc, - 0x12, - Timeout); + error = libusb_control_transfer(pdev->libusb_handle, + LIBUSB_ENDPOINT_IN | Recipient, + LIBUSB_REQUEST_GET_DESCRIPTOR, + 0x03ee, + 0, + ms_string_desc, + 0x12, + Timeout); + //WLog_ERR(TAG, "Get ms string: result number %d", error); if (error > 0) { @@ -1051,14 +1089,14 @@ static int libusb_udev_os_feature_descriptor_request(IUDEVICE* idev, UINT32 Requ data_read_BYTE(ms_string_desc + 16, bMS_Vendorcode); //WLog_ERR(TAG, "bMS_Vendorcode:0x%x", bMS_Vendorcode); /** get os descriptor */ - error = libusb_control_transfer(pdev->libusb_handle, - LIBUSB_ENDPOINT_IN |LIBUSB_REQUEST_TYPE_VENDOR | Recipient, - bMS_Vendorcode, - (InterfaceNumber << 8) | Ms_PageIndex, - Ms_featureDescIndex, - Buffer, - *BufferSize, - Timeout); + error = libusb_control_transfer(pdev->libusb_handle, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | Recipient, + bMS_Vendorcode, + (InterfaceNumber << 8) | Ms_PageIndex, + Ms_featureDescIndex, + Buffer, + *BufferSize, + Timeout); *BufferSize = error; } @@ -1066,6 +1104,7 @@ static int libusb_udev_os_feature_descriptor_request(IUDEVICE* idev, UINT32 Requ *UsbdStatus = USBD_STATUS_STALL_PID; else *UsbdStatus = USBD_STATUS_SUCCESS; + /* if(pdev->request_queue->unregister_request(pdev->request_queue, RequestId)) WLog_ERR(TAG, "request_queue_unregister_request: not fount request 0x%x", RequestId); @@ -1081,35 +1120,50 @@ static int libusb_udev_query_device_descriptor(IUDEVICE* idev, int offset) { case B_LENGTH: return pdev->devDescriptor->bLength; + case B_DESCRIPTOR_TYPE: return pdev->devDescriptor->bDescriptorType; + case BCD_USB: return pdev->devDescriptor->bcdUSB; + case B_DEVICE_CLASS: return pdev->devDescriptor->bDeviceClass; + case B_DEVICE_SUBCLASS: return pdev->devDescriptor->bDeviceSubClass; + case B_DEVICE_PROTOCOL: return pdev->devDescriptor->bDeviceProtocol; + case B_MAX_PACKET_SIZE0: return pdev->devDescriptor->bMaxPacketSize0; + case ID_VENDOR: return pdev->devDescriptor->idVendor; + case ID_PRODUCT: return pdev->devDescriptor->idProduct; + case BCD_DEVICE: return pdev->devDescriptor->bcdDevice; + case I_MANUFACTURER: return pdev->devDescriptor->iManufacturer; + case I_PRODUCT: return pdev->devDescriptor->iProduct; + case I_SERIAL_NUMBER: return pdev->devDescriptor->iSerialNumber; + case B_NUM_CONFIGURATIONS: return pdev->devDescriptor->bNumConfigurations; + default: return 0; } + return 0; } @@ -1119,17 +1173,19 @@ static void libusb_udev_detach_kernel_driver(IUDEVICE* idev) UDEVICE* pdev = (UDEVICE*) idev; if ((pdev->status & URBDRC_DEVICE_DETACH_KERNEL) == 0) - { + { for (i = 0; i < pdev->LibusbConfig->bNumInterfaces; i++) { - err = libusb_kernel_driver_active(pdev->libusb_handle , i); - WLog_DBG(TAG,"libusb_kernel_driver_active = %d", err); - if (err){ - err = libusb_detach_kernel_driver(pdev->libusb_handle , i); - WLog_DBG(TAG,"libusb_detach_kernel_driver = %d", err); + err = libusb_kernel_driver_active(pdev->libusb_handle, i); + WLog_DBG(TAG, "libusb_kernel_driver_active = %d", err); + + if (err) + { + err = libusb_detach_kernel_driver(pdev->libusb_handle, i); + WLog_DBG(TAG, "libusb_detach_kernel_driver = %d", err); } } - + pdev->status |= URBDRC_DEVICE_DETACH_KERNEL; } } @@ -1141,15 +1197,18 @@ static void libusb_udev_attach_kernel_driver(IUDEVICE* idev) for (i = 0; i < pdev->LibusbConfig->bNumInterfaces && err != LIBUSB_ERROR_NO_DEVICE; i++) { - err = libusb_release_interface (pdev->libusb_handle, i); - if (err < 0){ - WLog_DBG(TAG,"libusb_release_interface: error num %d = %d", i, err); + err = libusb_release_interface(pdev->libusb_handle, i); + + if (err < 0) + { + WLog_DBG(TAG, "libusb_release_interface: error num %d = %d", i, err); } + if (err != LIBUSB_ERROR_NO_DEVICE) { - err = libusb_attach_kernel_driver (pdev->libusb_handle , i); - WLog_DBG(TAG,"libusb_attach_kernel_driver if%d = %d", i, err); - } + err = libusb_attach_kernel_driver(pdev->libusb_handle, i); + WLog_DBG(TAG, "libusb_attach_kernel_driver if%d = %d", i, err); + } } } @@ -1212,10 +1271,9 @@ static int libusb_udev_wait_action_completion(IUDEVICE* idev) int error, sval; UDEVICE* pdev = (UDEVICE*) idev; - while(1) + while (1) { usleep(500000); - error = sem_getvalue(&pdev->sem_id, &sval); if (sval == 0) @@ -1234,7 +1292,7 @@ static void libusb_udev_push_action(IUDEVICE* idev) static void libusb_udev_complete_action(IUDEVICE* idev) { UDEVICE* pdev = (UDEVICE*) idev; - sem_trywait(&pdev->sem_id); + sem_trywait(&pdev->sem_id); } static int libusb_udev_wait_for_detach(IUDEVICE* idev) @@ -1261,7 +1319,7 @@ static int libusb_udev_wait_for_detach(IUDEVICE* idev) static void libusb_udev_lock_fifo_isoch(IUDEVICE* idev) { UDEVICE* pdev = (UDEVICE*) idev; - pthread_mutex_lock(&pdev->mutex_isoch); + pthread_mutex_lock(&pdev->mutex_isoch); } static void libusb_udev_unlock_fifo_isoch(IUDEVICE* idev) @@ -1270,30 +1328,31 @@ static void libusb_udev_unlock_fifo_isoch(IUDEVICE* idev) pthread_mutex_unlock(&pdev->mutex_isoch); } -static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStatus, UINT32* BufferSize, BYTE* Buffer) +static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStatus, + UINT32* BufferSize, BYTE* Buffer) { UDEVICE* pdev = (UDEVICE*) idev; int success = 0, ret; + WLog_DBG(TAG, "..."); - WLog_DBG(TAG,"..."); if (pdev->hub_handle != NULL) { - ret = idev->control_transfer(idev, 0xffff, 0, 0, - LIBUSB_ENDPOINT_IN - | LIBUSB_REQUEST_TYPE_CLASS - | LIBUSB_RECIPIENT_OTHER, - LIBUSB_REQUEST_GET_STATUS, - 0, pdev->port_number, UsbdStatus, BufferSize, Buffer, 1000); + ret = idev->control_transfer(idev, 0xffff, 0, 0, + LIBUSB_ENDPOINT_IN + | LIBUSB_REQUEST_TYPE_CLASS + | LIBUSB_RECIPIENT_OTHER, + LIBUSB_REQUEST_GET_STATUS, + 0, pdev->port_number, UsbdStatus, BufferSize, Buffer, 1000); if (ret < 0) { - WLog_DBG(TAG,"libusb_control_transfer: error num %d", ret); + WLog_DBG(TAG, "libusb_control_transfer: error num %d", ret); *BufferSize = 0; } else { - WLog_DBG(TAG,"PORT STATUS:0x%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"", - Buffer[3], Buffer[2], Buffer[1], Buffer[0]); + WLog_DBG(TAG, "PORT STATUS:0x%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"", + Buffer[3], Buffer[2], Buffer[1], Buffer[0]); success = 1; } } @@ -1312,18 +1371,16 @@ static int libusb_udev_request_queue_is_none(IUDEVICE* idev) } static int libusb_udev_isoch_transfer(IUDEVICE* idev, UINT32 RequestId, UINT32 EndpointAddress, - UINT32 TransferFlags, int NoAck, UINT32* ErrorCount, - UINT32* UrbdStatus, UINT32* StartFrame, UINT32 NumberOfPackets, - BYTE* IsoPacket, UINT32* BufferSize, BYTE* Buffer, int Timeout) + UINT32 TransferFlags, int NoAck, UINT32* ErrorCount, + UINT32* UrbdStatus, UINT32* StartFrame, UINT32 NumberOfPackets, + BYTE* IsoPacket, UINT32* BufferSize, BYTE* Buffer, int Timeout) { UINT32 iso_packet_size; UDEVICE* pdev = (UDEVICE*) idev; ISO_USER_DATA iso_user_data; struct libusb_transfer* iso_transfer = NULL; int status = 0, ret = 0, submit = 0; - iso_packet_size = *BufferSize / NumberOfPackets; - iso_transfer = libusb_alloc_transfer(NumberOfPackets); if (iso_transfer == NULL) @@ -1334,12 +1391,10 @@ static int libusb_udev_isoch_transfer(IUDEVICE* idev, UINT32 RequestId, UINT32 E /** process URB_FUNCTION_IOSCH_TRANSFER */ func_iso_data_init(&iso_user_data, NumberOfPackets, *BufferSize, NoAck, IsoPacket, Buffer); - /** fill setting */ - libusb_fill_iso_transfer(iso_transfer, - pdev->libusb_handle, EndpointAddress, Buffer, *BufferSize, - NumberOfPackets, func_iso_callback, &iso_user_data, 2000); - + libusb_fill_iso_transfer(iso_transfer, + pdev->libusb_handle, EndpointAddress, Buffer, *BufferSize, + NumberOfPackets, func_iso_callback, &iso_user_data, 2000); libusb_set_iso_packet_lengths(iso_transfer, iso_packet_size); if (pdev->status & (URBDRC_DEVICE_SIGNAL_END | URBDRC_DEVICE_NOT_FOUND)) @@ -1353,38 +1408,47 @@ static int libusb_udev_isoch_transfer(IUDEVICE* idev, UINT32 RequestId, UINT32 E if (submit < 0) { - WLog_DBG(TAG,"Error: Failed to submit transfer (ret = %d).", submit); + WLog_DBG(TAG, "Error: Failed to submit transfer (ret = %d).", submit); status = -1; - func_set_usbd_status(pdev, UrbdStatus, ret); + func_set_usbd_status(pdev, UrbdStatus, ret); } } #if ISOCH_FIFO + if (!NoAck) { idev->unlock_fifo_isoch(idev); } + #endif - while(pdev && iso_user_data.iso_status == 0 && status >= 0 && submit >= 0) + while (pdev && iso_user_data.iso_status == 0 && status >= 0 && submit >= 0) { - if (pdev->status & URBDRC_DEVICE_NOT_FOUND){ + if (pdev->status & URBDRC_DEVICE_NOT_FOUND) + { status = -1; break; } + ret = handle_events_completed(NULL, &iso_user_data.completed); - if (ret < 0) { - WLog_DBG(TAG,"Error: libusb_handle_events (ret = %d).", ret); + + if (ret < 0) + { + WLog_DBG(TAG, "Error: libusb_handle_events (ret = %d).", ret); status = -1; break; } + #if WAIT_COMPLETE_SLEEP + if (iso_user_data.iso_status == 0) { usleep(WAIT_COMPLETE_SLEEP); } + #endif - } + } if (iso_user_data.iso_status < 0) status = -1; @@ -1393,30 +1457,28 @@ static int libusb_udev_isoch_transfer(IUDEVICE* idev, UINT32 RequestId, UINT32 E *StartFrame = iso_user_data.start_frame; *BufferSize = iso_transfer->actual_length; libusb_free_transfer(iso_transfer); - return status; } static int libusb_udev_control_transfer(IUDEVICE* idev, UINT32 RequestId, UINT32 EndpointAddress, - UINT32 TransferFlags, BYTE bmRequestType, BYTE Request, UINT16 Value, UINT16 Index, - UINT32* UrbdStatus, UINT32* BufferSize, BYTE* Buffer, UINT32 Timeout) + UINT32 TransferFlags, BYTE bmRequestType, BYTE Request, UINT16 Value, UINT16 Index, + UINT32* UrbdStatus, UINT32* BufferSize, BYTE* Buffer, UINT32 Timeout) { int status = 0; UDEVICE* pdev = (UDEVICE*) idev; - - status = libusb_control_transfer(pdev->libusb_handle, - bmRequestType, Request, Value, Index, Buffer, *BufferSize, Timeout); + status = libusb_control_transfer(pdev->libusb_handle, + bmRequestType, Request, Value, Index, Buffer, *BufferSize, Timeout); if (!(status < 0)) *BufferSize = status; - func_set_usbd_status(pdev, UrbdStatus, status); - + func_set_usbd_status(pdev, UrbdStatus, status); return status; } static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, UINT32 RequestId, - UINT32 EndpointAddress, UINT32 TransferFlags, UINT32* UsbdStatus, UINT32* BufferSize, BYTE* Buffer, UINT32 Timeout) + UINT32 EndpointAddress, UINT32 TransferFlags, UINT32* UsbdStatus, UINT32* BufferSize, BYTE* Buffer, + UINT32 Timeout) { UINT32 transfer_type; UDEVICE* pdev = (UDEVICE*) idev; @@ -1425,10 +1487,8 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, UINT32 Request TRANSFER_REQUEST* request = NULL; int completed = 0, status = 0, submit = 0; int transferDir = EndpointAddress & 0x80; - /* alloc memory for urb transfer */ - transfer = libusb_alloc_transfer(0); - + transfer = libusb_alloc_transfer(0); ep_desc = func_get_ep_desc(pdev->LibusbConfig, pdev->MsConfig, EndpointAddress); if (!ep_desc) @@ -1436,11 +1496,11 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, UINT32 Request WLog_ERR(TAG, "func_get_ep_desc: endpoint 0x%"PRIx32" is not found!!", EndpointAddress); return -1; } - transfer_type = (ep_desc->bmAttributes) & 0x3; - WLog_DBG(TAG,"urb_bulk_or_interrupt_transfer: ep:0x%"PRIx32" " - "transfer_type %"PRIu32" flag:%"PRIu32" OutputBufferSize:0x%"PRIx32"", - EndpointAddress, transfer_type, TransferFlags, *BufferSize); + transfer_type = (ep_desc->bmAttributes) & 0x3; + WLog_DBG(TAG, "urb_bulk_or_interrupt_transfer: ep:0x%"PRIx32" " + "transfer_type %"PRIu32" flag:%"PRIu32" OutputBufferSize:0x%"PRIx32"", + EndpointAddress, transfer_type, TransferFlags, *BufferSize); switch (transfer_type) { @@ -1450,52 +1510,53 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, UINT32 Request break; case INTERRUPT_TRANSFER: + /** Interrupt Transfer */ - /** Sometime, we may have receive a oversized transfer request, - * it make submit urb return error, so we set the length of - * request to wMaxPacketSize */ + /** Sometime, we may have receive a oversized transfer request, + * it make submit urb return error, so we set the length of + * request to wMaxPacketSize */ if (*BufferSize != (ep_desc->wMaxPacketSize)) { - WLog_DBG(TAG,"Interrupt Transfer(%s): " - "BufferSize is different than maxPacketsize(0x%x)", - ((transferDir)?"IN":"OUT"), ep_desc->wMaxPacketSize); - if((*BufferSize) > (ep_desc->wMaxPacketSize) && - transferDir == USBD_TRANSFER_DIRECTION_IN) + WLog_DBG(TAG, "Interrupt Transfer(%s): " + "BufferSize is different than maxPacketsize(0x%x)", + ((transferDir) ? "IN" : "OUT"), ep_desc->wMaxPacketSize); + + if ((*BufferSize) > (ep_desc->wMaxPacketSize) && + transferDir == USBD_TRANSFER_DIRECTION_IN) (*BufferSize) = ep_desc->wMaxPacketSize; } + Timeout = 0; break; default: - WLog_DBG(TAG,"urb_bulk_or_interrupt_transfer:" + WLog_DBG(TAG, "urb_bulk_or_interrupt_transfer:" " other transfer type 0x%"PRIX32"", transfer_type); return -1; break; } libusb_fill_bulk_transfer(transfer, pdev->libusb_handle, EndpointAddress, - Buffer, *BufferSize, func_bulk_transfer_cb, &completed, Timeout); - + Buffer, *BufferSize, func_bulk_transfer_cb, &completed, Timeout); transfer->type = (unsigned char) transfer_type; - /** Bug fixed in libusb-1.0-8 later: issue of memory crash */ submit = libusb_submit_transfer(transfer); if (submit < 0) { - WLog_DBG(TAG,"libusb_bulk_transfer: error num %d", status); + WLog_DBG(TAG, "libusb_bulk_transfer: error num %d", status); func_set_usbd_status(pdev, UsbdStatus, status); *BufferSize = 0; } else { request = pdev->request_queue->register_request( - pdev->request_queue, RequestId, transfer, EndpointAddress); - request->submit = 1; + pdev->request_queue, RequestId, transfer, EndpointAddress); + request->submit = 1; } if ((pdev && *UsbdStatus == 0) && (submit >= 0) && - (pdev->iface.isSigToEnd((IUDEVICE*) pdev) == 0)) + (pdev->iface.isSigToEnd((IUDEVICE*) pdev) == 0)) { while (!completed) { @@ -1512,16 +1573,23 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, UINT32 Request { if (handle_events_completed(NULL, &completed) < 0) break; + #if WAIT_COMPLETE_SLEEP + if (!completed) usleep(WAIT_COMPLETE_SLEEP); + #endif } + break; } + #if WAIT_COMPLETE_SLEEP + if (!completed) usleep(WAIT_COMPLETE_SLEEP); + #endif } @@ -1551,19 +1619,19 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, UINT32 Request func_set_usbd_status(pdev, UsbdStatus, LIBUSB_ERROR_OTHER); break; } - + *BufferSize = transfer->actual_length; } - WLog_DBG(TAG,"bulk or interrupt Transfer data size : 0x%"PRIx32"", *BufferSize); + + WLog_DBG(TAG, "bulk or interrupt Transfer data size : 0x%"PRIx32"", *BufferSize); if (request) { - if(pdev->request_queue->unregister_request(pdev->request_queue, RequestId)) + if (pdev->request_queue->unregister_request(pdev->request_queue, RequestId)) WLog_ERR(TAG, "request_queue_unregister_request: not fount request 0x%"PRIx32"", RequestId); } libusb_free_transfer(transfer); - return 0; } @@ -1573,18 +1641,16 @@ static void libusb_udev_cancel_all_transfer_request(IUDEVICE* idev) UDEVICE* pdev = (UDEVICE*) idev; REQUEST_QUEUE* request_queue = pdev->request_queue; TRANSFER_REQUEST* request = NULL; - pthread_mutex_lock(&request_queue->request_loading); - request_queue->rewind(request_queue); while (request_queue->has_next(request_queue)) { request = request_queue->get_next(request_queue); - + if ((!request) || (!request->transfer) || - (request->endpoint != request->transfer->endpoint) || - (request->transfer->endpoint == 0) || (request->submit != 1)) + (request->endpoint != request->transfer->endpoint) || + (request->transfer->endpoint == 0) || (request->submit != 1)) { continue; } @@ -1593,19 +1659,18 @@ static void libusb_udev_cancel_all_transfer_request(IUDEVICE* idev) if (status < 0) { - WLog_DBG(TAG,"libusb_cancel_transfer: error num %d!!", status); + WLog_DBG(TAG, "libusb_cancel_transfer: error num %d!!", status); } else { request->submit = -1; } - } pthread_mutex_unlock(&request_queue->request_loading); } -static int func_cancel_xact_request(TRANSFER_REQUEST *request) +static int func_cancel_xact_request(TRANSFER_REQUEST* request) { int status; @@ -1613,7 +1678,7 @@ static int func_cancel_xact_request(TRANSFER_REQUEST *request) return -1; if ((!request->transfer) || (request->endpoint != request->transfer->endpoint) || - (request->transfer->endpoint == 0) || (request->submit != 1)) + (request->transfer->endpoint == 0) || (request->submit != 1)) { return 0; } @@ -1622,14 +1687,14 @@ static int func_cancel_xact_request(TRANSFER_REQUEST *request) if (status < 0) { - WLog_DBG(TAG,"libusb_cancel_transfer: error num %d!!", status); + WLog_DBG(TAG, "libusb_cancel_transfer: error num %d!!", status); if (status == LIBUSB_ERROR_NOT_FOUND) - return -1; + return -1; } else { - WLog_DBG(TAG,"libusb_cancel_transfer: Success num:0x%x!!", request->RequestId); + WLog_DBG(TAG, "libusb_cancel_transfer: Success num:0x%x!!", request->RequestId); request->submit = -1; return 1; } @@ -1643,20 +1708,19 @@ static int libusb_udev_cancel_transfer_request(IUDEVICE* idev, UINT32 RequestId) REQUEST_QUEUE* request_queue = pdev->request_queue; TRANSFER_REQUEST* request = NULL; int status = 0, retry_times = 0; - cancel_retry: pthread_mutex_lock(&request_queue->request_loading); - request_queue->rewind(request_queue); while (request_queue->has_next(request_queue)) { request = request_queue->get_next(request_queue); + if (!request) continue; - WLog_DBG(TAG,"CancelId:0x%"PRIx32" RequestId:0x%x endpoint 0x%x!!", - RequestId, request->RequestId, request->endpoint); + WLog_DBG(TAG, "CancelId:0x%"PRIx32" RequestId:0x%x endpoint 0x%x!!", + RequestId, request->RequestId, request->endpoint); if (request->RequestId == (RequestId && retry_times <= 10)) { @@ -1676,17 +1740,17 @@ cancel_retry: { retry_times++; usleep(100000); - WLog_DBG(TAG,"urbdrc_process_cancel_request: go retry!!"); + WLog_DBG(TAG, "urbdrc_process_cancel_request: go retry!!"); goto cancel_retry; } else if ((status < 0) || (retry_times >= 10)) { /** END */ - WLog_DBG(TAG,"urbdrc_process_cancel_request: error go exit!!"); + WLog_DBG(TAG, "urbdrc_process_cancel_request: error go exit!!"); return -1; } - WLog_DBG(TAG,"urbdrc_process_cancel_request: success!!"); + WLog_DBG(TAG, "urbdrc_process_cancel_request: success!!"); return 0; } @@ -1696,17 +1760,16 @@ BASIC_STATE_FUNC_DEFINED(ReqCompletion, UINT32) BASIC_STATE_FUNC_DEFINED(bus_number, UINT16) BASIC_STATE_FUNC_DEFINED(dev_number, UINT16) BASIC_STATE_FUNC_DEFINED(port_number, int) -BASIC_STATE_FUNC_DEFINED(isoch_queue, void *) -BASIC_STATE_FUNC_DEFINED(MsConfig, MSUSB_CONFIG_DESCRIPTOR *) +BASIC_STATE_FUNC_DEFINED(isoch_queue, void*) +BASIC_STATE_FUNC_DEFINED(MsConfig, MSUSB_CONFIG_DESCRIPTOR*) -BASIC_POINT_FUNC_DEFINED(udev, void *) -BASIC_POINT_FUNC_DEFINED(prev, void *) -BASIC_POINT_FUNC_DEFINED(next, void *) +BASIC_POINT_FUNC_DEFINED(udev, void*) +BASIC_POINT_FUNC_DEFINED(prev, void*) +BASIC_POINT_FUNC_DEFINED(next, void*) static void udev_load_interface(UDEVICE* pdev) { /* load interface */ - /* Basic */ BASIC_STATE_FUNC_REGISTER(channel_id, pdev); BASIC_STATE_FUNC_REGISTER(UsbDevice, pdev); @@ -1716,11 +1779,9 @@ static void udev_load_interface(UDEVICE* pdev) BASIC_STATE_FUNC_REGISTER(port_number, pdev); BASIC_STATE_FUNC_REGISTER(isoch_queue, pdev); BASIC_STATE_FUNC_REGISTER(MsConfig, pdev); - BASIC_STATE_FUNC_REGISTER(p_udev, pdev); BASIC_STATE_FUNC_REGISTER(p_prev, pdev); BASIC_STATE_FUNC_REGISTER(p_next, pdev); - pdev->iface.isCompositeDevice = libusb_udev_is_composite_device; pdev->iface.isSigToEnd = libusb_udev_is_signal_end; pdev->iface.isExist = libusb_udev_is_exist; @@ -1730,12 +1791,10 @@ static void udev_load_interface(UDEVICE* pdev) pdev->iface.setAlreadySend = libusb_udev_set_already_send; pdev->iface.setChannelClosed = libusb_udev_channel_closed; pdev->iface.getPath = libusb_udev_get_path; - /* Transfer */ pdev->iface.isoch_transfer = libusb_udev_isoch_transfer; pdev->iface.control_transfer = libusb_udev_control_transfer; pdev->iface.bulk_or_interrupt_transfer = libusb_udev_bulk_or_interrupt_transfer; - pdev->iface.select_interface = libusb_udev_select_interface; pdev->iface.select_configuration = libusb_udev_select_configuration; pdev->iface.complete_msconfig_setup = libusb_udev_complete_msconfig_setup; @@ -1763,7 +1822,6 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) LIBUSB_DEVICE_DESCRIPTOR* devDescriptor; LIBUSB_CONFIG_DESCRIPTOR* config_temp; LIBUSB_INTERFACE_DESCRIPTOR interface_temp; - /* Get HUB handle */ status = udev_get_hub_handle(pdev, bus_number, dev_number); @@ -1783,8 +1841,7 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) } num = pdev->devDescriptor->bNumConfigurations; - - status = libusb_get_active_config_descriptor (pdev->libusb_dev, &pdev->LibusbConfig); + status = libusb_get_active_config_descriptor(pdev->libusb_dev, &pdev->LibusbConfig); if (status < 0) { @@ -1796,30 +1853,32 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) config_temp = pdev->LibusbConfig; /* get the first interface and first altsetting */ interface_temp = config_temp->interface[0].altsetting[0]; - - WLog_DBG(TAG,"Registered Device: Vid: 0x%04"PRIX16" Pid: 0x%04"PRIX16"" - " InterfaceClass = 0x%02"PRIX8"", - pdev->devDescriptor->idVendor, - pdev->devDescriptor->idProduct, - interface_temp.bInterfaceClass); + WLog_DBG(TAG, "Registered Device: Vid: 0x%04"PRIX16" Pid: 0x%04"PRIX16"" + " InterfaceClass = 0x%02"PRIX8"", + pdev->devDescriptor->idVendor, + pdev->devDescriptor->idProduct, + interface_temp.bInterfaceClass); /* Denied list */ - switch(interface_temp.bInterfaceClass) + switch (interface_temp.bInterfaceClass) { case CLASS_RESERVE: + //case CLASS_COMMUNICATION_IF: //case CLASS_HID: //case CLASS_PHYSICAL: case CLASS_MASS_STORAGE: case CLASS_HUB: + //case CLASS_COMMUNICATION_DATA_IF: case CLASS_SMART_CARD: case CLASS_CONTENT_SECURITY: - //case CLASS_WIRELESS_CONTROLLER: - //case CLASS_ELSE_DEVICE: + //case CLASS_WIRELESS_CONTROLLER: + //case CLASS_ELSE_DEVICE: WLog_ERR(TAG, " Device is not supported!!"); zfree(pdev); return NULL; + default: break; } @@ -1828,14 +1887,14 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) devDescriptor = pdev->devDescriptor; if ((devDescriptor->bNumConfigurations == 1) && - (config_temp->bNumInterfaces > 1) && - (devDescriptor->bDeviceClass == 0x0)) + (config_temp->bNumInterfaces > 1) && + (devDescriptor->bDeviceClass == 0x0)) { pdev->isCompositeDevice = 1; } else if ((devDescriptor->bDeviceClass == 0xef) && - (devDescriptor->bDeviceSubClass == 0x02) && - (devDescriptor->bDeviceProtocol == 0x01)) + (devDescriptor->bDeviceSubClass == 0x02) && + (devDescriptor->bDeviceProtocol == 0x01)) { pdev->isCompositeDevice = 1; } @@ -1844,11 +1903,10 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) pdev->isCompositeDevice = 0; } - /* set device class to first interface class */ + /* set device class to first interface class */ devDescriptor->bDeviceClass = interface_temp.bInterfaceClass; devDescriptor->bDeviceSubClass = interface_temp.bInterfaceSubClass; devDescriptor->bDeviceProtocol = interface_temp.bInterfaceProtocol; - /* initialize pdev */ pdev->prev = NULL; pdev->next = NULL; @@ -1860,20 +1918,15 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) pdev->request_queue = request_queue_new(); pdev->isoch_queue = NULL; sem_init(&pdev->sem_id, 0, 0); - /* set config of windows */ pdev->MsConfig = msusb_msconfig_new(); - pthread_mutex_init(&pdev->mutex_isoch, NULL); - - //deb_config_msg(pdev->libusb_dev, config_temp, devDescriptor->bNumConfigurations); - + //deb_config_msg(pdev->libusb_dev, config_temp, devDescriptor->bNumConfigurations); udev_load_interface(pdev); - return (IUDEVICE*) pdev; } -int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray) +int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE** * devArray) { LIBUSB_DEVICE_DESCRIPTOR* descriptor; LIBUSB_DEVICE** libusb_list; @@ -1882,12 +1935,9 @@ int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray) UINT16 dev_number; ssize_t i, total_device; int status, num = 0; - WLog_INFO(TAG, "VID: 0x%04"PRIX16", PID: 0x%04"PRIX16"", idVendor, idProduct); - array = (UDEVICE**) malloc(16 * sizeof(UDEVICE*)); - - total_device = libusb_get_device_list(NULL, &libusb_list); + total_device = libusb_get_device_list(NULL, &libusb_list); for (i = 0; i < total_device; i++) { @@ -1899,7 +1949,6 @@ int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray) dev_number = 0; array[num] = (PUDEVICE) malloc(sizeof(UDEVICE)); array[num]->libusb_dev = libusb_list[i]; - status = libusb_open(libusb_list[i], &array[num]->libusb_handle); if (status < 0) @@ -1912,19 +1961,17 @@ int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray) bus_number = libusb_get_bus_number(libusb_list[i]); dev_number = libusb_get_device_address(libusb_list[i]); - array[num] = (PUDEVICE) udev_init(array[num], bus_number, dev_number); if (array[num] != NULL) num++; } + zfree(descriptor); } libusb_free_device_list(libusb_list, 1); - *devArray = (IUDEVICE**) array; - return num; } @@ -1932,11 +1979,8 @@ IUDEVICE* udev_new_by_addr(int bus_number, int dev_number) { int status; UDEVICE* pDev; - - WLog_DBG(TAG,"bus:%d dev:%d", bus_number, dev_number); - + WLog_DBG(TAG, "bus:%d dev:%d", bus_number, dev_number); pDev = (PUDEVICE) malloc(sizeof(UDEVICE)); - pDev->libusb_dev = udev_get_libusb_dev(bus_number, dev_number); if (pDev->libusb_dev == NULL) diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index 311c278..2d15fed 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -35,16 +35,16 @@ int libusb_debug; #define BASIC_STATE_FUNC_DEFINED(_arg, _type) \ -static _type udevman_get_##_arg (IUDEVMAN* idevman) \ -{ \ - UDEVMAN * udevman = (UDEVMAN *) idevman; \ - return udevman->_arg; \ -} \ -static void udevman_set_##_arg (IUDEVMAN* idevman, _type _t) \ -{ \ - UDEVMAN * udevman = (UDEVMAN *) idevman; \ - udevman->_arg = _t; \ -} + static _type udevman_get_##_arg (IUDEVMAN* idevman) \ + { \ + UDEVMAN * udevman = (UDEVMAN *) idevman; \ + return udevman->_arg; \ + } \ + static void udevman_set_##_arg (IUDEVMAN* idevman, _type _t) \ + { \ + UDEVMAN * udevman = (UDEVMAN *) idevman; \ + udevman->_arg = _t; \ + } #define BASIC_STATE_FUNC_REGISTER(_arg, _man) \ _man->iface.get_##_arg = udevman_get_##_arg; \ @@ -90,17 +90,14 @@ static IUDEVICE* udevman_get_next(IUDEVMAN* idevman) { UDEVMAN* udevman = (UDEVMAN*) idevman; IUDEVICE* pdev; - pdev = udevman->idev; - udevman->idev = (IUDEVICE*) ((UDEVICE*) udevman->idev)->next; - + udevman->idev = (IUDEVICE*)((UDEVICE*) udevman->idev)->next; return pdev; } static IUDEVICE* udevman_get_udevice_by_addr(IUDEVMAN* idevman, int bus_number, int dev_number) { IUDEVICE* pdev; - idevman->loading_lock(idevman); idevman->rewind(idevman); @@ -117,23 +114,22 @@ static IUDEVICE* udevman_get_udevice_by_addr(IUDEVMAN* idevman, int bus_number, idevman->loading_unlock(idevman); WLog_WARN(TAG, "bus:%d dev:%d not exist in udevman", - bus_number, dev_number); + bus_number, dev_number); return NULL; } static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_number, - int UsbDevice, UINT16 idVendor, UINT16 idProduct, int flag) + int UsbDevice, UINT16 idVendor, UINT16 idProduct, int flag) { UDEVMAN* udevman = (UDEVMAN*) idevman; IUDEVICE* pdev = NULL; IUDEVICE** devArray; int i, num, addnum = 0; - pdev = (IUDEVICE*) udevman_get_udevice_by_addr(idevman, bus_number, dev_number); if (pdev != NULL) return 0; - + if (flag == UDEVMAN_FLAG_ADD_BY_ADDR) { pdev = udev_new_by_addr(bus_number, dev_number); @@ -171,8 +167,8 @@ static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_n { pdev = devArray[i]; - if (udevman_get_udevice_by_addr(idevman, - pdev->get_bus_number(pdev), pdev->get_dev_number(pdev)) != NULL) + if (udevman_get_udevice_by_addr(idevman, + pdev->get_bus_number(pdev), pdev->get_dev_number(pdev)) != NULL) { zfree(pdev); continue; @@ -215,11 +211,9 @@ static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_n static int udevman_unregister_udevice(IUDEVMAN* idevman, int bus_number, int dev_number) { UDEVMAN* udevman = (UDEVMAN*) idevman; - UDEVICE * pdev, * dev; + UDEVICE* pdev, * dev; int ret = 0, err = 0; - dev = (UDEVICE*) udevman_get_udevice_by_addr(idevman, bus_number, dev_number); - idevman->loading_lock(idevman); idevman->rewind(idevman); @@ -230,7 +224,6 @@ static int udevman_unregister_udevice(IUDEVMAN* idevman, int bus_number, int dev if (pdev == dev) /* device exists */ { /* set previous device to point to next device */ - if (dev->prev != NULL) { /* unregistered device is not the head */ @@ -248,7 +241,7 @@ static int udevman_unregister_udevice(IUDEVMAN* idevman, int bus_number, int dev if (dev->next != NULL) { /* unregistered device is not the tail */ - pdev = (UDEVICE *)dev->next; + pdev = (UDEVICE*)dev->next; pdev->prev = dev->prev; } else @@ -256,11 +249,12 @@ static int udevman_unregister_udevice(IUDEVMAN* idevman, int bus_number, int dev /* unregistered device is the tail, update tail */ udevman->tail = (IUDEVICE*)dev->prev; } + udevman->device_num--; - - break; + break; } } + idevman->loading_unlock(idevman); if (dev) @@ -269,28 +263,31 @@ static int udevman_unregister_udevice(IUDEVMAN* idevman, int bus_number, int dev if (err != LIBUSB_ERROR_NO_DEVICE) { ret = libusb_reset_device(dev->libusb_handle); - if (ret<0) + + if (ret < 0) { WLog_ERR(TAG, "libusb_reset_device: ERROR!!ret:%d", ret); } } - + /* release all interface and attach kernel driver */ - dev->iface.attach_kernel_driver((IUDEVICE*)dev); - - if(dev->request_queue) zfree(dev->request_queue); + dev->iface.attach_kernel_driver((IUDEVICE*)dev); + + if (dev->request_queue) zfree(dev->request_queue); + /* free the config descriptor that send from windows */ msusb_msconfig_free(dev->MsConfig); - - libusb_close (dev->libusb_handle); - libusb_close (dev->hub_handle); - + libusb_close(dev->libusb_handle); + libusb_close(dev->hub_handle); sem_destroy(&dev->sem_id); + /* free device info */ if (dev->devDescriptor) zfree(dev->devDescriptor); + if (dev) - zfree(dev); + zfree(dev); + return 1; /* unregistration successful */ } @@ -302,28 +299,22 @@ static void udevman_parse_device_addr(char* str, int* id1, int* id2, char sign) { char s1[8]; char* s2; - ZeroMemory(s1, sizeof(s1)); - - s2 = (strchr(str, sign)) + 1; + s2 = (strchr(str, sign)) + 1; strncpy(s1, str, strlen(str) - (strlen(s2) + 1)); - - *id1 = atoi(s1); - *id2 = atoi(s2); + *id1 = strtol(s1, NULL, 0); + *id2 = strtol(s2, NULL, 0); } static void udevman_parse_device_pid_vid(char* str, int* id1, int* id2, char sign) { char s1[8]; char* s2; - ZeroMemory(s1, sizeof(s1)); - - s2 = (strchr(str, sign)) + 1; + s2 = (strchr(str, sign)) + 1; strncpy(s1, str, strlen(str) - (strlen(s2) + 1)); - - *id1 = (int) strtol(s1, NULL, 16); - *id2 = (int) strtol(s2, NULL, 16); + *id1 = strtol(s1, NULL, 16); + *id2 = strtol(s2, NULL, 16); } static int udevman_check_device_exist_by_id(IUDEVMAN* idevman, UINT16 idVendor, UINT16 idProduct) @@ -358,7 +349,6 @@ static IUDEVICE* udevman_get_udevice_by_UsbDevice_try_again(IUDEVMAN* idevman, U } idevman->loading_unlock(idevman); - return NULL; } @@ -380,9 +370,7 @@ static IUDEVICE* udevman_get_udevice_by_UsbDevice(IUDEVMAN* idevman, UINT32 UsbD } idevman->loading_unlock(idevman); - /* try again */ - pdev = (UDEVICE*) idevman->get_udevice_by_UsbDevice_try_again(idevman, UsbDevice); if (pdev) @@ -425,10 +413,8 @@ BASIC_STATE_FUNC_DEFINED(sem_timeout, int) static void udevman_free(IUDEVMAN* idevman) { UDEVMAN* udevman = (UDEVMAN*) idevman; - pthread_mutex_destroy(&udevman->devman_loading); sem_destroy(&udevman->sem_urb_lock); - libusb_exit(NULL); /* free udevman */ @@ -437,11 +423,10 @@ static void udevman_free(IUDEVMAN* idevman) zfree(udevman); } -static void udevman_load_interface(UDEVMAN * udevman) +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; @@ -449,18 +434,15 @@ static void udevman_load_interface(UDEVMAN * udevman) 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; - udevman->iface.get_udevice_by_UsbDevice_try_again = - udevman_get_udevice_by_UsbDevice_try_again; - + udevman->iface.get_udevice_by_UsbDevice_try_again = + udevman_get_udevice_by_UsbDevice_try_again; /* Extension */ udevman->iface.check_device_exist_by_id = udevman_check_device_exist_by_id; 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); - /* control semaphore or mutex lock */ udevman->iface.loading_lock = udevman_loading_lock; udevman->iface.loading_unlock = udevman_loading_unlock; @@ -502,7 +484,6 @@ static void urbdrc_udevman_register_devices(UDEVMAN* udevman, char* devices) dev_number = 0; idVendor = 0; idProduct = 0; - strcpy(hardware_id, token); token = strtok(NULL, "#"); @@ -510,14 +491,13 @@ static void urbdrc_udevman_register_devices(UDEVMAN* udevman, char* devices) { udevman_parse_device_pid_vid(hardware_id, &idVendor, &idProduct, ':'); success = udevman->iface.register_udevice((IUDEVMAN*) udevman, - 0, 0, UsbDevice, (UINT16) idVendor, (UINT16) idProduct, UDEVMAN_FLAG_ADD_BY_VID_PID); + 0, 0, UsbDevice, (UINT16) idVendor, (UINT16) idProduct, UDEVMAN_FLAG_ADD_BY_VID_PID); } else if (udevman->flags & UDEVMAN_FLAG_ADD_BY_ADDR) { udevman_parse_device_addr(hardware_id, &bus_number, &dev_number, ':'); - success = udevman->iface.register_udevice((IUDEVMAN*) udevman, - bus_number, dev_number, UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR); + bus_number, dev_number, UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR); } if (success) @@ -532,12 +512,9 @@ static void urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args) int status; DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; - flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; - status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, - urbdrc_udevman_args, flags, udevman, NULL, NULL); - + urbdrc_udevman_args, flags, udevman, NULL, NULL); arg = urbdrc_udevman_args; do @@ -546,7 +523,6 @@ static void urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args) continue; CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "dbg") { WLog_SetLogLevel(WLog_Get(TAG), WLOG_TRACE); @@ -569,9 +545,7 @@ static void urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args) } CommandLineSwitchDefault(arg) { - } - CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); @@ -587,34 +561,26 @@ int freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS p { UDEVMAN* udevman; ADDIN_ARGV* args = pEntryPoints->args; - libusb_init(NULL); - udevman = (PUDEVMAN) malloc(sizeof(UDEVMAN)); + if (!udevman) return -1; + udevman->device_num = 0; udevman->idev = NULL; udevman->head = NULL; - udevman->tail = NULL; + udevman->tail = NULL; udevman->sem_timeout = 0; udevman->flags = UDEVMAN_FLAG_ADD_BY_VID_PID; - pthread_mutex_init(&udevman->devman_loading, NULL); sem_init(&udevman->sem_urb_lock, 0, MAX_URB_REQUSET_NUM); - /* load usb device service management */ udevman_load_interface(udevman); - /* set debug flag, to enable Debug message for usb data transfer */ - libusb_debug = 10; - urbdrc_udevman_parse_addin_args(udevman, args); - pEntryPoints->pRegisterUDEVMAN(pEntryPoints->plugin, (IUDEVMAN*) udevman); - WLog_DBG(TAG, "UDEVMAN device registered."); - return 0; } diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index 23f7f2c..04aee67 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -24,6 +24,8 @@ #include #include #include +#include + #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) #include #include @@ -52,46 +54,42 @@ static int func_hardware_id_format(IUDEVICE* pdev, char(*HardwareIds)[DEVICE_HARDWARE_ID_SIZE]) { char str[DEVICE_HARDWARE_ID_SIZE]; - UINT16 idVendor, idProduct, bcdDevice; - + UINT16 idVendor, idProduct, bcdDevice; idVendor = (UINT16)pdev->query_device_descriptor(pdev, ID_VENDOR); idProduct = (UINT16)pdev->query_device_descriptor(pdev, ID_PRODUCT); bcdDevice = (UINT16)pdev->query_device_descriptor(pdev, BCD_DEVICE); - sprintf_s(str, sizeof(str), "USB\\VID_%04"PRIX16"&PID_%04"PRIX16"", idVendor, idProduct); - strcpy(HardwareIds[1], str); - + strcpy(HardwareIds[1], str); sprintf_s(str, sizeof(str), "%s&REV_%04"PRIX16"", HardwareIds[1], bcdDevice); strcpy(HardwareIds[0], str); - return 0; } -static int func_compat_id_format(IUDEVICE* pdev, char (*CompatibilityIds)[DEVICE_COMPATIBILITY_ID_SIZE]) +static int func_compat_id_format(IUDEVICE* pdev, + char (*CompatibilityIds)[DEVICE_COMPATIBILITY_ID_SIZE]) { char str[DEVICE_COMPATIBILITY_ID_SIZE]; UINT8 bDeviceClass, bDeviceSubClass, bDeviceProtocol; - bDeviceClass = (UINT8)pdev->query_device_descriptor(pdev, B_DEVICE_CLASS); bDeviceSubClass = (UINT8)pdev->query_device_descriptor(pdev, B_DEVICE_SUBCLASS); bDeviceProtocol = (UINT8)pdev->query_device_descriptor(pdev, B_DEVICE_PROTOCOL); - if(!(pdev->isCompositeDevice(pdev))) + if (!(pdev->isCompositeDevice(pdev))) { - sprintf_s(str, sizeof(str),"USB\\Class_%02"PRIX8"", bDeviceClass); + sprintf_s(str, sizeof(str), "USB\\Class_%02"PRIX8"", bDeviceClass); strcpy(CompatibilityIds[2], str); - sprintf_s(str, sizeof(str),"%s&SubClass_%02"PRIX8"", CompatibilityIds[2], bDeviceSubClass); + sprintf_s(str, sizeof(str), "%s&SubClass_%02"PRIX8"", CompatibilityIds[2], bDeviceSubClass); strcpy(CompatibilityIds[1], str); - sprintf_s(str, sizeof(str),"%s&Prot_%02"PRIX8"", CompatibilityIds[1], bDeviceProtocol); + sprintf_s(str, sizeof(str), "%s&Prot_%02"PRIX8"", CompatibilityIds[1], bDeviceProtocol); strcpy(CompatibilityIds[0], str); } else { - sprintf_s(str, sizeof(str),"USB\\DevClass_00"); + sprintf_s(str, sizeof(str), "USB\\DevClass_00"); strcpy(CompatibilityIds[2], str); - sprintf_s(str, sizeof(str),"%s&SubClass_00", CompatibilityIds[2]); + sprintf_s(str, sizeof(str), "%s&SubClass_00", CompatibilityIds[2]); strcpy(CompatibilityIds[1], str); - sprintf_s(str, sizeof(str),"%s&Prot_00", CompatibilityIds[1]); + sprintf_s(str, sizeof(str), "%s&Prot_00", CompatibilityIds[1]); strcpy(CompatibilityIds[0], str); } @@ -103,15 +101,12 @@ static void func_close_udevice(USB_SEARCHMAN* searchman, IUDEVICE* pdev) int idVendor = 0; int idProduct = 0; URBDRC_PLUGIN* urbdrc = searchman->urbdrc; - pdev->SigToEnd(pdev); idVendor = pdev->query_device_descriptor(pdev, ID_VENDOR); idProduct = pdev->query_device_descriptor(pdev, ID_PRODUCT); searchman->add(searchman, (UINT16) idVendor, (UINT16) idProduct); - pdev->cancel_all_transfer_request(pdev); pdev->wait_action_completion(pdev); - #if ISOCH_FIFO { /* free isoch queue */ @@ -121,10 +116,9 @@ static void func_close_udevice(USB_SEARCHMAN* searchman, IUDEVICE* pdev) isoch_queue->free(isoch_queue); } #endif - urbdrc->udevman->unregister_udevice(urbdrc->udevman, - pdev->get_bus_number(pdev), - pdev->get_dev_number(pdev)); + pdev->get_bus_number(pdev), + pdev->get_dev_number(pdev)); } static int fun_device_string_send_set(char* out_data, int out_offset, char* str) @@ -141,19 +135,16 @@ static int fun_device_string_send_set(char* out_data, int out_offset, char* str) data_write_UINT16(out_data + out_offset + offset, 0x0000); /* add "\0" */ offset += 2; - return offset + out_offset; } static int func_container_id_generate(IUDEVICE* pdev, char* strContainerId) { - char *p, *path; + char* p, *path; UINT8 containerId[17]; UINT16 idVendor, idProduct; - idVendor = (UINT16)pdev->query_device_descriptor(pdev, ID_VENDOR); idProduct = (UINT16)pdev->query_device_descriptor(pdev, ID_PRODUCT); - path = pdev->getPath(pdev); if (strlen(path) > 8) @@ -162,34 +153,30 @@ static int func_container_id_generate(IUDEVICE* pdev, char* strContainerId) p = path; ZeroMemory(containerId, sizeof(containerId)); - sprintf_s((char*)containerId, sizeof(containerId), "%04"PRIX16"%04"PRIX16"%s", idVendor, idProduct, p); - + sprintf_s((char*)containerId, sizeof(containerId), "%04"PRIX16"%04"PRIX16"%s", idVendor, idProduct, + p); /* format */ sprintf_s(strContainerId, DEVICE_CONTAINER_STR_SIZE, - "{%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"}", - containerId[0], containerId[1],containerId[2], containerId[3], - containerId[4], containerId[5], containerId[6], containerId[7], - containerId[8], containerId[9], containerId[10], containerId[11], - containerId[12], containerId[13], containerId[14], containerId[15]); - + "{%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"}", + containerId[0], containerId[1], containerId[2], containerId[3], + containerId[4], containerId[5], containerId[6], containerId[7], + containerId[8], containerId[9], containerId[10], containerId[11], + containerId[12], containerId[13], containerId[14], containerId[15]); return 0; } static int func_instance_id_generate(IUDEVICE* pdev, char* strInstanceId) { UINT8 instanceId[17]; - ZeroMemory(instanceId, sizeof(instanceId)); sprintf_s((char*)instanceId, sizeof(instanceId), "\\%s", pdev->getPath(pdev)); - /* format */ sprintf_s(strInstanceId, DEVICE_INSTANCE_STR_SIZE, - "%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"", - instanceId[0], instanceId[1],instanceId[2], instanceId[3], - instanceId[4], instanceId[5], instanceId[6], instanceId[7], - instanceId[8], instanceId[9], instanceId[10], instanceId[11], - instanceId[12], instanceId[13], instanceId[14], instanceId[15]); - + "%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"", + instanceId[0], instanceId[1], instanceId[2], instanceId[3], + instanceId[4], instanceId[5], instanceId[6], instanceId[7], + instanceId[8], instanceId[9], instanceId[10], instanceId[11], + instanceId[12], instanceId[13], instanceId[14], instanceId[15]); return 0; } @@ -209,16 +196,16 @@ static void func_lock_isoch_mutex(TRANSFER_DATA* transfer_data) data_read_UINT32(transfer_data->pBuffer + 4, FunctionId); if ((FunctionId == TRANSFER_IN_REQUEST || - FunctionId == TRANSFER_OUT_REQUEST) && - transfer_data->cbSize >= 16) + FunctionId == TRANSFER_OUT_REQUEST) && + transfer_data->cbSize >= 16) { data_read_UINT16(transfer_data->pBuffer + 14, URB_Function); if (URB_Function == URB_FUNCTION_ISOCH_TRANSFER && - transfer_data->cbSize >= 20) + transfer_data->cbSize >= 20) { data_read_UINT32(transfer_data->pBuffer + 16, RequestField); - noAck = (RequestField & 0x80000000)>>31; + noAck = (RequestField & 0x80000000) >> 31; if (!noAck) { @@ -237,21 +224,20 @@ static void func_lock_isoch_mutex(TRANSFER_DATA* transfer_data) * * @return 0 on success, otherwise a Win32 error code */ -static UINT urbdrc_process_capability_request(URBDRC_CHANNEL_CALLBACK* callback, char* data, UINT32 data_sizem, UINT32 MessageId) +static UINT 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; + char* out_data; UINT ret; - WLog_VRB(TAG, ""); data_read_UINT32(data + 0, Version); - - InterfaceId = ((STREAM_ID_NONE<<30) | CAPABILITIES_NEGOTIATOR); - + InterfaceId = ((STREAM_ID_NONE << 30) | CAPABILITIES_NEGOTIATOR); out_size = 16; - out_data = (char *) calloc(1, out_size); + out_data = (char*) calloc(1, out_size); + if (!out_data) return ERROR_OUTOFMEMORY; @@ -259,10 +245,8 @@ static UINT urbdrc_process_capability_request(URBDRC_CHANNEL_CALLBACK* callback, 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 */ - ret = callback->channel->Write(callback->channel, out_size, (BYTE*) out_data, NULL); zfree(out_data); - return ret; } @@ -271,7 +255,8 @@ static UINT urbdrc_process_capability_request(URBDRC_CHANNEL_CALLBACK* callback, * * @return 0 on success, otherwise a Win32 error code */ -static UINT urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, char* data, UINT32 data_sizem, UINT32 MessageId) +static UINT urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, char* data, + UINT32 data_sizem, UINT32 MessageId) { UINT32 InterfaceId; UINT32 out_size; @@ -280,16 +265,14 @@ static UINT urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, cha UINT32 Capabilities; char* out_data; UINT ret; - WLog_VRB(TAG, ""); data_read_UINT32(data + 0, MajorVersion); data_read_UINT32(data + 4, MinorVersion); data_read_UINT32(data + 8, Capabilities); - - InterfaceId = ((STREAM_ID_PROXY<<30) | CLIENT_CHANNEL_NOTIFICATION); - + InterfaceId = ((STREAM_ID_PROXY << 30) | CLIENT_CHANNEL_NOTIFICATION); out_size = 24; out_data = (char*) calloc(1, out_size); + if (!out_data) return ERROR_OUTOFMEMORY; @@ -299,9 +282,8 @@ static UINT urbdrc_process_channel_create(URBDRC_CHANNEL_CALLBACK* callback, cha data_write_UINT32(out_data + 12, MajorVersion); data_write_UINT32(out_data + 16, MinorVersion); data_write_UINT32(out_data + 20, Capabilities); /* capabilities version */ - ret = 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 ret; } @@ -313,20 +295,15 @@ static int urdbrc_send_virtual_channel_add(IWTSVirtualChannel* channel, UINT32 M WLog_VRB(TAG, ""); assert(NULL != channel); assert(NULL != channel->Write); - - InterfaceId = ((STREAM_ID_PROXY<<30) | CLIENT_DEVICE_SINK); - + InterfaceId = ((STREAM_ID_PROXY << 30) | CLIENT_DEVICE_SINK); out_size = 12; out_data = (char*) malloc(out_size); memset(out_data, 0, out_size); - data_write_UINT32(out_data + 0, InterfaceId); /* interface */ data_write_UINT32(out_data + 4, MessageId); /* message id */ data_write_UINT32(out_data + 8, ADD_VIRTUAL_CHANNEL); /* function id */ - channel->Write(channel, out_size, (BYTE*) out_data, NULL); zfree(out_data); - return 0; } @@ -345,45 +322,41 @@ static UINT urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVI char strInstanceId[DEVICE_INSTANCE_STR_SIZE]; char* composite_str = "USB\\COMPOSITE"; int size, out_offset, cchCompatIds, bcdUSB; - ISOCH_CALLBACK_QUEUE *cb_queue; + ISOCH_CALLBACK_QUEUE* cb_queue; UINT ret; - WLog_VRB(TAG, ""); - InterfaceId = ((STREAM_ID_PROXY<<30) | CLIENT_DEVICE_SINK); - + InterfaceId = ((STREAM_ID_PROXY << 30) | CLIENT_DEVICE_SINK); /* USB kernel driver detach!! */ pdev->detach_kernel_driver(pdev); - #if ISOCH_FIFO /* create/initial isoch queue */ cb_queue = isoch_queue_new(); + if (!cb_queue) return ERROR_OUTOFMEMORY; - pdev->set_isoch_queue(pdev, (void *)cb_queue); -#endif + pdev->set_isoch_queue(pdev, (void*)cb_queue); +#endif func_hardware_id_format(pdev, HardwareIds); func_compat_id_format(pdev, CompatibilityIds); func_instance_id_generate(pdev, strInstanceId); func_container_id_generate(pdev, strContainerId); - cchCompatIds = strlen(CompatibilityIds[0]) + 1 + - strlen(CompatibilityIds[1]) + 1 + - strlen(CompatibilityIds[2]) + 2; + strlen(CompatibilityIds[1]) + 1 + + strlen(CompatibilityIds[2]) + 2; if (pdev->isCompositeDevice(pdev)) - cchCompatIds += strlen(composite_str)+1; + cchCompatIds += strlen(composite_str) + 1; out_offset = 24; size = 24; + size += (strlen(strInstanceId) + 1) * 2 + + (strlen(HardwareIds[0]) + 1) * 2 + 4 + + (strlen(HardwareIds[1]) + 1) * 2 + 2 + + 4 + (cchCompatIds) * 2 + + (strlen(strContainerId) + 1) * 2 + 4 + 28; + out_data = (char*)calloc(1, size); - size += (strlen(strInstanceId)+1) * 2 + - (strlen(HardwareIds[0]) + 1) * 2 + 4 + - (strlen(HardwareIds[1]) + 1) * 2 + 2 + - 4 + (cchCompatIds) * 2 + - (strlen(strContainerId) + 1) * 2 + 4 + 28; - - out_data = (char *)calloc(1, size); if (!out_data) return ERROR_OUTOFMEMORY; @@ -393,9 +366,7 @@ static UINT urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVI data_write_UINT32(out_data + 12, 0x00000001); /* NumUsbDevice */ data_write_UINT32(out_data + 16, pdev->get_UsbDevice(pdev)); /* UsbDevice */ data_write_UINT32(out_data + 20, 0x00000025); /* cchDeviceInstanceId */ - out_offset = fun_device_string_send_set(out_data, out_offset, strInstanceId); - data_write_UINT32(out_data + out_offset, 0x00000036); /* cchHwIds */ out_offset += 4; /* HardwareIds 1 */ @@ -404,7 +375,6 @@ static UINT urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVI out_offset = fun_device_string_send_set(out_data, out_offset, HardwareIds[1]); /*data_write_UINT16(out_data + out_offset, 0x0000);*/ /* add "\0" */ out_offset += 2; - data_write_UINT32(out_data + out_offset, cchCompatIds); /* cchCompatIds */ out_offset += 4; /* CompatibilityIds 1 */ @@ -419,33 +389,30 @@ static UINT urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVI /*data_write_UINT16(out_data + out_offset, 0x0000);*/ /* add "\0" */ out_offset += 2; - data_write_UINT32(out_data + out_offset, 0x00000027); /* cchContainerId */ out_offset += 4; /* ContainerId */ out_offset = fun_device_string_send_set(out_data, out_offset, strContainerId); - /* USB_DEVICE_CAPABILITIES 28 bytes */ data_write_UINT32(out_data + out_offset, 0x0000001c); /* CbSize */ data_write_UINT32(out_data + out_offset + 4, 2); /* UsbBusInterfaceVersion, 0 ,1 or 2 */ data_write_UINT32(out_data + out_offset + 8, 0x600); /* USBDI_Version, 0x500 or 0x600 */ - /* Supported_USB_Version, 0x110,0x110 or 0x200(usb2.0) */ bcdUSB = pdev->query_device_descriptor(pdev, BCD_USB); data_write_UINT32(out_data + out_offset + 12, bcdUSB); - data_write_UINT32(out_data + out_offset + 16, 0x00000000); /* HcdCapabilities, MUST always be zero */ + data_write_UINT32(out_data + out_offset + 16, + 0x00000000); /* HcdCapabilities, MUST always be zero */ if (bcdUSB < 0x200) data_write_UINT32(out_data + out_offset + 20, 0x00000000); /* DeviceIsHighSpeed */ else data_write_UINT32(out_data + out_offset + 20, 0x00000001); /* DeviceIsHighSpeed */ - data_write_UINT32(out_data + out_offset + 24, 0x50); /* NoAckIsochWriteJitterBufferSizeInMs, >=10 or <=512 */ + data_write_UINT32(out_data + out_offset + 24, + 0x50); /* NoAckIsochWriteJitterBufferSizeInMs, >=10 or <=512 */ out_offset += 28; - - ret = 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 ret; } @@ -454,13 +421,12 @@ static UINT urdbrc_send_usb_device_add(URBDRC_CHANNEL_CALLBACK* callback, IUDEVI * * @return 0 on success, otherwise a Win32 error code */ -static UINT urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, char* pBuffer, UINT32 cbSize) +static UINT urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, char* pBuffer, + UINT32 cbSize) { UINT32 MessageId; UINT32 FunctionId; - UINT error = CHANNEL_RC_OK; - data_read_UINT32(pBuffer + 0, MessageId); data_read_UINT32(pBuffer + 4, FunctionId); @@ -480,15 +446,19 @@ static UINT urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, char } #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) -static char *devd_get_val(char *buf, size_t buf_size, const char *val_name, size_t val_name_size, size_t *val_size) { - char *ret, *buf_end, *ptr; - +static char* devd_get_val(char* buf, size_t buf_size, const char* val_name, size_t val_name_size, + size_t* val_size) +{ + char* ret, *buf_end, *ptr; buf_end = (buf + buf_size); + for (ret = buf; ret != NULL && ret < buf_end;) { ret = memmem(ret, (buf_end - ret), val_name, val_name_size); + if (ret == NULL) return NULL; + /* Found. */ /* Check: space before or buf+1. */ if ((buf + 1) < ret && ret[-1] != ' ') @@ -496,58 +466,68 @@ static char *devd_get_val(char *buf, size_t buf_size, const char *val_name, size ret += val_name_size; continue; } + /* Check: = after name and size for value. */ ret += val_name_size; + if ((ret + 1) >= buf_end) return NULL; + if (ret[0] != '=') continue; + ret ++; break; } + if (ret == NULL || val_size == NULL) return ret; + /* Calc value data size. */ ptr = memchr(ret, ' ', (buf_end - ret)); + if (ptr == NULL) /* End of string/last value. */ ptr = buf_end; + (*val_size) = (ptr - ret); return ret; } -static void *urbdrc_search_usb_device(void *arg) { - USB_SEARCHMAN *searchman = (USB_SEARCHMAN*)arg; - URBDRC_PLUGIN *urbdrc = (URBDRC_PLUGIN*)searchman->urbdrc; - IUDEVMAN *udevman = urbdrc->udevman; - IWTSVirtualChannelManager *channel_mgr = urbdrc->listener_callback->channel_mgr; - IWTSVirtualChannel *dvc_channel; - USB_SEARCHDEV *sdev; - IUDEVICE *pdev; +static void* urbdrc_search_usb_device(void* arg) +{ + USB_SEARCHMAN* searchman = (USB_SEARCHMAN*)arg; + URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*)searchman->urbdrc; + IUDEVMAN* udevman = urbdrc->udevman; + IWTSVirtualChannelManager* channel_mgr = urbdrc->listener_callback->channel_mgr; + IWTSVirtualChannel* dvc_channel; + USB_SEARCHDEV* sdev; + IUDEVICE* pdev; HANDLE listobj[2]; HANDLE mon_fd; int devd_skt; char buf[4096], *val, *ptr, *end_val; ssize_t data_size; size_t val_size, tm; - int idVendor, idProduct; - int busnum, devnum; + long idVendor, idProduct; + long busnum, devnum; int action, success, error, found, on_close; struct sockaddr_un sun; DWORD status; UINT32 error; - WLog_DBG(TAG, "urbdrc_search_usb_device - devd: start"); - devd_skt = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + if (devd_skt == -1) { WLog_ERR(TAG, "Can't create devd socket: error = %i", errno); goto err_out; } + memset(&sun, 0, sizeof(sun)); sun.sun_family = PF_LOCAL; sun.sun_len = sizeof(sun); strlcpy(sun.sun_path, "/var/run/devd.seqpacket.pipe", sizeof(sun.sun_path)); + if (-1 == connect(devd_skt, (struct sockaddr*)&sun, sizeof(sun))) { WLog_ERR(TAG, "Can't connect devd socket: error = %i - %s", errno, strerror(errno)); @@ -562,185 +542,221 @@ static void *urbdrc_search_usb_device(void *arg) { while (WaitForMultipleObjects(2, listobj, FALSE, INFINITE) != WAIT_OBJECT_0) { + status = WaitForMultipleObjects(2, listobj, FALSE, INFINITE); - status = WaitForMultipleObjects(2, listobj, FALSE, INFINITE); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); - return 0; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); + return 0; + } - if (status == WAIT_OBJECT_0) - break; + if (status == WAIT_OBJECT_0) + break; + errno = 0; WLog_DBG(TAG, "======= SEARCH ======= "); - /* !system=USB subsystem=DEVICE type=ATTACH ugen=ugen3.3 cdev=ugen3.3 vendor=0x046d product=0x082d devclass=0xef devsubclass=0x02 sernum="6E7D726F" release=0x0011 mode=host port=4 parent=ugen3.1 */ /* !system=USB subsystem=DEVICE type=DETACH ugen=ugen3.3 cdev=ugen3.3 vendor=0x046d product=0x082d devclass=0xef devsubclass=0x02 sernum="6E7D726F" release=0x0011 mode=host port=4 parent=ugen3.1 */ data_size = read(devd_skt, buf, (sizeof(buf) - 1)); + if (data_size == -1) { WLog_ERR(TAG, "devd socket read: error = %i", errno); break; } + buf[data_size] = 0; WLog_DBG(TAG, "devd event: %s", buf); - + if (buf[0] != '!') /* Skeep non notify events. */ continue; + /* Check: system=USB */ val = devd_get_val(buf, data_size, "system", 6, &val_size); + if (val == NULL || val_size != 3 || memcmp(val, "USB", 3) != 0) continue; + /* Check: subsystem=DEVICE */ val = devd_get_val(buf, data_size, "subsystem", 9, &val_size); + if (val == NULL || val_size != 6 || memcmp(val, "DEVICE", 6) != 0) continue; + /* Get event type. */ val = devd_get_val(buf, data_size, "type", 4, &val_size); + if (val == NULL || val_size != 6) continue; + action = -1; + if (memcmp(val, "ATTACH", 6) == 0) action = 0; + if (memcmp(val, "DETACH", 6) == 0) action = 1; + if (action == -1) continue; /* Skeep other actions. */ /* Get bus and dev num. */ /* ugen=ugen3.3 */ val = devd_get_val(buf, data_size, "ugen", 4, &val_size); + if (val == NULL || val_size < 7 || memcmp(val, "ugen", 4) != 0) continue; + val += 4; val_size -= 4; ptr = memchr(val, '.', val_size); + if (ptr == NULL) continue; + /* Prepare strings. */ ptr[0] = 0; ptr ++; val[val_size] = 0; /* Extract numbers. */ - busnum = atoi(val); - devnum = atoi(ptr); + busnum = strtol(val, NULL, 0); + + if (errno != 0) + continue; + + devnum = strtol(ptr, NULL, 0); + + if (errno != 0) + continue; + /* Restore spaces. */ ptr[-1] = ' '; val[val_size] = ' '; - /* Handle event. */ dvc_channel = NULL; switch (action) { - case 0: /* ATTACH */ - sdev = NULL; - success = 0; - found = 0; - - /* vendor=0x046d */ - val = devd_get_val(buf, data_size, "vendor", 6, &val_size); - if (val == NULL || val_size < 1) - continue; - val[val_size] = 0; - idVendor = strtol(val, NULL, 16); - val[val_size] = ' '; - - /* product=0x082d */ - val = devd_get_val(buf, data_size, "product", 7, &val_size); - if (val == NULL || val_size < 1) - continue; - val[val_size] = 0; - idProduct = strtol(val, NULL, 16); - val[val_size] = ' '; - - WLog_DBG(TAG, "ATTACH: bus: %i, dev: %i, ven: %i, prod: %i", busnum, devnum, idVendor, idProduct); - - dvc_channel = channel_mgr->FindChannelById(channel_mgr, urbdrc->first_channel_id); - searchman->rewind(searchman); - while (dvc_channel && searchman->has_next(searchman)) - { - sdev = searchman->get_next(searchman); - if (sdev->idVendor == idVendor && - sdev->idProduct == idProduct) - { - WLog_VRB(TAG, "Searchman Found Device: %04"PRIx16":%04"PRIx16"", - sdev->idVendor, sdev->idProduct); - found = 1; - break; - } - } + case 0: /* ATTACH */ + sdev = NULL; + success = 0; + found = 0; + /* vendor=0x046d */ + val = devd_get_val(buf, data_size, "vendor", 6, &val_size); - if (!found && udevman->isAutoAdd(udevman)) - { - WLog_VRB(TAG, "Auto Find Device: %04x:%04x ", - idVendor, idProduct); - found = 2; - } + if (val == NULL || val_size < 1) + continue; - if (found) - { - success = udevman->register_udevice(udevman, busnum, devnum, - searchman->UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR); - } + val[val_size] = 0; + idVendor = strtol(val, NULL, 16); - if (success) - { - searchman->UsbDevice ++; + if (errno != 0) + continue; - usleep(400000); - error = urdbrc_send_virtual_channel_add(dvc_channel, 0); - if (found == 1) - searchman->remove(searchman, sdev->idVendor, sdev->idProduct); - } - break; - case 1: /* DETACH */ - pdev = NULL; - on_close = 0; - WLog_DBG(TAG, "DETACH: bus: %i, dev: %i", busnum, devnum); + val[val_size] = ' '; + /* product=0x082d */ + val = devd_get_val(buf, data_size, "product", 7, &val_size); - usleep(500000); - udevman->loading_lock(udevman); - udevman->rewind(udevman); - while (udevman->has_next(udevman)) - { - pdev = udevman->get_next(udevman); - if (pdev->get_bus_number(pdev) == busnum && - pdev->get_dev_number(pdev) == devnum) + if (val == NULL || val_size < 1) + continue; + + val[val_size] = 0; + idProduct = strtol(val, NULL, 16); + + if (errno != 0) + continue; + + val[val_size] = ' '; + WLog_DBG(TAG, "ATTACH: bus: %i, dev: %i, ven: %i, prod: %i", busnum, devnum, idVendor, idProduct); + dvc_channel = channel_mgr->FindChannelById(channel_mgr, urbdrc->first_channel_id); + searchman->rewind(searchman); + + while (dvc_channel && searchman->has_next(searchman)) { - dvc_channel = channel_mgr->FindChannelById(channel_mgr, pdev->get_channel_id(pdev)); + sdev = searchman->get_next(searchman); - if (dvc_channel == NULL) + if (sdev->idVendor == idVendor && + sdev->idProduct == idProduct) { - WLog_ERR(TAG, "SEARCH: dvc_channel %d is NULL!!", pdev->get_channel_id(pdev)); - func_close_udevice(searchman, pdev); + WLog_VRB(TAG, "Searchman Found Device: %04"PRIx16":%04"PRIx16"", + sdev->idVendor, sdev->idProduct); + found = 1; break; } + } + + if (!found && udevman->isAutoAdd(udevman)) + { + WLog_VRB(TAG, "Auto Find Device: %04x:%04x ", + idVendor, idProduct); + found = 2; + } + + if (found) + { + success = udevman->register_udevice(udevman, busnum, devnum, + searchman->UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR); + } + + if (success) + { + searchman->UsbDevice ++; + usleep(400000); + error = urdbrc_send_virtual_channel_add(dvc_channel, 0); + + if (found == 1) + searchman->remove(searchman, sdev->idVendor, sdev->idProduct); + } + + break; - if (!pdev->isSigToEnd(pdev)) + case 1: /* DETACH */ + pdev = NULL; + on_close = 0; + WLog_DBG(TAG, "DETACH: bus: %i, dev: %i", busnum, devnum); + usleep(500000); + udevman->loading_lock(udevman); + udevman->rewind(udevman); + + while (udevman->has_next(udevman)) + { + pdev = udevman->get_next(udevman); + + if (pdev->get_bus_number(pdev) == busnum && + pdev->get_dev_number(pdev) == devnum) { - dvc_channel->Write(dvc_channel, 0, NULL, NULL); - pdev->SigToEnd(pdev); - } + dvc_channel = channel_mgr->FindChannelById(channel_mgr, pdev->get_channel_id(pdev)); - on_close = 1; - break; + if (dvc_channel == NULL) + { + WLog_ERR(TAG, "SEARCH: dvc_channel %d is NULL!!", pdev->get_channel_id(pdev)); + func_close_udevice(searchman, pdev); + break; + } + + if (!pdev->isSigToEnd(pdev)) + { + dvc_channel->Write(dvc_channel, 0, NULL, NULL); + pdev->SigToEnd(pdev); + } + + on_close = 1; + break; + } } - } - udevman->loading_unlock(udevman); - usleep(300000); + udevman->loading_unlock(udevman); + usleep(300000); - if (pdev && on_close && dvc_channel && - pdev->isSigToEnd(pdev) && - !(pdev->isChannelClosed(pdev))) - { - dvc_channel->Close(dvc_channel); - } - break; + if (pdev && on_close && dvc_channel && + pdev->isSigToEnd(pdev) && + !(pdev->isChannelClosed(pdev))) + { + dvc_channel->Close(dvc_channel); + } + + break; } } @@ -749,8 +765,7 @@ err_out: close(devd_skt); sem_post(&searchman->sem_term); WLog_DBG(TAG, "urbdrc_search_usb_device - devd: end"); - - return 0; + return 0; } #endif #if defined (__linux__) @@ -766,18 +781,16 @@ static void* urbdrc_search_usb_device(void* arg) HANDLE listobj[2]; HANDLE mon_fd; int numobj, timeout; - int busnum, devnum; + long busnum, devnum; int success = 0, on_close = 0, found = 0; WLog_VRB(TAG, ""); channel_mgr = urbdrc->listener_callback->channel_mgr; DWORD status; DWORD dwError; - /* init usb monitor */ struct udev* udev; struct udev_device* dev; struct udev_monitor* mon; - udev = udev_new(); if (!udev) @@ -790,11 +803,11 @@ static void* urbdrc_search_usb_device(void* arg) mon = udev_monitor_new_from_netlink(udev, "udev"); udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", "usb_device"); udev_monitor_enable_receiving(mon); - /* Get the file descriptor (fd) for the monitor. This fd will get passed to select() */ mon_fd = CreateFileDescriptorEvent(NULL, TRUE, FALSE, - udev_monitor_get_fd(mon), WINPR_FD_READ); + udev_monitor_get_fd(mon), WINPR_FD_READ); + if (!mon_fd) goto fail_create_monfd_event; @@ -805,47 +818,45 @@ static void* urbdrc_search_usb_device(void* arg) devnum = 0; sdev = NULL; pdev = NULL; - dvc_channel = NULL; + dvc_channel = NULL; on_close = 0; listobj[0] = searchman->term_event; listobj[1] = mon_fd; numobj = 2; + status = WaitForMultipleObjects(numobj, listobj, FALSE, INFINITE); - status = WaitForMultipleObjects(numobj, listobj, FALSE, INFINITE); - - if (status == WAIT_FAILED) - { - dwError = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %"PRIu32"!", dwError); - goto out; - } - - status = WaitForSingleObject(searchman->term_event, 0); + if (status == WAIT_FAILED) + { + dwError = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %"PRIu32"!", dwError); + goto out; + } - if (status == WAIT_FAILED) - { - dwError = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", dwError); - goto out; - } + status = WaitForSingleObject(searchman->term_event, 0); - if (status == WAIT_OBJECT_0) - { - sem_post(&searchman->sem_term); - goto out; - } + if (status == WAIT_FAILED) + { + dwError = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", dwError); + goto out; + } - status = WaitForSingleObject(mon_fd, 0); + if (status == WAIT_OBJECT_0) + { + sem_post(&searchman->sem_term); + goto out; + } - if (status == WAIT_FAILED) - { - dwError = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", dwError); - goto out; - } + status = WaitForSingleObject(mon_fd, 0); + if (status == WAIT_FAILED) + { + dwError = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", dwError); + goto out; + } - if (status == WAIT_OBJECT_0) + if (status == WAIT_OBJECT_0) { dev = udev_monitor_receive_device(mon); @@ -855,36 +866,48 @@ static void* urbdrc_search_usb_device(void* arg) if (strcmp(action, "add") == 0) { - int idVendor, idProduct; + long idVendor, idProduct; success = 0; found = 0; - idVendor = strtol(udev_device_get_sysattr_value(dev, "idVendor"), NULL, 16); + + if (errno != 0) + continue; + idProduct = strtol(udev_device_get_sysattr_value(dev, "idProduct"), NULL, 16); + if (errno != 0) + continue; + if (idVendor < 0 || idProduct < 0) { udev_device_unref(dev); continue; } - busnum = atoi(udev_device_get_property_value(dev,"BUSNUM")); - devnum = atoi(udev_device_get_property_value(dev,"DEVNUM")); + busnum = strtol(udev_device_get_property_value(dev, "BUSNUM"), NULL, 0); - dvc_channel = channel_mgr->FindChannelById(channel_mgr, - urbdrc->first_channel_id); + if (errno != 0) + continue; + + devnum = strtol(udev_device_get_property_value(dev, "DEVNUM"), NULL, 0); + + if (errno != 0) + continue; + dvc_channel = channel_mgr->FindChannelById(channel_mgr, + urbdrc->first_channel_id); searchman->rewind(searchman); - while(dvc_channel && searchman->has_next(searchman)) + while (dvc_channel && searchman->has_next(searchman)) { sdev = searchman->get_next(searchman); if (sdev->idVendor == idVendor && - sdev->idProduct == idProduct) + sdev->idProduct == idProduct) { WLog_VRB(TAG, "Searchman Find Device: %04"PRIx16":%04"PRIx16"", - sdev->idVendor, sdev->idProduct); + sdev->idVendor, sdev->idProduct); found = 1; break; } @@ -893,32 +916,29 @@ static void* urbdrc_search_usb_device(void* arg) if (!found && udevman->isAutoAdd(udevman)) { WLog_VRB(TAG, "Auto Find Device: %04x:%04x ", - idVendor, idProduct); + idVendor, idProduct); found = 2; } if (found) { success = udevman->register_udevice(udevman, busnum, devnum, - searchman->UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR); + searchman->UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR); } if (success) { searchman->UsbDevice++; - - /* when we send the usb device add request, - * we will detach the device driver at same - * time. But, if the time of detach the - * driver and attach driver is too close, - * the system will crash. workaround: we - * wait it for some time to avoid system + /* when we send the usb device add request, + * we will detach the device driver at same + * time. But, if the time of detach the + * driver and attach driver is too close, + * the system will crash. workaround: we + * wait it for some time to avoid system * crash. */ - listobj[0] = searchman->term_event; numobj = 1; timeout = 4000; /* milliseconds */ - status = WaitForMultipleObjects(numobj, listobj, FALSE, timeout); if (status == WAIT_FAILED) @@ -952,14 +972,21 @@ static void* urbdrc_search_usb_device(void* arg) } else if (strcmp(action, "remove") == 0) { - busnum = atoi(udev_device_get_property_value(dev,"BUSNUM")); - devnum = atoi(udev_device_get_property_value(dev,"DEVNUM")); + busnum = strtol(udev_device_get_property_value(dev, "BUSNUM"), NULL, 0); + + if (errno != 0) + goto out; + + devnum = strtol(udev_device_get_property_value(dev, "DEVNUM"), NULL, 0); + + if (errno != 0) + goto out; usleep(500000); udevman->loading_lock(udevman); udevman->rewind(udevman); - while(udevman->has_next(udevman)) + while (udevman->has_next(udevman)) { pdev = udevman->get_next(udevman); @@ -976,7 +1003,7 @@ static void* urbdrc_search_usb_device(void* arg) if (!pdev->isSigToEnd(pdev)) { - dvc_channel->Write(dvc_channel, 0, NULL, NULL); + dvc_channel->Write(dvc_channel, 0, NULL, NULL); pdev->SigToEnd(pdev); } @@ -986,11 +1013,9 @@ static void* urbdrc_search_usb_device(void* arg) } udevman->loading_unlock(udevman); - listobj[0] = searchman->term_event; numobj = 1; timeout = 3000; /* milliseconds */ - status = WaitForMultipleObjects(numobj, listobj, FALSE, timeout); if (status == WAIT_FAILED) @@ -1031,12 +1056,11 @@ static void* urbdrc_search_usb_device(void* arg) } } } + out: CloseHandle(mon_fd); - fail_create_monfd_event: sem_post(&searchman->sem_term); - return 0; } #endif @@ -1055,27 +1079,24 @@ void* urbdrc_new_device_create(void* arg) UINT32 MessageId; UINT32 FunctionId; int i = 0, found = 0; - WLog_DBG(TAG, "..."); - channel_mgr = urbdrc->listener_callback->channel_mgr; ChannelId = channel_mgr->GetChannelId(callback->channel); - data_read_UINT32(pBuffer + 0, MessageId); data_read_UINT32(pBuffer + 4, FunctionId); - int error = 0; switch (urbdrc->vchannel_status) { case INIT_CHANNEL_IN: urbdrc->first_channel_id = ChannelId; + 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); @@ -1086,7 +1107,7 @@ void* urbdrc_new_device_create(void* arg) udevman->loading_lock(udevman); udevman->rewind(udevman); - while(udevman->has_next(udevman)) + while (udevman->has_next(udevman)) { pdev = udevman->get_next(udevman); @@ -1098,26 +1119,26 @@ void* urbdrc_new_device_create(void* arg) break; } } + udevman->loading_unlock(udevman); - + if (found && pdev->isAlreadySend(pdev)) { - /* when we send the usb device add request, we will detach - * the device driver at same time. But, if the time of detach the + /* when we send the usb device add request, we will detach + * the device driver at same time. But, if the time of detach the * driver and attach driver is too close, the system will crash. * workaround: we wait it for some time to avoid system crash. */ - error = pdev->wait_for_detach(pdev); if (error >= 0) urdbrc_send_usb_device_add(callback, pdev); } - + break; default: WLog_ERR(TAG, "vchannel_status unknown value %"PRIu32"", - urbdrc->vchannel_status); + urbdrc->vchannel_status); break; } @@ -1129,16 +1150,15 @@ void* urbdrc_new_device_create(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callback, char* pBuffer, UINT32 cbSize) +static UINT urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callback, char* pBuffer, + UINT32 cbSize) { int i; UINT32 MessageId; UINT32 FunctionId; UINT error = CHANNEL_RC_OK; URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) callback->plugin; - WLog_DBG(TAG, "..."); - data_read_UINT32(pBuffer + 0, MessageId); data_read_UINT32(pBuffer + 4, FunctionId); @@ -1151,18 +1171,19 @@ static UINT urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callbac case RIMCALL_RELEASE: WLog_VRB(TAG, "recv RIMCALL_RELEASE"); 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); @@ -1180,6 +1201,7 @@ static UINT urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callbac free(transfer_data); return ERROR_INVALID_OPERATION; } + pthread_detach(thread); break; @@ -1188,6 +1210,7 @@ static UINT urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callbac error = 1; break; } + return error; } @@ -1220,10 +1243,9 @@ static UINT urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback return 0; udevman = (IUDEVMAN*) urbdrc->udevman; - data_read_UINT32(pBuffer + 0, InterfaceTemp); InterfaceId = (InterfaceTemp & 0x0fffffff); - Mask = ((InterfaceTemp & 0xf0000000)>>30); + Mask = ((InterfaceTemp & 0xf0000000) >> 30); WLog_VRB(TAG, "Size=%"PRIu32" InterfaceId=0x%"PRIX32" Mask=0x%"PRIX32"", cbSize, InterfaceId, Mask); switch (InterfaceId) @@ -1240,8 +1262,8 @@ static UINT urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback WLog_VRB(TAG, "InterfaceId 0x%"PRIX32" Start matching devices list", InterfaceId); pthread_t thread; TRANSFER_DATA* transfer_data; + transfer_data = (TRANSFER_DATA*)malloc(sizeof(TRANSFER_DATA)); - transfer_data = (TRANSFER_DATA *)malloc(sizeof(TRANSFER_DATA)); if (!transfer_data) { WLog_ERR(TAG, "transfer_data is NULL!!"); @@ -1253,7 +1275,8 @@ static UINT urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback transfer_data->udevman = udevman; transfer_data->cbSize = cbSize - 4; transfer_data->UsbDevice = InterfaceId; - transfer_data->pBuffer = (BYTE *)malloc((cbSize - 4)); + transfer_data->pBuffer = (BYTE*)malloc((cbSize - 4)); + if (!transfer_data->pBuffer) { free(transfer_data); @@ -1261,16 +1284,14 @@ static UINT urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback } memcpy(transfer_data->pBuffer, pBuffer + 4, (cbSize - 4)); - /* To ensure that not too many urb requests at the same time */ udevman->wait_urb(udevman); - #if ISOCH_FIFO /* lock isoch mutex */ func_lock_isoch_mutex(transfer_data); #endif - error = pthread_create(&thread, 0, urbdrc_process_udev_data_transfer, transfer_data); + if (error != 0) { WLog_ERR(TAG, "Create Data Transfer Thread got error = %"PRIu32"", error); @@ -1291,7 +1312,7 @@ static UINT urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback * * @return 0 on success, otherwise a Win32 error code */ -static UINT urbdrc_on_close(IWTSVirtualChannelCallback * pChannelCallback) +static UINT urbdrc_on_close(IWTSVirtualChannelCallback* pChannelCallback) { URBDRC_CHANNEL_CALLBACK* callback = (URBDRC_CHANNEL_CALLBACK*) pChannelCallback; URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) callback->plugin; @@ -1300,13 +1321,12 @@ static UINT urbdrc_on_close(IWTSVirtualChannelCallback * pChannelCallback) IUDEVICE* pdev = NULL; UINT32 ChannelId = 0; int found = 0; - ChannelId = callback->channel_mgr->GetChannelId(callback->channel); WLog_INFO(TAG, "urbdrc_on_close: channel id %"PRIu32"", ChannelId); udevman->loading_lock(udevman); udevman->rewind(udevman); - while(udevman->has_next(udevman)) + while (udevman->has_next(udevman)) { pdev = udevman->get_next(udevman); @@ -1336,13 +1356,13 @@ static UINT urbdrc_on_close(IWTSVirtualChannelCallback * pChannelCallback) * @return 0 on success, otherwise a Win32 error code */ static UINT urbdrc_on_new_channel_connection(IWTSListenerCallback* pListenerCallback, - IWTSVirtualChannel * pChannel, BYTE* pData, BOOL* pbAccept, IWTSVirtualChannelCallback** ppCallback) + IWTSVirtualChannel* pChannel, BYTE* pData, BOOL* pbAccept, IWTSVirtualChannelCallback** ppCallback) { URBDRC_LISTENER_CALLBACK* listener_callback = (URBDRC_LISTENER_CALLBACK*) pListenerCallback; URBDRC_CHANNEL_CALLBACK* callback; - WLog_VRB(TAG, ""); callback = (URBDRC_CHANNEL_CALLBACK*) calloc(1, sizeof(URBDRC_CHANNEL_CALLBACK)); + if (!callback) return ERROR_OUTOFMEMORY; @@ -1352,7 +1372,6 @@ static UINT urbdrc_on_new_channel_connection(IWTSListenerCallback* pListenerCall callback->channel_mgr = listener_callback->channel_mgr; callback->channel = pChannel; *ppCallback = (IWTSVirtualChannelCallback*) callback; - return CHANNEL_RC_OK; } @@ -1366,29 +1385,29 @@ static UINT urbdrc_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) pPlugin; IUDEVMAN* udevman = NULL; USB_SEARCHMAN* searchman = NULL; - WLog_VRB(TAG, ""); 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; 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; + urbdrc->searchman = searchman; return pChannelMgr->CreateListener(pChannelMgr, "URBDRC", 0, - (IWTSListenerCallback*) urbdrc->listener_callback, NULL); + (IWTSListenerCallback*) urbdrc->listener_callback, NULL); } /** @@ -1401,7 +1420,6 @@ static UINT 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) @@ -1413,7 +1431,7 @@ static UINT urbdrc_plugin_terminated(IWTSPlugin* pPlugin) if (searchman->started) { struct timespec ts; - ts.tv_sec = time(NULL)+10; + ts.tv_sec = time(NULL) + 10; ts.tv_nsec = 0; sem_timedwait(&searchman->sem_term, &ts); } @@ -1431,7 +1449,7 @@ static UINT urbdrc_plugin_terminated(IWTSPlugin* pPlugin) if (urbdrc->listener_callback) zfree(urbdrc->listener_callback); - if(urbdrc) + if (urbdrc) zfree(urbdrc); return CHANNEL_RC_OK; @@ -1448,7 +1466,6 @@ static void urbdrc_register_udevman_addin(IWTSPlugin* pPlugin, IUDEVMAN* udevman } DEBUG_DVC("device registered."); - urbdrc->udevman = udevman; } @@ -1461,8 +1478,9 @@ static UINT urbdrc_load_udevman_addin(IWTSPlugin* pPlugin, const char* name, ADD { 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); - entry = (PFREERDP_URBDRC_DEVICE_ENTRY) freerdp_load_channel_addin_entry("urbdrc", (LPSTR) name, NULL, 0); if (!entry) return ERROR_INVALID_OPERATION; @@ -1503,11 +1521,10 @@ static UINT urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args) int status; DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; - flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; - status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, - urbdrc_args, flags, urbdrc, NULL, NULL); + urbdrc_args, flags, urbdrc, NULL, NULL); + if (status < 0) return ERROR_INVALID_DATA; @@ -1519,7 +1536,6 @@ static UINT urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args) continue; CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "dbg") { WLog_SetLogLevel(WLog_Get(TAG), WLOG_TRACE); @@ -1531,12 +1547,11 @@ static UINT urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args) } CommandLineSwitchDefault(arg) { - } - CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); + return CHANNEL_RC_OK; } @@ -1556,13 +1571,13 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) UINT status = 0; ADDIN_ARGV* args; URBDRC_PLUGIN* urbdrc; - urbdrc = (URBDRC_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "urbdrc"); args = pEntryPoints->GetPluginData(pEntryPoints); if (urbdrc == NULL) { urbdrc = (URBDRC_PLUGIN*) calloc(1, sizeof(URBDRC_PLUGIN)); + if (!urbdrc) return CHANNEL_RC_NO_MEMORY; @@ -1572,13 +1587,14 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) urbdrc->iface.Terminated = urbdrc_plugin_terminated; urbdrc->searchman = NULL; urbdrc->vchannel_status = INIT_CHANNEL_IN; - status = pEntryPoints->RegisterPlugin(pEntryPoints, "urbdrc", (IWTSPlugin*) urbdrc); + if (status != CHANNEL_RC_OK) goto error_register; } status = urbdrc_process_addin_args(urbdrc, args); + if (status != CHANNEL_RC_OK) { /* TODO: we should unregister the plugin ? */ @@ -1586,7 +1602,6 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) //return status; } - if (!urbdrc->subsystem && !urbdrc_set_subsystem(urbdrc, "libusb")) { /* TODO: we should unregister the plugin ? */ @@ -1595,7 +1610,6 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) } return urbdrc_load_udevman_addin((IWTSPlugin*) urbdrc, urbdrc->subsystem, args); - error_register: free(urbdrc); return status; diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 63edc3e..3bb6298 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -229,12 +230,12 @@ static void freerdp_client_print_command_line_args(COMMAND_LINE_ARGUMENT_A* arg) || (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL)) { BOOL overlong = FALSE; + printf(" %s", "/"); if (arg->Format) { size_t length = (strlen(arg->Name) + strlen(arg->Format) + 2); - if (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL) length += 2; @@ -312,6 +313,7 @@ BOOL freerdp_client_print_command_line_help_ex(int argc, char** argv, printf("Multimedia Redirection: /multimedia:sys:alsa\n"); printf("USB Device Redirection: /usb:id,dev:054c:0268\n"); printf("\n"); + printf("For Gateways, the https_proxy environment variable is respected:\n"); #ifdef _WIN32 printf(" set HTTPS_PROXY=http://proxy.contoso.com:3128/\n"); @@ -320,6 +322,7 @@ BOOL freerdp_client_print_command_line_help_ex(int argc, char** argv, #endif printf(" xfreerdp /g:rdp.contoso.com ...\n"); printf("\n"); + printf("More documentation is coming, in the meantime consult source files\n"); printf("\n"); return TRUE; @@ -1063,12 +1066,17 @@ BOOL freerdp_parse_username(char* username, char** user, char** domain) BOOL freerdp_parse_hostname(char* hostname, char** host, int* port) { char* p; - int length; p = strrchr(hostname, ':'); if (p) { - length = (p - hostname); + unsigned long val; + SSIZE_T length = (p - hostname); + errno = 0; + val = strtoul(p + 1, NULL, 0); + + if ((errno != 0) || (val <= 0) || (val > UINT16_MAX)) + return FALSE; *host = (char*) calloc(length + 1UL, sizeof(char)); if (!(*host)) @@ -1076,7 +1084,7 @@ BOOL freerdp_parse_hostname(char* hostname, char** host, int* port) CopyMemory(*host, hostname, length); (*host)[length] = '\0'; - *port = atoi(p + 1); + *port = val; } else { @@ -1498,6 +1506,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, CommandLineFindArgumentA(args, "v"); arg = args; + errno = 0; do { @@ -1518,8 +1527,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (p) { + unsigned long val = strtoul(&p[1], NULL, 0); + + if ((errno != 0) || (val == 0) || (val > UINT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; length = (int)(p - arg->Value); - settings->ServerPort = atoi(&p[1]); + settings->ServerPort = val; if (!(settings->ServerHostname = (char*) calloc(length + 1UL, sizeof(char)))) return COMMAND_LINE_ERROR_MEMORY; @@ -1550,7 +1563,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (*(p2 + 1) == ':') { - settings->ServerPort = atoi(&p2[2]); + unsigned long val = strtoul(&p2[2], NULL, 0); + + if ((errno != 0) || (val == 0) || (val > UINT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->ServerPort = val; } printf("hostname %s port %"PRIu32"\n", settings->ServerHostname, settings->ServerPort); @@ -1584,11 +1602,21 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "w") { - settings->DesktopWidth = atoi(arg->Value); + long val = strtol(arg->Value, NULL, 0); + + if ((errno != 0) || (val <= 0) || (val > UINT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->DesktopWidth = val; } CommandLineSwitchCase(arg, "h") { - settings->DesktopHeight = atoi(arg->Value); + long val = strtol(arg->Value, NULL, 0); + + if ((errno != 0) || (val <= 0) || (val > UINT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->DesktopHeight = val; } CommandLineSwitchCase(arg, "size") { @@ -1600,8 +1628,28 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (p) { *p = '\0'; - settings->DesktopWidth = atoi(str); - settings->DesktopHeight = atoi(&p[1]); + { + long val = strtol(str, NULL, 0); + + if ((errno != 0) || (val <= 0) || (val > UINT16_MAX)) + { + free(str); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + + settings->DesktopWidth = val; + } + { + long val = strtol(&p[1], NULL, 0); + + if ((errno != 0) || (val <= 0) || (val > UINT16_MAX)) + { + free(str); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + + settings->DesktopHeight = val; + } } else { @@ -1616,7 +1664,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, settings->PercentScreenUseWidth = 1; partial = TRUE; } - if (strchr(p, 'h')) { settings->PercentScreenUseHeight = 1; @@ -1630,7 +1677,17 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } *p = '\0'; - settings->PercentScreen = atoi(str); + { + long val = strtol(str, NULL, 0); + + if ((errno != 0) || (val < 0) || (val > 100)) + { + free(str); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + + settings->PercentScreen = val; + } } } @@ -1679,7 +1736,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, for (i = 0; i < settings->NumMonitorIds; i++) { - settings->MonitorIds[i] = atoi(p[i]); + unsigned long val = strtoul(p[i], NULL, 0); + + if ((errno != 0) || (val > UINT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->MonitorIds[i] = val; } free(p); @@ -1711,9 +1773,26 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if ((p = strchr(str, 'x'))) { + unsigned long w, h; *p = '\0'; - settings->SmartSizingWidth = atoi(str); - settings->SmartSizingHeight = atoi(&p[1]); + w = strtoul(str, NULL, 0); + + if ((errno != 0) || (w == 0) || (w > UINT16_MAX)) + { + free(str); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + + h = strtoul(&p[1], NULL, 0); + + if ((errno != 0) || (h == 0) || (h > UINT16_MAX)) + { + free(str); + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + + settings->SmartSizingWidth = w; + settings->SmartSizingHeight = h; } free(str); @@ -1721,7 +1800,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "bpp") { - settings->ColorDepth = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->ColorDepth = val; switch (settings->ColorDepth) { @@ -1763,7 +1847,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "kbd") { - unsigned long int id; + unsigned long id; char* pEnd; id = strtoul(arg->Value, &pEnd, 16); @@ -1772,33 +1856,49 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (id == 0) { - id = (unsigned long int) freerdp_map_keyboard_layout_name_to_id(arg->Value); + const int rc = freerdp_map_keyboard_layout_name_to_id(arg->Value); - if (id == -1) + if (rc < 0) WLog_ERR(TAG, "A problem occurred while mapping the layout name to id"); - else if (id == 0) + else if (rc == 0) { WLog_ERR(TAG, "Could not identify keyboard layout: %s", arg->Value); WLog_ERR(TAG, "Use /kbd-list to list available layouts"); } - if (id <= 0) + if (rc <= 0) return COMMAND_LINE_STATUS_PRINT; + id = rc; } settings->KeyboardLayout = (UINT32) id; } CommandLineSwitchCase(arg, "kbd-type") { - settings->KeyboardType = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->KeyboardType = val; } CommandLineSwitchCase(arg, "kbd-subtype") { - settings->KeyboardSubType = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->KeyboardSubType = val; } CommandLineSwitchCase(arg, "kbd-fn-key") { - settings->KeyboardFunctionKey = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->KeyboardFunctionKey = val; } CommandLineSwitchCase(arg, "u") { @@ -1828,8 +1928,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (p) { + unsigned long val = strtoul(&p[1], NULL, 0); + + if ((errno != 0) || (val == 0) || (val > UINT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; length = (int)(p - arg->Value); - settings->GatewayPort = atoi(&p[1]); + settings->GatewayPort = val; if (!(settings->GatewayHostname = (char*) calloc(length + 1UL, sizeof(char)))) return COMMAND_LINE_ERROR_MEMORY; @@ -1880,15 +1984,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (p) { - length = (int)(p - arg->Value); + unsigned long val = strtoul(&p[1], NULL, 0); - if (!isdigit(p[1])) - { - WLog_ERR(TAG, "Could not parse proxy port"); + if ((errno != 0) || (val == 0) || (val > UINT16_MAX)) return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; - } - settings->ProxyPort = atoi(&p[1]); + length = (p - arg->Value); + settings->ProxyPort = val; settings->ProxyHostname = (char*) malloc(length + 1); strncpy(settings->ProxyHostname, arg->Value, length); settings->ProxyHostname[length] = '\0'; @@ -1946,9 +2048,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "gateway-usage-method") { - int type; + long type; char* pEnd; type = strtol(arg->Value, &pEnd, 10); + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; if (type == 0) { @@ -2028,7 +2132,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "compression-level") { - settings->CompressionLevel = atoi(arg->Value); + unsigned long val = strtol(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->CompressionLevel = val; } CommandLineSwitchCase(arg, "drives") { @@ -2058,8 +2167,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "audio-mode") { - int mode; - mode = atoi(arg->Value); + long mode = strtol(arg->Value, NULL, 0); + + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; if (mode == AUDIO_MODE_REDIRECT) { @@ -2077,9 +2188,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "network") { - int type; + long type; char* pEnd; type = strtol(arg->Value, &pEnd, 10); + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; if (type == 0) { @@ -2144,7 +2257,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (arg->Value) { #ifdef WITH_GFX_H264 - if (_strnicmp("AVC444", arg->Value, 6) == 0) { settings->GfxH264 = TRUE; @@ -2163,10 +2275,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, CommandLineSwitchCase(arg, "gfx-thin-client") { settings->GfxThinClient = arg->Value ? TRUE : FALSE; - if (settings->GfxThinClient) settings->GfxSmallCache = TRUE; - settings->SupportGraphicsPipeline = TRUE; } CommandLineSwitchCase(arg, "gfx-small-cache") @@ -2210,7 +2320,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "frame-ack") { - settings->FrameAcknowledge = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->FrameAcknowledge = val; } CommandLineSwitchCase(arg, "nsc") { @@ -2224,7 +2339,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "jpeg-quality") { - settings->JpegQuality = atoi(arg->Value) % 100; + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > 100)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->JpegQuality = val; } #endif CommandLineSwitchCase(arg, "nego") @@ -2241,8 +2361,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "pcid") { + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; settings->SendPreconnectionPdu = TRUE; - settings->PreconnectionId = atoi(arg->Value); + settings->PreconnectionId = val; } CommandLineSwitchCase(arg, "sec") { @@ -2399,7 +2523,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "parent-window") { - settings->ParentWindowId = strtol(arg->Value, NULL, 0); + UINT64 val = _strtoui64(arg->Value, NULL, 0); + + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->ParentWindowId = val; } CommandLineSwitchCase(arg, "bitmap-cache") { @@ -2426,7 +2555,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, { settings->NSCodec = TRUE; } - #if defined(WITH_JPEG) else if (strcmp(arg->Value, "jpeg") == 0) { @@ -2435,7 +2563,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (settings->JpegQuality == 0) settings->JpegQuality = 75; } - #endif } CommandLineSwitchCase(arg, "fast-path") @@ -2445,11 +2572,21 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "max-fast-path-size") { - settings->MultifragMaxRequestSize = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->MultifragMaxRequestSize = val; } CommandLineSwitchCase(arg, "max-loop-time") { - settings->MaxTimeInCheckLoop = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->MaxTimeInCheckLoop = val; if ((long) settings->MaxTimeInCheckLoop < 0) { @@ -2504,7 +2641,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "auto-reconnect-max-retries") { - settings->AutoReconnectMaxRetries = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->AutoReconnectMaxRetries = val; if (settings->AutoReconnectMaxRetries > 1000) return COMMAND_LINE_ERROR; @@ -2540,19 +2682,37 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "pwidth") { - settings->DesktopPhysicalWidth = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->DesktopPhysicalWidth = val; } CommandLineSwitchCase(arg, "pheight") { - settings->DesktopPhysicalHeight = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->DesktopPhysicalHeight = val; } CommandLineSwitchCase(arg, "orientation") { - settings->DesktopOrientation = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > INT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->DesktopOrientation = val; } CommandLineSwitchCase(arg, "scale") { - int scaleFactor = atoi(arg->Value); + unsigned long scaleFactor = strtoul(arg->Value, NULL, 0); + + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; if (scaleFactor == 100 || scaleFactor == 140 || scaleFactor == 180) { @@ -2567,7 +2727,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "scale-desktop") { - int desktopScaleFactor = atoi(arg->Value); + unsigned long desktopScaleFactor = strtoul(arg->Value, NULL, 0); + + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; if (desktopScaleFactor >= 100 && desktopScaleFactor <= 500) { @@ -2581,7 +2744,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "scale-device") { - int deviceScaleFactor = atoi(arg->Value); + unsigned long deviceScaleFactor = strtoul(arg->Value, NULL, 0); + + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; if (deviceScaleFactor == 100 || deviceScaleFactor == 140 || deviceScaleFactor == 180) @@ -2660,7 +2826,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT) { - settings->ServerPort = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val == 0) || (val > UINT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->ServerPort = val; } arg = CommandLineFindArgumentA(args, "p"); diff --git a/client/common/compatibility.c b/client/common/compatibility.c index a95b6a3..154e7ff 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -23,6 +23,8 @@ #include "config.h" #endif +#include + #include #include @@ -94,35 +96,59 @@ COMMAND_LINE_ARGUMENT_A old_args[] = BOOL freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32* ServerPort) { char* p; + char* host = NULL; if (str[0] == '[' && (p = strchr(str, ']')) && (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':')))) { /* Either "[...]" or "[...]:..." with at most one : after the brackets */ - if (!(*ServerHostname = _strdup(str + 1))) + if (!(host = _strdup(str + 1))) return FALSE; - if ((p = strchr((char*) *ServerHostname, ']'))) + if ((p = strchr(host, ']'))) { *p = 0; if (p[1] == ':') - *ServerPort = atoi(p + 2); + { + unsigned long val; + errno = 0; + val = strtoul(p + 2, NULL, 0); + + if ((errno != 0) || (val == 0) || (val > UINT16_MAX)) + { + free(host); + return FALSE; + } + + *ServerPort = val; + } } } else { /* Port number is cut off and used if exactly one : in the string */ - if (!(*ServerHostname = _strdup(str))) + if (!(host = _strdup(str))) return FALSE; - if ((p = strchr((char*) *ServerHostname, ':')) && !strchr(p + 1, ':')) + if ((p = strchr(host, ':')) && !strchr(p + 1, ':')) { + unsigned long val; + errno = 0; + val = strtoul(p + 1, NULL, 0); + + if ((errno != 0) || (val == 0) || (val > UINT16_MAX)) + { + free(host); + return FALSE; + } + *p = 0; - *ServerPort = atoi(p + 1); + *ServerPort = val; } } + *ServerHostname = host; return TRUE; } @@ -205,7 +231,6 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args) return args_handled; } - int freerdp_client_old_command_line_pre_filter(void* context, int index, int argc, LPCSTR* argv) { rdpSettings* settings = (rdpSettings*) context; @@ -374,12 +399,10 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg return 0; } - int freerdp_client_old_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT_A* arg) { return 0; } - int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count) { int status; @@ -445,7 +468,6 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count) free(settings); return detect_status; } - int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSettings* settings) { char* p; @@ -481,6 +503,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe } arg = old_args; + errno = 0; do { @@ -495,7 +518,12 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe } CommandLineSwitchCase(arg, "a") { - settings->ColorDepth = atoi(arg->Value); + unsigned long val = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (val > INT8_MAX)) + return FALSE; + + settings->ColorDepth = val; WLog_WARN(TAG, "-a %s -> /bpp:%s", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "c") @@ -538,9 +566,25 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe if (p) { + unsigned long h, w = strtoul(str, NULL, 0); + + if ((errno != 0) || (w == 0) || (w > UINT16_MAX)) + { + free(str); + return FALSE; + } + + h = strtoul(&p[1], NULL, 0); + + if ((errno != 0) || (h == 0) || (h > UINT16_MAX)) + { + free(str); + return FALSE; + } + *p = '\0'; - settings->DesktopWidth = atoi(str); - settings->DesktopHeight = atoi(&p[1]); + settings->DesktopWidth = w; + settings->DesktopHeight = h; } free(str); @@ -587,7 +631,12 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe } CommandLineSwitchCase(arg, "t") { - settings->ServerPort = atoi(arg->Value); + unsigned long p = strtoul(arg->Value, NULL, 0); + + if ((errno != 0) || (p == 0) || (p > UINT16_MAX)) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + + settings->ServerPort = p; WLog_WARN(TAG, "-t %s -> /port:%s", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "u") @@ -599,10 +648,13 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe } CommandLineSwitchCase(arg, "x") { - int type; + long type; char* pEnd; type = strtol(arg->Value, &pEnd, 16); + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + if (type == 0) { type = CONNECTION_TYPE_LAN; @@ -635,7 +687,11 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe } CommandLineSwitchCase(arg, "X") { - settings->ParentWindowId = strtol(arg->Value, NULL, 0); + settings->ParentWindowId = _strtoui64(arg->Value, NULL, 0); + + if (errno != 0) + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + WLog_WARN(TAG, "-X %s -> /parent-window:%s", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "z") diff --git a/client/common/file.c b/client/common/file.c index ac39697..b26e704 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include #include @@ -222,7 +224,7 @@ static BOOL freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, const W const WCHAR* value, int index) { int length; - int ivalue; + long ivalue; char* nameA; char* valueA; BOOL ret = TRUE; @@ -245,9 +247,12 @@ static BOOL freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, const W WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); valueA[length] = '\0'; - ivalue = atoi(valueA); + errno = 0; + ivalue = strtol(valueA, NULL, 0); - if (freerdp_client_rdp_file_set_integer(file, nameA, ivalue, index) < 0) + if ((errno != 0) || (ivalue < INT32_MIN) || (ivalue > INT32_MAX)) + ret = FALSE; + else if (freerdp_client_rdp_file_set_integer(file, nameA, ivalue, index) < 0) ret = FALSE; free(nameA); @@ -258,7 +263,12 @@ static BOOL freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, const W static BOOL freerdp_client_parse_rdp_file_integer_ascii(rdpFile* file, const char* name, const char* value, int index) { - int ivalue = atoi(value); + long ivalue; + errno = 0; + ivalue = strtol(value, NULL, 0); + + if ((errno != 0) || (ivalue < INT32_MIN) || (ivalue > INT32_MAX)) + return FALSE; if (freerdp_client_rdp_file_set_integer(file, name, ivalue, index) < 0) return FALSE; diff --git a/client/iOS/FreeRDP/ios_freerdp.m b/client/iOS/FreeRDP/ios_freerdp.m index a2d01e8..7479ca5 100644 --- a/client/iOS/FreeRDP/ios_freerdp.m +++ b/client/iOS/FreeRDP/ios_freerdp.m @@ -21,6 +21,8 @@ #import "RDPSession.h" #import "Utils.h" +#include + #define TAG FREERDP_TAG("iOS") #pragma mark Connection helpers diff --git a/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c b/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c index 7370eb6..59d6ae5 100644 --- a/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c +++ b/libfreerdp/codec/test/TestFreeRDPCodecPlanar.c @@ -2964,7 +2964,6 @@ static BOOL RunTestPlanar(BITMAP_PLANAR_CONTEXT* planar, const BYTE* srcBitmap, const UINT32 width, const UINT32 height) { BOOL rc = FALSE; - const UINT32 size = width * height * GetBytesPerPixel(dstFormat); UINT32 dstSize; BYTE* compressedBitmap = freerdp_bitmap_compress_planar(planar, srcBitmap, srcFormat, width, height, 0, NULL, &dstSize); diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index 22248f6..027b273 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -78,7 +80,6 @@ int freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* k BYTE* buffer; BYTE pad1[64]; BYTE pad2[64]; - memset(pad1, 0x36, 64); memset(pad2, 0x5C, 64); @@ -100,11 +101,9 @@ int freerdp_assistance_crypt_derive_key_sha1(BYTE* hash, int hashLength, BYTE* k goto fail; CopyMemory(key, buffer, keyLength); - rc = 1; fail: free(buffer); - return rc; } @@ -117,7 +116,6 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) int count; int length; char** tokens; - count = 1; str = _strdup(list); @@ -133,6 +131,7 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) } tokens = (char**) calloc(count, sizeof(char*)); + if (!tokens) { free(str); @@ -161,7 +160,6 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) for (i = 0; i < count; i++) { p = tokens[i]; - q = strchr(p, ':'); if (!q) @@ -169,9 +167,16 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) q[0] = '\0'; q++; - file->MachineAddresses[i] = _strdup(p); - file->MachinePorts[i] = (UINT32) atoi(q); + errno = 0; + { + unsigned long val = strtoul(q, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + goto out; + + file->MachinePorts[i] = val; + } if (!file->MachineAddresses[i]) goto out; @@ -190,7 +195,6 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) } p = tokens[i]; - q = strchr(p, ':'); if (!q) @@ -201,10 +205,21 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) if (file->MachineAddress) free(file->MachineAddress); + file->MachineAddress = _strdup(p); + if (!file->MachineAddress) goto out; - file->MachinePort = (UINT32) atoi(q); + + errno = 0; + { + unsigned long val = strtoul(q, NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + goto out; + + file->MachinePort = val; + } if (!file->MachineAddress) goto out; @@ -216,18 +231,18 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list) free(str); return 1; out: + if (file->MachineAddresses) { - for (i=0; iMachineAddresses[i]); + for (i = 0; i < count; i++) + free(file->MachineAddresses[i]); } - free (file->MachineAddresses); - free (file->MachinePorts); + free(file->MachineAddresses); + free(file->MachinePorts); file->MachineCount = 0; file->MachinePorts = NULL; file->MachineAddresses = NULL; - free(tokens); free(str); return -1; @@ -241,12 +256,10 @@ int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file) int length; char* tokens[8]; int ret = -1; - /** * ,,,, * ,,, */ - count = 1; str = _strdup(file->RCTicket); @@ -302,7 +315,6 @@ int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file) goto error; ret = freerdp_assistance_parse_address_list(file, tokens[2]); - error: free(str); @@ -335,8 +347,6 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) char* end; char* p; int ret = -1; - - str = file->ConnectionString2; if (!strstr(str, "")) @@ -346,6 +356,7 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) return -1; str = _strdup(file->ConnectionString2); + if (!str) return -1; @@ -354,15 +365,16 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) /* Parse Auth String Node () */ end = strstr(tag, "/>"); + if (!end) goto out_fail; *end = '\0'; - p = strstr(tag, "KH=\""); + if (p) { - char *q; + char* q; size_t length; p += sizeof("KH=\"") - 1; q = strchr(p, '"'); @@ -373,6 +385,7 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) length = q - p; free(file->RASpecificParams); file->RASpecificParams = (char*) malloc(length + 1); + if (!file->RASpecificParams) goto out_fail; @@ -381,9 +394,10 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) } p = strstr(tag, "ID=\""); + if (p) { - char *q; + char* q; size_t length; p += sizeof("ID=\"") - 1; q = strchr(p, '"'); @@ -394,24 +408,24 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) length = q - p; free(file->RASessionId); file->RASessionId = (char*) malloc(length + 1); + if (!file->RASessionId) goto out_fail; CopyMemory(file->RASessionId, p, length); file->RASessionId[length] = '\0'; } - *end = '/'; + *end = '/'; /* Parse UINT16_MAX)) + goto out_fail; + port = val; + } p = strstr(q, " N=\""); if (!p) goto out_fail; p += sizeof(" N=\"") - 1; - q = strchr(p, '"'); if (!q) @@ -436,7 +455,6 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) q[0] = '\0'; q++; - length = strlen(p); if (length > 8) @@ -445,9 +463,12 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) { if (file->MachineAddress) free(file->MachineAddress); + file->MachineAddress = _strdup(p); + if (!file->MachineAddress) goto out_fail; + file->MachinePort = (UINT32) port; break; } @@ -460,7 +481,6 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) out_fail: free(str); return ret; - } char* freerdp_assistance_construct_expert_blob(const char* name, const char* pass) @@ -475,7 +495,6 @@ char* freerdp_assistance_construct_expert_blob(const char* name, const char* pas nameLength = strlen(name) + strlen("NAME="); passLength = strlen(pass) + strlen("PASS="); - size = nameLength + passLength + 64; ExpertBlob = (char*) calloc(1, size); @@ -483,8 +502,7 @@ char* freerdp_assistance_construct_expert_blob(const char* name, const char* pas return NULL; sprintf_s(ExpertBlob, size, "%d;NAME=%s%d;PASS=%s", - nameLength, name, passLength, pass); - + nameLength, name, passLength, pass); return ExpertBlob; } @@ -497,7 +515,6 @@ char* freerdp_assistance_generate_pass_stub(DWORD flags) char set3[10] = "0123456789"; char set4[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char set5[26] = "abcdefghijklmnopqrstuvwxyz"; - passStub = (char*) malloc(15); if (!passStub) @@ -514,9 +531,7 @@ char* freerdp_assistance_generate_pass_stub(DWORD flags) * * Example: WB^6HsrIaFmEpi */ - winpr_RAND((BYTE*) nums, sizeof(nums)); - passStub[0] = set1[nums[0] % sizeof(set1)]; /* character 0 */ passStub[1] = set2[nums[1] % sizeof(set2)]; /* character 1 */ passStub[2] = set3[nums[2] % sizeof(set3)]; /* character 2 */ @@ -532,11 +547,11 @@ char* freerdp_assistance_generate_pass_stub(DWORD flags) passStub[12] = set1[nums[12] % sizeof(set1)]; /* character 12 */ passStub[13] = set1[nums[13] % sizeof(set1)]; /* character 13 */ passStub[14] = '\0'; - return passStub; } -BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, int* pEncryptedSize) +BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, + int* pEncryptedSize) { BOOL rc; int status; @@ -549,7 +564,6 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas size_t cbOut, cbIn, cbFinal; WCHAR* PasswordW = NULL; WCHAR* PassStubW = NULL; - status = ConvertToUnicode(CP_UTF8, 0, password, -1, &PasswordW, 0); if (status <= 0) @@ -557,9 +571,10 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas cbPasswordW = (status - 1) * 2; - if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*) PasswordHash, sizeof(PasswordHash))) + if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*) PasswordHash, + sizeof(PasswordHash))) { - free (PasswordW); + free(PasswordW); return NULL; } @@ -567,14 +582,12 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas if (status <= 0) { - free (PasswordW); + free(PasswordW); return NULL; } cbPassStubW = (status - 1) * 2; - EncryptedSize = cbPassStubW + 4; - pbIn = (BYTE*) calloc(1, EncryptedSize); pbOut = (BYTE*) calloc(1, EncryptedSize); @@ -598,23 +611,21 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas *((UINT32*) pbIn) = cbPassStubW; CopyMemory(&pbIn[4], PassStubW, cbPassStubW); - free(PasswordW); free(PassStubW); - rc4Ctx = winpr_Cipher_New(WINPR_CIPHER_ARC4_128, WINPR_ENCRYPT, - PasswordHash, NULL); + PasswordHash, NULL); + if (!rc4Ctx) { WLog_ERR(TAG, "EVP_CipherInit_ex failure"); - free (pbOut); - free (pbIn); + free(pbOut); + free(pbIn); return NULL; } cbOut = cbFinal = 0; cbIn = EncryptedSize; - rc = winpr_Cipher_Update(rc4Ctx, pbIn, cbIn, pbOut, &cbOut); free(pbIn); @@ -622,7 +633,7 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas { WLog_ERR(TAG, "EVP_CipherUpdate failure"); winpr_Cipher_Free(rc4Ctx); - free (pbOut); + free(pbOut); return NULL; } @@ -630,14 +641,12 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas { WLog_ERR(TAG, "EVP_CipherFinal_ex failure"); winpr_Cipher_Free(rc4Ctx); - free (pbOut); + free(pbOut); return NULL; } winpr_Cipher_Free(rc4Ctx); - *pEncryptedSize = EncryptedSize; - return pbOut; } @@ -654,7 +663,6 @@ int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password) BYTE DerivedKey[WINPR_AES_BLOCK_SIZE]; BYTE InitializationVector[WINPR_AES_BLOCK_SIZE]; BYTE PasswordHash[WINPR_SHA1_DIGEST_LENGTH]; - status = ConvertToUnicode(CP_UTF8, 0, password, -1, &PasswordW, 0); if (status <= 0) @@ -664,12 +672,12 @@ int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password) if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash, sizeof(PasswordHash))) { - free (PasswordW); + free(PasswordW); return -1; } status = freerdp_assistance_crypt_derive_key_sha1(PasswordHash, sizeof(PasswordHash), - DerivedKey, sizeof(DerivedKey)); + DerivedKey, sizeof(DerivedKey)); if (status < 0) { @@ -678,9 +686,9 @@ int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password) } ZeroMemory(InitializationVector, sizeof(InitializationVector)); - aesDec = winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, - DerivedKey, InitializationVector); + DerivedKey, InitializationVector); + if (!aesDec) { free(PasswordW); @@ -717,16 +725,12 @@ int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password) } winpr_Cipher_Free(aesDec); - cbOut += cbFinal; cbFinal = 0; - pbOutW = (WCHAR*) pbOut; cchOutW = cbOut / 2; - file->ConnectionString2 = NULL; status = ConvertFromUnicode(CP_UTF8, 0, pbOutW, cchOutW, &file->ConnectionString2, 0, NULL, NULL); - free(PasswordW); free(pbOut); @@ -743,9 +747,8 @@ int freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* password) int freerdp_assistance_decrypt(rdpAssistanceFile* file, const char* password) { int status = 1; - file->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(password, - file->PassStub, &file->EncryptedPassStubLength); + file->PassStub, &file->EncryptedPassStubLength); if (!file->EncryptedPassStub) return -1; @@ -764,7 +767,6 @@ BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size) int length; BYTE* buffer; int i, ln, hn; - length = strlen(str); if ((length % 2) != 0) @@ -772,7 +774,6 @@ BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size) length /= 2; *size = length; - buffer = (BYTE*) malloc(length); if (!buffer) @@ -781,7 +782,6 @@ BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size) for (i = 0; i < length; i++) { hn = ln = 0; - c = str[(i * 2) + 0]; if ((c >= '0') && (c <= '9')) @@ -812,8 +812,8 @@ char* freerdp_assistance_bin_to_hex_string(const BYTE* data, int size) char* p; int ln, hn; char bin2hex[] = "0123456789ABCDEF"; - p = (char*) calloc((size + 1), 2); + if (!p) return NULL; @@ -821,13 +821,11 @@ char* freerdp_assistance_bin_to_hex_string(const BYTE* data, int size) { ln = data[i] & 0xF; hn = (data[i] >> 4) & 0xF; - p[i * 2] = bin2hex[hn]; p[(i * 2) + 1] = bin2hex[ln]; } p[size * 2] = '\0'; - return p; } @@ -836,10 +834,8 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu char* p; char* q; char* r; - int value; int status; size_t length; - p = strstr(buffer, "UPLOADINFO"); if (!p) @@ -856,7 +852,6 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu return -1; /* Parse USERNAME */ - p = strstr(buffer, "USERNAME=\""); if (p) @@ -878,7 +873,6 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu } /* Parse LHTICKET */ - p = strstr(buffer, "LHTICKET=\""); if (p) @@ -900,7 +894,6 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu } /* Parse RCTICKET */ - p = strstr(buffer, "RCTICKET=\""); if (p) @@ -922,7 +915,6 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu } /* Parse RCTICKETENCRYPTED */ - p = strstr(buffer, "RCTICKETENCRYPTED=\""); if (p) @@ -940,7 +932,6 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu } /* Parse PassStub */ - p = strstr(buffer, "PassStub=\""); if (p) @@ -962,7 +953,6 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu } /* Parse DtStart */ - p = strstr(buffer, "DtStart=\""); if (p) @@ -974,7 +964,6 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu return -1; length = q - p; - r = (char*) malloc(length + 1); if (!r) @@ -982,18 +971,19 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu CopyMemory(r, p, length); r[length] = '\0'; + errno = 0; + { + unsigned long val = strtoul(r, NULL, 0); + free(r); - value = atoi(r); - free(r); - - if (value < 0) - return -1; + if ((errno != 0) || (val > UINT32_MAX)) + return -1; - file->DtStart = (UINT32) value; + file->DtStart = val; + } } /* Parse DtLength */ - p = strstr(buffer, "DtLength=\""); if (p) @@ -1005,7 +995,6 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu return -1; length = q - p; - r = (char*) malloc(length + 1); if (!r) @@ -1013,18 +1002,19 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu CopyMemory(r, p, length); r[length] = '\0'; + errno = 0; + { + unsigned long val = strtoul(r, NULL, 0); + free(r); - value = atoi(r); - free(r); - - if (value < 0) - return -1; + if ((errno != 0) || (val > UINT32_MAX)) + return -1; - file->DtLength = (UINT32) value; + file->DtLength = val; + } } /* Parse L (LowSpeed) */ - p = strstr(buffer, " L=\""); if (p) @@ -1046,7 +1036,7 @@ int freerdp_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* bu if (file->LHTicket) { file->EncryptedLHTicket = freerdp_assistance_hex_string_to_bin(file->LHTicket, - &file->EncryptedLHTicketLength); + &file->EncryptedLHTicketLength); } status = freerdp_assistance_parse_connection_string1(file); @@ -1067,7 +1057,6 @@ int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name) FILE* fp = NULL; size_t readSize; INT64 fileSize; - fp = fopen(name, "r"); if (!fp) @@ -1098,6 +1087,7 @@ int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name) if (!ferror(fp)) readSize = fileSize; } + fclose(fp); if (readSize < 1) @@ -1109,18 +1099,15 @@ int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name) buffer[fileSize] = '\0'; buffer[fileSize + 1] = '\0'; - status = freerdp_assistance_parse_file_buffer(file, (char*) buffer, fileSize); - free(buffer); - return status; } -int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file, rdpSettings* settings) +int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file, + rdpSettings* settings) { UINT32 i; - freerdp_set_param_bool(settings, FreeRDP_RemoteAssistanceMode, TRUE); if (!file->RASessionId || !file->MachineAddress) @@ -1129,19 +1116,19 @@ int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* fil if (freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceSessionId, file->RASessionId) != 0) return -1; - if (file->RCTicket && (freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceRCTicket, file->RCTicket) != 0)) + if (file->RCTicket && + (freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceRCTicket, file->RCTicket) != 0)) return -1; - if (file->PassStub && (freerdp_set_param_string(settings, FreeRDP_RemoteAssistancePassStub, file->PassStub) != 0)) + if (file->PassStub && + (freerdp_set_param_string(settings, FreeRDP_RemoteAssistancePassStub, file->PassStub) != 0)) return -1; if (freerdp_set_param_string(settings, FreeRDP_ServerHostname, file->MachineAddress) != 0) return -1; freerdp_set_param_uint32(settings, FreeRDP_ServerPort, file->MachinePort); - freerdp_target_net_addresses_free(settings); - settings->TargetNetAddressCount = file->MachineCount; if (settings->TargetNetAddressCount) @@ -1196,6 +1183,5 @@ void freerdp_assistance_file_free(rdpAssistanceFile* file) free(file->MachineAddresses); free(file->MachinePorts); - free(file); } diff --git a/libfreerdp/core/gateway/http.c b/libfreerdp/core/gateway/http.c index 4fd190d..ff7a981 100644 --- a/libfreerdp/core/gateway/http.c +++ b/libfreerdp/core/gateway/http.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -52,12 +54,12 @@ static char* string_strnstr(const char* str1, const char* str2, size_t slen) if (slen-- < 1 || (sc = *str1++) == '\0') return NULL; } - while(sc != c); + while (sc != c); if (len > slen) return NULL; } - while(strncmp(str1, str2, len) != 0); + while (strncmp(str1, str2, len) != 0); str1--; } @@ -258,7 +260,6 @@ char* http_encode_body_line(char* param, char* value) { char* line; int length; - length = strlen(param) + strlen(value) + 2; line = (char*) malloc(length + 1); @@ -274,7 +275,6 @@ char* http_encode_content_length_line(int ContentLength) char* line; int length; char str[32]; - _itoa_s(ContentLength, str, sizeof(str), 10); length = strlen("Content-Length") + strlen(str) + 2; line = (char*) malloc(length + 1); @@ -290,7 +290,6 @@ char* http_encode_header_line(char* Method, char* URI) { char* line; int length; - length = strlen("HTTP/1.1") + strlen(Method) + strlen(URI) + 2; line = (char*)malloc(length + 1); @@ -305,7 +304,6 @@ char* http_encode_authorization_line(char* AuthScheme, char* AuthParam) { char* line; int length; - length = strlen("Authorization") + strlen(AuthScheme) + strlen(AuthParam) + 3; line = (char*) malloc(length + 1); @@ -322,7 +320,6 @@ wStream* http_request_write(HttpContext* context, HttpRequest* request) int i, count; char** lines; int length = 0; - count = 0; lines = (char**) calloc(32, sizeof(char*)); @@ -409,8 +406,8 @@ wStream* http_request_write(HttpContext* context, HttpRequest* request) Stream_Rewind(s, 1); /* don't include null terminator in length */ Stream_SetLength(s, Stream_GetPosition(s)); return s; - out_free: + for (i = 0; i < count; i++) free(lines[i]); @@ -458,7 +455,15 @@ BOOL http_response_parse_header_status_line(HttpResponse* response, char* status reason_phrase = separator + 1; *separator = '\0'; - response->StatusCode = atoi(status_code); + errno = 0; + { + long val = strtol(status_code, NULL, 0); + + if ((errno != 0) || (val < 0) || (val > INT16_MAX)) + return FALSE; + + response->StatusCode = strtol(status_code, NULL, 0); + } response->ReasonPhrase = _strdup(reason_phrase); if (!response->ReasonPhrase) @@ -474,7 +479,14 @@ BOOL http_response_parse_header_field(HttpResponse* response, char* name, char* if (_stricmp(name, "Content-Length") == 0) { - response->ContentLength = atoi(value); + long val; + errno = 0; + val = strtol(value, NULL, 0); + + if ((errno != 0) || (val < 0) || (val > INT32_MAX)) + return FALSE; + + response->ContentLength = val; } else if (_stricmp(name, "Content-Type") == 0) { @@ -488,7 +500,6 @@ BOOL http_response_parse_header_field(HttpResponse* response, char* name, char* char* separator = NULL; char* authScheme = NULL; char* authValue = NULL; - separator = strchr(value, ' '); if (separator) @@ -551,6 +562,7 @@ BOOL http_response_parse_header(HttpResponse* response) for (count = 1; count < response->count; count++) { line = response->lines[count]; + /** * name end_of_header * | | @@ -624,18 +636,15 @@ HttpResponse* http_response_recv(rdpTls* tls) int bodyLength; int payloadOffset; HttpResponse* response; - size = 2048; payload = NULL; payloadOffset = 0; - s = Stream_New(NULL, size); if (!s) goto out_free; buffer = (char*) Stream_Buffer(s); - response = http_response_new(); if (!response) @@ -661,13 +670,13 @@ HttpResponse* http_response_recv(rdpTls* tls) #ifdef HAVE_VALGRIND_MEMCHECK_H VALGRIND_MAKE_MEM_DEFINED(Stream_Pointer(s), status); #endif - Stream_Seek(s, status); if (Stream_GetRemainingLength(s) < 1024) { if (!Stream_EnsureRemainingCapacity(s, 1024)) goto out_error; + buffer = (char*) Stream_Buffer(s); payload = &buffer[payloadOffset]; } @@ -690,7 +699,6 @@ HttpResponse* http_response_recv(rdpTls* tls) { count = 0; line = buffer; - position = Stream_GetPosition(s); while ((line = string_strnstr(line, "\r\n", payloadOffset - (line - buffer) - 2))) @@ -717,7 +725,6 @@ HttpResponse* http_response_recv(rdpTls* tls) CopyMemory(header, buffer, payloadOffset); header[payloadOffset - 1] = '\0'; header[payloadOffset - 2] = '\0'; - count = 0; line = strtok(header, "\r\n"); @@ -736,7 +743,6 @@ HttpResponse* http_response_recv(rdpTls* tls) goto out_error; response->BodyLength = Stream_GetPosition(s) - payloadOffset; - bodyLength = 0; /* expected body length */ if (response->ContentType) @@ -772,7 +778,6 @@ HttpResponse* http_response_recv(rdpTls* tls) Stream_Seek(s, status); response->BodyLength += status; - } if (response->BodyLength > 0) @@ -789,7 +794,7 @@ HttpResponse* http_response_recv(rdpTls* tls) if (bodyLength != response->BodyLength) { WLog_WARN(TAG, "http_response_recv: %s unexpected body length: actual: %d, expected: %d", - response->ContentType, bodyLength, response->BodyLength); + response->ContentType, bodyLength, response->BodyLength); } break; @@ -799,6 +804,7 @@ HttpResponse* http_response_recv(rdpTls* tls) { if (!Stream_EnsureRemainingCapacity(s, 1024)) goto out_error; + buffer = (char*) Stream_Buffer(s); payload = &buffer[payloadOffset]; } @@ -823,6 +829,7 @@ HttpResponse* http_response_new() return NULL; response->Authenticates = ListDictionary_New(FALSE); + if (!response->Authenticates) { free(response); @@ -831,10 +838,8 @@ HttpResponse* http_response_new() ListDictionary_KeyObject(response->Authenticates)->fnObjectEquals = strings_equals_nocase; ListDictionary_KeyObject(response->Authenticates)->fnObjectFree = string_free; - ListDictionary_ValueObject(response->Authenticates)->fnObjectEquals = strings_equals_nocase; ListDictionary_ValueObject(response->Authenticates)->fnObjectFree = string_free; - return response; } @@ -851,9 +856,7 @@ void http_response_free(HttpResponse* response) free(response->lines); free(response->ReasonPhrase); - free(response->ContentType); - ListDictionary_Free(response->Authenticates); if (response->BodyContent) diff --git a/libfreerdp/core/listener.c b/libfreerdp/core/listener.c index 43cb131..6598d9e 100644 --- a/libfreerdp/core/listener.c +++ b/libfreerdp/core/listener.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -63,7 +64,6 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a #ifdef _WIN32 u_long arg; #endif - hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -108,7 +108,6 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a sin_addr = &(((struct sockaddr_in6*) ai->ai_addr)->sin6_addr); inet_ntop(ai->ai_family, sin_addr, addr, sizeof(addr)); - option_value = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &option_value, sizeof(option_value)) == -1) @@ -120,7 +119,6 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a arg = 1; ioctlsocket(sockfd, FIONBIO, &arg); #endif - status = _bind((SOCKET) sockfd, ai->ai_addr, ai->ai_addrlen); if (status != 0) @@ -139,22 +137,21 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a } /* FIXME: these file descriptors do not work on Windows */ - listener->sockfds[listener->num_sockfds] = sockfd; listener->events[listener->num_sockfds] = WSACreateEvent(); + if (!listener->events[listener->num_sockfds]) { listener->num_sockfds = 0; break; } + WSAEventSelect(sockfd, listener->events[listener->num_sockfds], FD_READ | FD_ACCEPT | FD_CLOSE); listener->num_sockfds++; - WLog_INFO(TAG, "Listening on %s:%s", addr, servname); } freeaddrinfo(res); - return (listener->num_sockfds > 0 ? TRUE : FALSE); } @@ -182,10 +179,8 @@ static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* } fcntl(sockfd, F_SETFL, O_NONBLOCK); - addr.sun_family = AF_UNIX; strncpy(addr.sun_path, path, sizeof(addr.sun_path)); - unlink(path); status = _bind(sockfd, (struct sockaddr*) &addr, sizeof(addr)); @@ -206,6 +201,7 @@ static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* } hevent = CreateFileDescriptorEvent(NULL, FALSE, FALSE, sockfd, WINPR_FD_READ); + if (!hevent) { WLog_ERR(TAG, "failed to create sockfd event"); @@ -239,25 +235,22 @@ static BOOL freerdp_listener_open_from_socket(freerdp_listener* instance, int fd listener->sockfds[listener->num_sockfds] = fd; listener->events[listener->num_sockfds] = - CreateFileDescriptorEvent(NULL, FALSE, FALSE, fd, WINPR_FD_READ); + CreateFileDescriptorEvent(NULL, FALSE, FALSE, fd, WINPR_FD_READ); + if (!listener->events[listener->num_sockfds]) return FALSE; listener->num_sockfds++; - WLog_INFO(TAG, "Listening on socket %d.", fd); return TRUE; #else return FALSE; #endif - - } static void freerdp_listener_close(freerdp_listener* instance) { int i; - rdpListener* listener = (rdpListener*) instance->listener; for (i = 0; i < listener->num_sockfds; i++) @@ -323,7 +316,6 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) for (i = 0; i < listener->num_sockfds; i++) { WSAResetEvent(listener->events[i]); - peer_addr_size = sizeof(peer_addr); peer_sockfd = _accept(listener->sockfds[i], (struct sockaddr*) &peer_addr, &peer_addr_size); peer_accepted = FALSE; @@ -336,17 +328,20 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) /* No data available */ if (wsa_error == WSAEWOULDBLOCK) continue; + #else + if (errno == EAGAIN || errno == EWOULDBLOCK) continue; + #endif WLog_DBG(TAG, "accept"); - free(client); return FALSE; } client = freerdp_peer_new(peer_sockfd); + if (!client) { closesocket((SOCKET) peer_sockfd); @@ -354,21 +349,26 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) } sin_addr = NULL; + if (peer_addr.ss_family == AF_INET) { sin_addr = &(((struct sockaddr_in*) &peer_addr)->sin_addr); + if ((*(UINT32*) sin_addr) == 0x0100007f) client->local = TRUE; } else if (peer_addr.ss_family == AF_INET6) { sin_addr = &(((struct sockaddr_in6*) &peer_addr)->sin6_addr); + if (memcmp(sin_addr, localhost6_bytes, 16) == 0) client->local = TRUE; } + #ifndef _WIN32 else if (peer_addr.ss_family == AF_UNIX) client->local = TRUE; + #endif if (sin_addr) @@ -391,7 +391,6 @@ freerdp_listener* freerdp_listener_new(void) { freerdp_listener* instance; rdpListener* listener; - instance = (freerdp_listener*) calloc(1, sizeof(freerdp_listener)); if (!instance) @@ -404,25 +403,21 @@ freerdp_listener* freerdp_listener_new(void) instance->GetEventHandles = freerdp_listener_get_event_handles; instance->CheckFileDescriptor = freerdp_listener_check_fds; instance->Close = freerdp_listener_close; - listener = (rdpListener*) calloc(1, sizeof(rdpListener)); if (!listener) { - free (instance); + free(instance); return NULL; } listener->instance = instance; - instance->listener = (void*) listener; - return instance; } void freerdp_listener_free(freerdp_listener* instance) { - if (instance) { free(instance->listener); diff --git a/libfreerdp/core/proxy.c b/libfreerdp/core/proxy.c index 4835477..6c98471 100644 --- a/libfreerdp/core/proxy.c +++ b/libfreerdp/core/proxy.c @@ -18,6 +18,7 @@ */ #include +#include #include "proxy.h" #include "freerdp/settings.h" @@ -109,13 +110,14 @@ BOOL proxy_parse_uri(rdpSettings* settings, const char* uri) if (pport) { - if (!isdigit(*(pport + 1))) - { - WLog_ERR(TAG, "Could not parse proxy port"); + long val; + errno = 0; + val = strtol(pport + 1, NULL, 0); + + if ((errno != 0) || (val <= 0) || (val > UINT16_MAX)) return FALSE; - } - port = atoi(pport + 1); + port = val; } else { diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index c415763..034e233 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -234,7 +235,6 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) int status = -1; BIO_RDP_TLS* tls = (BIO_RDP_TLS*) BIO_get_data(bio); - if (!tls) return 0; @@ -340,6 +340,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) break; case BIO_CTRL_POP: + /* Only detach if we are the BIO explicitly being popped */ if (bio == ptr) { @@ -347,8 +348,10 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) BIO_free_all(ssl_wbio); #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + if (next_bio) CRYPTO_add(&(bio->next_bio->references), -1, CRYPTO_LOCK_BIO); + tls->ssl->wbio = tls->ssl->rbio = NULL; #else /* OpenSSL 1.1: This will also clear the reference we obtained during push */ @@ -392,7 +395,6 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) } BIO_set_init(bio, 1); - status = 1; break; @@ -437,16 +439,13 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) static int bio_rdp_tls_new(BIO* bio) { BIO_RDP_TLS* tls; - BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); if (!(tls = calloc(1, sizeof(BIO_RDP_TLS)))) return 0; InitializeCriticalSectionAndSpinCount(&tls->lock, 4000); - BIO_set_data(bio, (void*) tls); - return 1; } @@ -469,6 +468,7 @@ static int bio_rdp_tls_free(BIO* bio) SSL_shutdown(tls->ssl); SSL_free(tls->ssl); } + BIO_set_init(bio, 0); BIO_set_flags(bio, 0); } @@ -1016,12 +1016,12 @@ BOOL tls_send_alert(rdpTls* tls) if (!tls->ssl) return TRUE; -/** - * FIXME: The following code does not work on OpenSSL > 1.1.0 because the - * SSL struct is opaqe now - */ - + /** + * FIXME: The following code does not work on OpenSSL > 1.1.0 because the + * SSL struct is opaqe now + */ #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + if (tls->alertDescription != TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY) { /** @@ -1035,7 +1035,6 @@ BOOL tls_send_alert(rdpTls* tls) */ SSL_SESSION* ssl_session = SSL_get_session(tls->ssl); SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(tls->ssl); - SSL_set_quiet_shutdown(tls->ssl, 1); if ((tls->alertLevel == TLS_ALERT_LEVEL_FATAL) && (ssl_session)) @@ -1048,8 +1047,8 @@ BOOL tls_send_alert(rdpTls* tls) if (tls->ssl->s3->wbuf.left == 0) tls->ssl->method->ssl_dispatch_alert(tls->ssl); } -#endif +#endif return TRUE; } diff --git a/libfreerdp/locale/keyboard_sun.c b/libfreerdp/locale/keyboard_sun.c index 111abf7..57fa9dc 100644 --- a/libfreerdp/locale/keyboard_sun.c +++ b/libfreerdp/locale/keyboard_sun.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -210,8 +211,8 @@ int freerdp_get_solaris_keyboard_layout_and_type(int* type, int* layout) char* pch; char* beg; char* end; + int rc = -1; char buffer[1024]; - /* Sample output for "kbd -t -l" : @@ -221,10 +222,8 @@ int freerdp_get_solaris_keyboard_layout_and_type(int* type, int* layout) delay(ms)=500 rate(ms)=40 */ - *type = 0; *layout = 0; - kbd = popen("kbd -t -l", "r"); if (!kbd) @@ -232,25 +231,40 @@ int freerdp_get_solaris_keyboard_layout_and_type(int* type, int* layout) while (fgets(buffer, sizeof(buffer), kbd) != NULL) { + long val; + if ((pch = strstr(buffer, "type=")) != NULL) { beg = pch + sizeof("type=") - 1; end = strchr(beg, '\n'); end[0] = '\0'; - *type = atoi(beg); + errno = 0; + val = strtol(beg, NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + goto fail; + + *type = val; } else if ((pch = strstr(buffer, "layout=")) != NULL) { beg = pch + sizeof("layout=") - 1; end = strchr(beg, ' '); end[0] = '\0'; - *layout = atoi(beg); + errno = 0; + val = strtol(beg, NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + goto fail; + + *layout = val; } } + rc = 0; +fail: pclose(kbd); - - return 0; + return rc; } DWORD freerdp_detect_solaris_keyboard_layout() diff --git a/rdtk/librdtk/rdtk_font.c b/rdtk/librdtk/rdtk_font.c index aac7f3e..97a13f1 100644 --- a/rdtk/librdtk/rdtk_font.c +++ b/rdtk/librdtk/rdtk_font.c @@ -20,6 +20,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -274,7 +276,15 @@ static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int s return -1; *q = '\0'; - font->size = atoi(p); + errno = 0; + { + long val = strtol(p, NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + font->size = val; + } *q = '"'; if (font->size <= 0) @@ -314,7 +324,15 @@ static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int s return -1; *q = '\0'; - font->height = atoi(p); + errno = 0; + { + long val = strtol(p, NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + font->height = val; + } *q = '"'; if (font->height <= 0) @@ -406,7 +424,15 @@ static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int s return -1; *q = '\0'; - glyph->width = atoi(p); + errno = 0; + { + long val = strtoul(p, NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + glyph->width = val; + } *q = '"'; if (glyph->width < 0) @@ -434,8 +460,23 @@ static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int s *p = 0; tok[1] = p + 1; - glyph->offsetX = atoi(tok[0]); - glyph->offsetY = atoi(tok[1]); + errno = 0; + { + long val = strtol(tok[0], NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + glyph->offsetX = val; + } + { + long val = strtol(tok[1], NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + glyph->offsetY = val; + } *q = '"'; p = q + 1; /* parse glyph rect x,y,w,h */ @@ -473,10 +514,39 @@ static int rdtk_font_parse_descriptor_buffer(rdtkFont* font, BYTE* buffer, int s *p = 0; tok[3] = p + 1; - glyph->rectX = atoi(tok[0]); - glyph->rectY = atoi(tok[1]); - glyph->rectWidth = atoi(tok[2]); - glyph->rectHeight = atoi(tok[3]); + errno = 0; + { + long val = strtol(tok[0], NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + glyph->rectX = val; + } + { + long val = strtol(tok[1], NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + glyph->rectY = val; + } + { + long val = strtol(tok[2], NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + glyph->rectWidth = val; + } + { + long val = strtol(tok[3], NULL, 0); + + if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX)) + return -1; + + glyph->rectHeight = val; + } *q = '"'; p = q + 1; /* parse code */ @@ -514,7 +584,6 @@ static int rdtk_font_load_descriptor(rdtkFont* font, const char* filename) return rdtk_font_parse_descriptor_buffer(font, (BYTE*) buffer, size); } - rdtkFont* rdtk_font_new(rdtkEngine* engine, const char* path, const char* file) { int status; @@ -589,7 +658,6 @@ cleanup: return NULL; } - static rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, BYTE* imageData, int imageSize, BYTE* descriptorData, int descriptorSize) { @@ -643,7 +711,6 @@ static rdtkFont* rdtk_embedded_font_new(rdtkEngine* engine, BYTE* imageData, int return font; } - void rdtk_font_free(rdtkFont* font) { if (font) @@ -655,7 +722,6 @@ void rdtk_font_free(rdtkFont* font) free(font); } } - int rdtk_font_engine_init(rdtkEngine* engine) { if (!engine->font) @@ -676,7 +742,6 @@ int rdtk_font_engine_init(rdtkEngine* engine) return 1; } - int rdtk_font_engine_uninit(rdtkEngine* engine) { if (engine->font) diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index c60a229..9d7f7aa 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -735,7 +735,8 @@ static BOOL tf_peer_suppress_output(rdpContext* context, BYTE allow, { if (allow > 0) { - WLog_DBG(TAG, "Client restore output (%"PRIu16", %"PRIu16") (%"PRIu16", %"PRIu16").", area->left, area->top, + WLog_DBG(TAG, "Client restore output (%"PRIu16", %"PRIu16") (%"PRIu16", %"PRIu16").", area->left, + area->top, area->right, area->bottom); } else @@ -889,8 +890,9 @@ int main(int argc, char* argv[]) freerdp_listener* instance; char* file; char name[MAX_PATH]; - int port = 3389, i; + long port = 3389, i; BOOL localOnly = FALSE; + errno = 0; for (i = 1; i < argc; i++) { @@ -907,7 +909,7 @@ int main(int argc, char* argv[]) port = strtol(arg, NULL, 10); - if ((port < 1) || (port > 0xFFFF)) + if ((port < 1) || (port > 0xFFFF) || (errno != 0)) return -1; } else if (strcmp(arg, "--local-only")) diff --git a/server/Windows/cli/wfreerdp.c b/server/Windows/cli/wfreerdp.c index 0b7c2f7..edcd23a 100644 --- a/server/Windows/cli/wfreerdp.c +++ b/server/Windows/cli/wfreerdp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -40,10 +41,9 @@ int IDcount = 0; BOOL CALLBACK moncb(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { WLog_DBG(TAG, "%d\t(%ld, %ld), (%ld, %ld)", - IDcount, lprcMonitor->left, lprcMonitor->top, - lprcMonitor->right, lprcMonitor->bottom); + IDcount, lprcMonitor->left, lprcMonitor->top, + lprcMonitor->right, lprcMonitor->bottom); IDcount++; - return TRUE; } @@ -52,13 +52,12 @@ int main(int argc, char* argv[]) BOOL screen_selected = FALSE; int index; wfServer* server; - server = wfreerdp_server_new(); - set_screen_id(0); - //handle args index = 1; + errno = 0; + while (index < argc) { //first the args that will cause the program to terminate @@ -72,11 +71,11 @@ int main(int argc, char* argv[]) WLog_INFO(TAG, "Detecting screens..."); WLog_INFO(TAG, "ID\tResolution\t\tName (Interface)"); - for (i=0; ; i++) + for (i = 0; ; i++) { if (get_screen_info(i, name, &width, &height, &bpp) != 0) { - if ( (width * height * bpp) == 0 ) + if ((width * height * bpp) == 0) continue; WLog_INFO(TAG, "%d\t%dx%dx%d\t", i, width, height, bpp); @@ -101,24 +100,36 @@ int main(int argc, char* argv[]) return 0; } - + if (strcmp("--screen", argv[index]) == 0) { + UINT32 val; screen_selected = TRUE; index++; + if (index == argc) { WLog_INFO(TAG, "missing screen id parameter"); return 0; } - set_screen_id(atoi(argv[index])); + val = strtoul(argv[index], NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return -1; + + set_screen_id(val); index++; } if (index == argc - 1) { - server->port = (DWORD) atoi(argv[index]); + UINT32 val = strtoul(argv[index], NULL, 0); + + if ((errno != 0) || (val > UINT32_MAX)) + return -1; + + server->port = val; break; } } @@ -134,11 +145,11 @@ int main(int argc, char* argv[]) WLog_INFO(TAG, "Detecting screens..."); WLog_INFO(TAG, "ID\tResolution\t\tName (Interface)"); - for (i=0; ; i++) + for (i = 0; ; i++) { if (get_screen_info(i, name, &width, &height, &bpp) != 0) { - if ( (width * height * bpp) == 0 ) + if ((width * height * bpp) == 0) continue; WLog_INFO(TAG, "%d\t%dx%dx%d\t", i, width, height, bpp); @@ -155,11 +166,9 @@ int main(int argc, char* argv[]) WLog_INFO(TAG, "Starting server"); wfreerdp_server_start(server); - WaitForSingleObject(server->thread, INFINITE); WLog_INFO(TAG, "Stopping server"); wfreerdp_server_stop(server); wfreerdp_server_free(server); - return 0; } diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c index 2c0e0bf..899bd30 100644 --- a/server/shadow/shadow_server.c +++ b/server/shadow/shadow_server.c @@ -22,6 +22,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -172,6 +174,7 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a return status; arg = shadow_args; + errno = 0; do { @@ -181,7 +184,12 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a CommandLineSwitchStart(arg) CommandLineSwitchCase(arg, "port") { - server->port = (DWORD) atoi(arg->Value); + long val = strtol(arg->Value, NULL, 0); + + if ((errno != 0) || (val <= 0) || (val > UINT16_MAX)) + return -1; + + server->port = (DWORD) val; } CommandLineSwitchCase(arg, "ipc-socket") { @@ -202,7 +210,7 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a { char* p; char* tok[4]; - int x, y, w, h; + long x = -1, y = -1, w = -1, h = -1; char* str = _strdup(arg->Value); if (!str) @@ -239,13 +247,30 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a *p++ = '\0'; tok[3] = p; - x = atoi(tok[0]); - y = atoi(tok[1]); - w = atoi(tok[2]); - h = atoi(tok[3]); + x = strtol(tok[0], NULL, 0); + + if (errno != 0) + goto fail; + + y = strtol(tok[1], NULL, 0); + + if (errno != 0) + goto fail; + + w = strtol(tok[2], NULL, 0); + + if (errno != 0) + goto fail; + + h = strtol(tok[3], NULL, 0); + + if (errno != 0) + goto fail; + + fail: free(str); - if ((x < 0) || (y < 0) || (w < 1) || (h < 1)) + if ((x < 0) || (y < 0) || (w < 1) || (h < 1) || (errno != 0)) return -1; server->subRect.left = x; @@ -333,15 +358,15 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) { /* Select monitors */ - index = atoi(arg->Value); + long val = strtol(arg->Value, NULL, 0); - if (index < 0) + if ((val < 0) || (errno != 0)) index = 0; - if (index >= numMonitors) + if (val >= numMonitors) index = 0; - server->selectedMonitor = index; + server->selectedMonitor = val; } else { diff --git a/winpr/include/winpr/crt.h b/winpr/include/winpr/crt.h index 25e9b79..397f7e4 100644 --- a/winpr/include/winpr/crt.h +++ b/winpr/include/winpr/crt.h @@ -32,26 +32,38 @@ #ifndef _WIN32 +#ifndef _strtoui64 +#define _strtoui64 strtoull +#endif + +#ifndef _strtoi64 +#define _strtoi64 strtoll +#endif + #ifndef _rotl -static INLINE UINT32 _rotl(UINT32 value, int shift) { +static INLINE UINT32 _rotl(UINT32 value, int shift) +{ return (value << shift) | (value >> (32 - shift)); } #endif #ifndef _rotl64 -static INLINE UINT64 _rotl64(UINT64 value, int shift) { +static INLINE UINT64 _rotl64(UINT64 value, int shift) +{ return (value << shift) | (value >> (64 - shift)); } #endif #ifndef _rotr -static INLINE UINT32 _rotr(UINT32 value, int shift) { +static INLINE UINT32 _rotr(UINT32 value, int shift) +{ return (value >> shift) | (value << (32 - shift)); } #endif #ifndef _rotr64 -static INLINE UINT64 _rotr64(UINT64 value, int shift) { +static INLINE UINT64 _rotr64(UINT64 value, int shift) +{ return (value >> shift) | (value << (64 - shift)); } #endif @@ -63,22 +75,24 @@ static INLINE UINT64 _rotr64(UINT64 value, int shift) { #else -static INLINE UINT32 _byteswap_ulong(UINT32 _val) { - return (((_val) >> 24) | \ - (((_val) & 0x00FF0000) >> 8) | \ - (((_val) & 0x0000FF00) << 8) | \ - ((_val) << 24)); +static INLINE UINT32 _byteswap_ulong(UINT32 _val) +{ + return (((_val) >> 24) | \ + (((_val) & 0x00FF0000) >> 8) | \ + (((_val) & 0x0000FF00) << 8) | \ + ((_val) << 24)); } -static INLINE UINT64 _byteswap_uint64(UINT64 _val) { - return (((_val) << 56) | \ - (((_val) << 40) & 0xFF000000000000) | \ - (((_val) << 24) & 0xFF0000000000) | \ - (((_val) << 8) & 0xFF00000000) | \ - (((_val) >> 8) & 0xFF000000) | \ - (((_val) >> 24) & 0xFF0000) | \ - (((_val) >> 40) & 0xFF00) | \ - ((_val) >> 56)); +static INLINE UINT64 _byteswap_uint64(UINT64 _val) +{ + return (((_val) << 56) | \ + (((_val) << 40) & 0xFF000000000000) | \ + (((_val) << 24) & 0xFF0000000000) | \ + (((_val) << 8) & 0xFF00000000) | \ + (((_val) >> 8) & 0xFF000000) | \ + (((_val) >> 24) & 0xFF0000) | \ + (((_val) >> 40) & 0xFF00) | \ + ((_val) >> 56)); } #endif @@ -89,7 +103,8 @@ static INLINE UINT64 _byteswap_uint64(UINT64 _val) { #else -static INLINE UINT16 _byteswap_ushort(UINT16 _val) { +static INLINE UINT16 _byteswap_ushort(UINT16 _val) +{ return (((_val) >> 8) | ((_val) << 8)); } @@ -128,8 +143,10 @@ WINPR_API void* _aligned_realloc(void* memblock, size_t size, size_t alignment); WINPR_API void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignment); WINPR_API void* _aligned_offset_malloc(size_t size, size_t alignment, size_t offset); -WINPR_API void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, size_t offset); -WINPR_API void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset); +WINPR_API void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, + size_t offset); +WINPR_API void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, + size_t offset); WINPR_API size_t _aligned_msize(void* memblock, size_t alignment, size_t offset); diff --git a/winpr/libwinpr/clipboard/synthetic.c b/winpr/libwinpr/clipboard/synthetic.c index 156e738..55767f0 100644 --- a/winpr/libwinpr/clipboard/synthetic.c +++ b/winpr/libwinpr/clipboard/synthetic.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include #include @@ -37,7 +38,8 @@ * Null-terminated ANSI text with CR/LF line endings. */ -static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId, const void* data, + UINT32* pSize) { int size; char* pDstData = NULL; @@ -46,34 +48,34 @@ static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId { char* str = NULL; - size = (int) *pSize; + if (*pSize > INT32_MAX) + return NULL; + + size = (int) * pSize; size = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) data, - size / 2, (CHAR**) &str, 0, NULL, NULL); + size / 2, (CHAR**) &str, 0, NULL, NULL); if (!str) return NULL; pDstData = ConvertLineEndingToCRLF((const char*) str, &size); free(str); - *pSize = size; - return pDstData; } else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) || - (formatId == ClipboardGetFormatId(clipboard, "UTF8_STRING")) || - (formatId == ClipboardGetFormatId(clipboard, "text/plain")) || - (formatId == ClipboardGetFormatId(clipboard, "TEXT")) || - (formatId == ClipboardGetFormatId(clipboard, "STRING"))) + (formatId == ClipboardGetFormatId(clipboard, "UTF8_STRING")) || + (formatId == ClipboardGetFormatId(clipboard, "text/plain")) || + (formatId == ClipboardGetFormatId(clipboard, "TEXT")) || + (formatId == ClipboardGetFormatId(clipboard, "STRING"))) { - size = (int) *pSize; + size = (INT64) * pSize; pDstData = ConvertLineEndingToCRLF((const char*) data, &size); if (!pDstData) return NULL; *pSize = size; - return pDstData; } @@ -86,7 +88,8 @@ static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId * Null-terminated OEM text with CR/LF line endings. */ -static void* clipboard_synthesize_cf_oemtext(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_cf_oemtext(wClipboard* clipboard, UINT32 formatId, + const void* data, UINT32* pSize) { return clipboard_synthesize_cf_text(clipboard, formatId, data, pSize); } @@ -97,15 +100,16 @@ static void* clipboard_synthesize_cf_oemtext(wClipboard* clipboard, UINT32 forma * System locale identifier associated with CF_TEXT */ -static void* clipboard_synthesize_cf_locale(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_cf_locale(wClipboard* clipboard, UINT32 formatId, + const void* data, UINT32* pSize) { UINT32* pDstData = NULL; - pDstData = (UINT32*) malloc(sizeof(UINT32)); + if (!pDstData) return NULL; - *pDstData = 0x0409; /* English - United States */ + *pDstData = 0x0409; /* English - United States */ return (void*) pDstData; } @@ -115,7 +119,8 @@ static void* clipboard_synthesize_cf_locale(wClipboard* clipboard, UINT32 format * Null-terminated UTF-16 text with CR/LF line endings. */ -static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 formatId, + const void* data, UINT32* pSize) { int size; int status; @@ -123,12 +128,15 @@ static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 f WCHAR* pDstData = NULL; if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) || - (formatId == ClipboardGetFormatId(clipboard, "UTF8_STRING")) || - (formatId == ClipboardGetFormatId(clipboard, "text/plain")) || - (formatId == ClipboardGetFormatId(clipboard, "TEXT")) || - (formatId == ClipboardGetFormatId(clipboard, "STRING"))) + (formatId == ClipboardGetFormatId(clipboard, "UTF8_STRING")) || + (formatId == ClipboardGetFormatId(clipboard, "text/plain")) || + (formatId == ClipboardGetFormatId(clipboard, "TEXT")) || + (formatId == ClipboardGetFormatId(clipboard, "STRING"))) { - size = (int) *pSize; + if (!pSize || (*pSize > INT32_MAX)) + return NULL; + + size = (int) * pSize; crlfStr = ConvertLineEndingToCRLF((char*) data, &size); if (!crlfStr) @@ -152,43 +160,39 @@ static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 f * Null-terminated UTF-8 string with LF line endings. */ -static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 formatId, + const void* data, UINT32* pSize) { - int size; + INT64 size; char* pDstData = NULL; if (formatId == CF_UNICODETEXT) { - size = (int) *pSize; + size = (INT64) * pSize; size = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) data, - size / 2, (CHAR**) &pDstData, 0, NULL, NULL); + size / 2, (CHAR**) &pDstData, 0, NULL, NULL); if (!pDstData) return NULL; size = ConvertLineEndingToLF(pDstData, size); - *pSize = size; - return pDstData; } else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) || - (formatId == ClipboardGetFormatId(clipboard, "text/plain")) || - (formatId == ClipboardGetFormatId(clipboard, "TEXT")) || - (formatId == ClipboardGetFormatId(clipboard, "STRING"))) + (formatId == ClipboardGetFormatId(clipboard, "text/plain")) || + (formatId == ClipboardGetFormatId(clipboard, "TEXT")) || + (formatId == ClipboardGetFormatId(clipboard, "STRING"))) { - size = (int) *pSize; + size = (INT64) * pSize; pDstData = (char*) malloc(size); if (!pDstData) return NULL; CopyMemory(pDstData, data, size); - size = ConvertLineEndingToLF((char*) pDstData, size); - *pSize = size; - return pDstData; } @@ -201,17 +205,16 @@ static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 form * BITMAPINFO structure followed by the bitmap bits. */ -static void* clipboard_synthesize_cf_dib(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_cf_dib(wClipboard* clipboard, UINT32 formatId, const void* data, + UINT32* pSize) { UINT32 SrcSize; UINT32 DstSize; BYTE* pDstData; - SrcSize = *pSize; if (formatId == CF_DIBV5) { - } else if (formatId == ClipboardGetFormatId(clipboard, "image/bmp")) { @@ -231,11 +234,9 @@ static void* clipboard_synthesize_cf_dib(wClipboard* clipboard, UINT32 formatId, if (!pDstData) return NULL; - data = (void*) &((BYTE*) data)[sizeof(BITMAPFILEHEADER)]; - + data = (void*) & ((BYTE*) data)[sizeof(BITMAPFILEHEADER)]; CopyMemory(pDstData, data, DstSize); *pSize = DstSize; - return pDstData; } @@ -248,15 +249,14 @@ static void* clipboard_synthesize_cf_dib(wClipboard* clipboard, UINT32 formatId, * BITMAPV5HEADER structure followed by the bitmap color space information and the bitmap bits. */ -static void* clipboard_synthesize_cf_dibv5(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_cf_dibv5(wClipboard* clipboard, UINT32 formatId, const void* data, + UINT32* pSize) { if (formatId == CF_DIB) { - } else if (formatId == ClipboardGetFormatId(clipboard, "image/bmp")) { - } return NULL; @@ -268,12 +268,12 @@ static void* clipboard_synthesize_cf_dibv5(wClipboard* clipboard, UINT32 formatI * Bitmap file format. */ -static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 formatId, + const void* data, UINT32* pSize) { UINT32 SrcSize; UINT32 DstSize; BYTE* pDstData; - SrcSize = *pSize; if (formatId == CF_DIB) @@ -302,16 +302,13 @@ static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 format pFileHeader->bfReserved1 = 0; pFileHeader->bfReserved2 = 0; pFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); - pDst = &pDstData[sizeof(BITMAPFILEHEADER)]; CopyMemory(pDst, data, SrcSize); *pSize = DstSize; - return pDstData; } else if (formatId == CF_DIBV5) { - } return NULL; @@ -323,11 +320,12 @@ static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 format * HTML clipboard format: msdn.microsoft.com/en-us/library/windows/desktop/ms649015/ */ -static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 formatId, + const void* data, UINT32* pSize) { char* pSrcData = NULL; char* pDstData = NULL; - int SrcSize = (int) *pSize; + INT64 SrcSize = (INT64) * pSize; if (formatId == ClipboardGetFormatId(clipboard, "text/html")) { @@ -347,22 +345,24 @@ static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 form if ((bom[0] == 0xFF) && (bom[1] == 0xFE)) { - wstr = (WCHAR*) &((BYTE*) data)[2]; - + wstr = (WCHAR*) & ((BYTE*) data)[2]; ConvertFromUnicode(CP_UTF8, 0, wstr, - (SrcSize - 2) / 2, &pSrcData, 0, NULL, NULL); + (SrcSize - 2) / 2, &pSrcData, 0, NULL, NULL); } } if (!pSrcData) { pSrcData = (char*) calloc(1, SrcSize + 1); + if (!pSrcData) return NULL; + CopyMemory(pSrcData, data, SrcSize); } pDstData = (char*) calloc(1, SrcSize + 200); + if (!pDstData) { free(pSrcData); @@ -370,12 +370,11 @@ static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 form } strcpy(pDstData, - "Version:0.9\r\n" - "StartHTML:0000000000\r\n" - "EndHTML:0000000000\r\n" - "StartFragment:0000000000\r\n" - "EndFragment:0000000000\r\n"); - + "Version:0.9\r\n" + "StartHTML:0000000000\r\n" + "EndHTML:0000000000\r\n" + "StartFragment:0000000000\r\n" + "EndFragment:0000000000\r\n"); body = strstr(pSrcData, ""); strcat(pDstData, ""); - /* StartFragment */ sprintf_s(num, sizeof(num), "%010"PRIuz"", strlen(pDstData)); CopyMemory(&pDstData[69], num, 10); strcat(pDstData, pSrcData); - /* EndFragment */ sprintf_s(num, sizeof(num), "%010"PRIuz"", strlen(pDstData)); CopyMemory(&pDstData[93], num, 10); @@ -406,7 +403,6 @@ static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 form /* EndHTML */ sprintf_s(num, sizeof(num), "%010"PRIuz"", strlen(pDstData)); CopyMemory(&pDstData[43], num, 10); - *pSize = (UINT32) strlen(pDstData) + 1; free(pSrcData); } @@ -420,32 +416,37 @@ static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 form * HTML text format. */ -static void* clipboard_synthesize_text_html(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) +static void* clipboard_synthesize_text_html(wClipboard* clipboard, UINT32 formatId, + const void* data, UINT32* pSize) { - int beg; - int end; + long beg; + long end; char* str; char* begStr; char* endStr; - int SrcSize; - int DstSize = -1; + INT64 SrcSize; + long DstSize = -1; BYTE* pDstData = NULL; if (formatId == ClipboardGetFormatId(clipboard, "HTML Format")) { str = (char*) data; - SrcSize = (int) *pSize; - + SrcSize = (INT64) * pSize; begStr = strstr(str, "StartHTML:"); endStr = strstr(str, "EndHTML:"); if (!begStr || !endStr) return NULL; - beg = atoi(&begStr[10]); - end = atoi(&endStr[8]); + errno = 0; + beg = strtol(&begStr[10], NULL, 0); + + if (errno != 0) + return NULL; + + end = strtol(&endStr[8], NULL, 0); - if (beg < 0 || end < 0 || (beg > SrcSize) || (end > SrcSize) || (beg >= end)) + if (beg < 0 || end < 0 || (beg > SrcSize) || (end > SrcSize) || (beg >= end) || (errno != 0)) return NULL; DstSize = end - beg; @@ -466,143 +467,108 @@ BOOL ClipboardInitSynthesizers(wClipboard* clipboard) { UINT32 formatId; UINT32 altFormatId; - /** * CF_TEXT */ - ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_OEMTEXT, - clipboard_synthesize_cf_oemtext); - + clipboard_synthesize_cf_oemtext); ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_UNICODETEXT, - clipboard_synthesize_cf_unicodetext); - + clipboard_synthesize_cf_unicodetext); ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_LOCALE, - clipboard_synthesize_cf_locale); - + clipboard_synthesize_cf_locale); altFormatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING"); - ClipboardRegisterSynthesizer(clipboard, CF_TEXT, altFormatId, - clipboard_synthesize_utf8_string); - + clipboard_synthesize_utf8_string); /** * CF_OEMTEXT */ - ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_TEXT, - clipboard_synthesize_cf_text); - + clipboard_synthesize_cf_text); ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_UNICODETEXT, - clipboard_synthesize_cf_unicodetext); - + clipboard_synthesize_cf_unicodetext); ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_LOCALE, - clipboard_synthesize_cf_locale); - + clipboard_synthesize_cf_locale); altFormatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING"); - ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, altFormatId, - clipboard_synthesize_utf8_string); - + clipboard_synthesize_utf8_string); /** * CF_UNICODETEXT */ - ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_TEXT, - clipboard_synthesize_cf_text); - + clipboard_synthesize_cf_text); ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_OEMTEXT, - clipboard_synthesize_cf_oemtext); - + clipboard_synthesize_cf_oemtext); ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_LOCALE, - clipboard_synthesize_cf_locale); - + clipboard_synthesize_cf_locale); altFormatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING"); - ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, altFormatId, - clipboard_synthesize_utf8_string); - + clipboard_synthesize_utf8_string); /** * UTF8_STRING */ - formatId = ClipboardRegisterFormat(clipboard, "UTF8_STRING"); if (formatId) { ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT, - clipboard_synthesize_cf_text); - + clipboard_synthesize_cf_text); ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT, - clipboard_synthesize_cf_oemtext); - + clipboard_synthesize_cf_oemtext); ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT, - clipboard_synthesize_cf_unicodetext); - + clipboard_synthesize_cf_unicodetext); ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE, - clipboard_synthesize_cf_locale); + clipboard_synthesize_cf_locale); } /** * text/plain */ - formatId = ClipboardRegisterFormat(clipboard, "text/plain"); if (formatId) { ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT, - clipboard_synthesize_cf_text); - + clipboard_synthesize_cf_text); ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT, - clipboard_synthesize_cf_oemtext); - + clipboard_synthesize_cf_oemtext); ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT, - clipboard_synthesize_cf_unicodetext); - + clipboard_synthesize_cf_unicodetext); ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE, - clipboard_synthesize_cf_locale); + clipboard_synthesize_cf_locale); } /** * TEXT */ - formatId = ClipboardRegisterFormat(clipboard, "TEXT"); if (formatId) { ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT, - clipboard_synthesize_cf_text); - + clipboard_synthesize_cf_text); ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT, - clipboard_synthesize_cf_oemtext); - + clipboard_synthesize_cf_oemtext); ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT, - clipboard_synthesize_cf_unicodetext); - + clipboard_synthesize_cf_unicodetext); ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE, - clipboard_synthesize_cf_locale); + clipboard_synthesize_cf_locale); } /** * STRING */ - formatId = ClipboardRegisterFormat(clipboard, "STRING"); if (formatId) { ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT, - clipboard_synthesize_cf_text); - + clipboard_synthesize_cf_text); ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT, - clipboard_synthesize_cf_oemtext); - + clipboard_synthesize_cf_oemtext); ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT, - clipboard_synthesize_cf_unicodetext); - + clipboard_synthesize_cf_unicodetext); ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE, - clipboard_synthesize_cf_locale); + clipboard_synthesize_cf_locale); } /** @@ -612,12 +578,10 @@ BOOL ClipboardInitSynthesizers(wClipboard* clipboard) if (formatId) { ClipboardRegisterSynthesizer(clipboard, CF_DIB, CF_DIBV5, - clipboard_synthesize_cf_dibv5); - + clipboard_synthesize_cf_dibv5); altFormatId = ClipboardRegisterFormat(clipboard, "image/bmp"); - ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId, - clipboard_synthesize_image_bmp); + clipboard_synthesize_image_bmp); } /** @@ -627,55 +591,47 @@ BOOL ClipboardInitSynthesizers(wClipboard* clipboard) if (formatId && 0) { ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, CF_DIB, - clipboard_synthesize_cf_dib); - + clipboard_synthesize_cf_dib); altFormatId = ClipboardRegisterFormat(clipboard, "image/bmp"); - ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId, - clipboard_synthesize_image_bmp); + clipboard_synthesize_image_bmp); } /** * image/bmp */ - formatId = ClipboardRegisterFormat(clipboard, "image/bmp"); if (formatId) { ClipboardRegisterSynthesizer(clipboard, formatId, CF_DIB, - clipboard_synthesize_cf_dib); - + clipboard_synthesize_cf_dib); ClipboardRegisterSynthesizer(clipboard, formatId, CF_DIBV5, - clipboard_synthesize_cf_dibv5); + clipboard_synthesize_cf_dibv5); } /** * HTML Format */ - formatId = ClipboardRegisterFormat(clipboard, "HTML Format"); if (formatId) { altFormatId = ClipboardRegisterFormat(clipboard, "text/html"); - ClipboardRegisterSynthesizer(clipboard, formatId, altFormatId, - clipboard_synthesize_text_html); + clipboard_synthesize_text_html); } /** * text/html */ - formatId = ClipboardRegisterFormat(clipboard, "text/html"); if (formatId) { altFormatId = ClipboardRegisterFormat(clipboard, "HTML Format"); - ClipboardRegisterSynthesizer(clipboard, formatId, altFormatId, - clipboard_synthesize_html_format); + clipboard_synthesize_html_format); } return TRUE; diff --git a/winpr/libwinpr/registry/registry_reg.c b/winpr/libwinpr/registry/registry_reg.c index ac9bc8d..498a449 100644 --- a/winpr/libwinpr/registry/registry_reg.c +++ b/winpr/libwinpr/registry/registry_reg.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include #include #include @@ -89,6 +90,7 @@ static void reg_load_start(Reg* reg) return; reg->buffer = (char*) malloc(file_size + 2); + if (!reg->buffer) return ; @@ -138,16 +140,20 @@ static RegVal* reg_load_value(Reg* reg, RegKey* key) data = p[3] + 1; length = p[1] - p[0]; name = (char*) malloc(length + 1); + if (!name) return NULL; + memcpy(name, p[0], length); name[length] = '\0'; value = (RegVal*) malloc(sizeof(RegVal)); + if (!value) { free(name); return NULL; } + value->name = name; value->type = REG_NONE; value->next = value->prev = NULL; @@ -163,13 +169,25 @@ static RegVal* reg_load_value(Reg* reg, RegKey* key) if (value->type == REG_DWORD) { - value->data.dword = strtoul(data, NULL, 16); + unsigned long val; + errno = 0; + val = strtoul(data, NULL, 16); + + if ((errno != 0) || (val > UINT32_MAX)) + { + free(value); + free(name); + return NULL; + } + + value->data.dword = val; } else if (value->type == REG_SZ) { p[4] = strchr(data, '"'); p[4][0] = '\0'; value->data.string = _strdup(data); + if (!value->data.string) { free(value); @@ -233,8 +251,10 @@ static void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey) char* save; int length; path = _strdup(subkey->name); + if (!path) return; + name = strtok_s(path, "\\", &save); while (name != NULL) @@ -244,6 +264,7 @@ static void reg_insert_key(Reg* reg, RegKey* key, RegKey* subkey) length = strlen(name); name += length + 1; subkey->subname = _strdup(name); + /* TODO: free allocated memory in error case */ if (!subkey->subname) { @@ -267,17 +288,21 @@ static RegKey* reg_load_key(Reg* reg, RegKey* key) p[0] = reg->line + 1; p[1] = strrchr(p[0], ']'); subkey = (RegKey*) malloc(sizeof(RegKey)); + if (!subkey) return NULL; + subkey->values = NULL; subkey->prev = subkey->next = NULL; length = p[1] - p[0]; subkey->name = (char*) malloc(length + 1); + if (!subkey->name) { free(subkey); return NULL; } + memcpy(subkey->name, p[0], length); subkey->name[length] = '\0'; @@ -393,39 +418,40 @@ Reg* reg_open(BOOL read_only) if (!reg) return NULL; - reg->read_only = read_only; - reg->filename = WINPR_HKLM_HIVE; + reg->read_only = read_only; + reg->filename = WINPR_HKLM_HIVE; - if (reg->read_only) - { - reg->fp = fopen(reg->filename, "r"); - } - else - { - reg->fp = fopen(reg->filename, "r+"); + if (reg->read_only) + { + reg->fp = fopen(reg->filename, "r"); + } + else + { + reg->fp = fopen(reg->filename, "r+"); + + if (!reg->fp) + reg->fp = fopen(reg->filename, "w+"); + } - if (!reg->fp) - reg->fp = fopen(reg->filename, "w+"); - } + if (!reg->fp) + { + free(reg); + return NULL; + } - if (!reg->fp) - { - free(reg); - return NULL; - } + reg->root_key = (RegKey*) malloc(sizeof(RegKey)); - reg->root_key = (RegKey*) malloc(sizeof(RegKey)); if (!reg->root_key) { fclose(reg->fp); free(reg); return NULL; } - reg->root_key->values = NULL; - reg->root_key->subkeys = NULL; - reg->root_key->name = "HKEY_LOCAL_MACHINE"; - reg_load(reg); + reg->root_key->values = NULL; + reg->root_key->subkeys = NULL; + reg->root_key->name = "HKEY_LOCAL_MACHINE"; + reg_load(reg); return reg; } diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 5a3d7ea..88910ba 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -2855,16 +2856,16 @@ WINSCARDAPI LONG WINAPI PCSC_SCardAddReaderName(HANDLE* key, LPSTR readerName) } #ifdef __MACOSX__ -unsigned int determineMacOSXVersion() +unsigned int determineMacOSXVersion(void) { int mib[2]; size_t len = 0; char* kernelVersion = NULL; char* tok = NULL; unsigned int version = 0; - int majorVersion = 0; - int minorVersion = 0; - int patchVersion = 0; + long majorVersion = 0; + long minorVersion = 0; + long patchVersion = 0; int count = 0; mib[0] = CTL_KERN; mib[1] = KERN_OSRELEASE; @@ -2884,21 +2885,34 @@ unsigned int determineMacOSXVersion() } tok = strtok(kernelVersion, "."); + errno = 0; while (tok) { switch (count) { case 0: - majorVersion = atoi(tok); + majorVersion = strtol(tok, NULL, 0); + + if (errno != 0) + goto fail; + break; case 1: - minorVersion = atoi(tok); + minorVersion = strtol(tok, NULL, 0); + + if (errno != 0) + goto fail; + break; case 2: - patchVersion = atoi(tok); + patchVersion = strtol(tok, NULL, 0); + + if (errno != 0) + goto fail; + break; } @@ -2964,6 +2978,7 @@ unsigned int determineMacOSXVersion() version |= (minorVersion << 8) | (patchVersion); } +fail: free(kernelVersion); return version; } diff --git a/winpr/libwinpr/utils/ini.c b/winpr/libwinpr/utils/ini.c index 112a6c5..fda153a 100644 --- a/winpr/libwinpr/utils/ini.c +++ b/winpr/libwinpr/utils/ini.c @@ -33,7 +33,6 @@ BOOL IniFile_Load_NextLine(wIniFile* ini, char* str) { int length = 0; - ini->nextLine = strtok_s(str, "\n", &ini->tokctx); if (ini->nextLine) @@ -57,11 +56,9 @@ BOOL IniFile_Load_NextLine(wIniFile* ini, char* str) int IniFile_Load_String(wIniFile* ini, const char* iniString) { long int fileSize; - ini->line = NULL; ini->nextLine = NULL; ini->buffer = NULL; - fileSize = (long int) strlen(iniString); if (fileSize < 1) @@ -73,12 +70,9 @@ int IniFile_Load_String(wIniFile* ini, const char* iniString) return -1; CopyMemory(ini->buffer, iniString, fileSize); - ini->buffer[fileSize] = '\n'; ini->buffer[fileSize + 1] = '\0'; - IniFile_Load_NextLine(ini, ini->buffer); - return 1; } @@ -106,10 +100,10 @@ int IniFile_Load_File(wIniFile* ini, const char* filename) goto out_file; fileSize = _ftelli64(ini->fp); - + if (fileSize < 0) goto out_file; - + if (_fseeki64(ini->fp, 0, SEEK_SET) < 0) goto out_file; @@ -130,14 +124,10 @@ int IniFile_Load_File(wIniFile* ini, const char* filename) fclose(ini->fp); ini->fp = NULL; - ini->buffer[fileSize] = '\n'; ini->buffer[fileSize + 1] = '\0'; - IniFile_Load_NextLine(ini, ini->buffer); - return 1; - out_buffer: free(ini->buffer); ini->buffer = NULL; @@ -174,9 +164,7 @@ char* IniFile_Load_GetNextLine(wIniFile* ini) ini->line = ini->nextLine; ini->lineLength = (int) strlen(ini->line); - IniFile_Load_NextLine(ini, NULL); - return ini->line; } @@ -290,13 +278,12 @@ wIniFileSection* IniFile_AddSection(wIniFile* ini, const char* name) { int new_size; wIniFileSection** new_sect; - new_size = ini->cSections * 2; new_sect = (wIniFileSection**) realloc(ini->sections, sizeof(wIniFileSection*) * new_size); - + if (!new_sect) return NULL; - + ini->cSections = new_size; ini->sections = new_sect; } @@ -326,13 +313,14 @@ wIniFileKey* IniFile_GetKey(wIniFile* ini, wIniFileSection* section, const char* return key; } -wIniFileKey* IniFile_AddKey(wIniFile* ini, wIniFileSection* section, const char* name, const char* value) +wIniFileKey* IniFile_AddKey(wIniFile* ini, wIniFileSection* section, const char* name, + const char* value) { wIniFileKey* key; if (!section || !name) return NULL; - + key = IniFile_GetKey(ini, section, name); if (!key) @@ -341,19 +329,18 @@ wIniFileKey* IniFile_AddKey(wIniFile* ini, wIniFileSection* section, const char* { int new_size; wIniFileKey** new_key; - new_size = section->cKeys * 2; new_key = (wIniFileKey**) realloc(section->keys, sizeof(wIniFileKey*) * new_size); - + if (!new_key) return NULL; - + section->cKeys = new_size; section->keys = new_key; } key = IniFile_Key_New(name, value); - + if (!key) return NULL; @@ -378,7 +365,7 @@ int IniFile_Load(wIniFile* ini) char* name; char* value; char* separator; - char *beg, *end; + char* beg, *end; wIniFileKey* key = NULL; wIniFileSection* section = NULL; @@ -392,21 +379,18 @@ int IniFile_Load(wIniFile* ini) if (line[0] == '[') { beg = &line[1]; - end = strchr(line, ']'); if (!end) return -1; *end = '\0'; - IniFile_AddSection(ini, beg); section = ini->sections[ini->nSections - 1]; } else { separator = strchr(line, '='); - end = separator; while ((&end[-1] > line) && ((end[-1] == ' ') || (end[-1] == '\t'))) @@ -414,23 +398,22 @@ int IniFile_Load(wIniFile* ini) *end = '\0'; name = line; - beg = separator + 1; while (*beg && ((*beg == ' ') || (*beg == '\t'))) beg++; - + if (*beg == '"') beg++; - + end = &line[ini->lineLength]; - + while ((end > beg) && ((end[-1] == ' ') || (end[-1] == '\t'))) end--; - + if (end[-1] == '"') end[-1] = '\0'; - + value = beg; if (!IniFile_AddKey(ini, section, name, value)) @@ -439,39 +422,34 @@ int IniFile_Load(wIniFile* ini) } key = NULL; + if (section && section->keys) key = section->keys[section->nKeys - 1]; } } IniFile_Load_Finish(ini); - return 1; } int IniFile_ReadBuffer(wIniFile* ini, const char* buffer) { int status; - ini->readOnly = TRUE; ini->filename = NULL; - status = IniFile_Load_String(ini, buffer); - + if (status < 0) return status; - - status = IniFile_Load(ini); + status = IniFile_Load(ini); return status; } int IniFile_ReadFile(wIniFile* ini, const char* filename) { int status; - ini->readOnly = TRUE; - free(ini->filename); ini->filename = _strdup(filename); @@ -479,12 +457,11 @@ int IniFile_ReadFile(wIniFile* ini, const char* filename) return -1; status = IniFile_Load_File(ini, filename); - + if (status < 0) return status; - - status = IniFile_Load(ini); + status = IniFile_Load(ini); return status; } @@ -496,23 +473,22 @@ char** IniFile_GetSectionNames(wIniFile* ini, int* count) int nameLength; char** sectionNames; wIniFileSection* section = NULL; - length = (sizeof(char*) * ini->nSections) + sizeof(char); - + for (index = 0; index < ini->nSections; index++) { section = ini->sections[index]; nameLength = (int) strlen(section->name); length += (nameLength + 1); } - + sectionNames = (char**) malloc(length); if (!sectionNames) return NULL; - p = (char*) &((BYTE*) sectionNames)[sizeof(char*) * ini->nSections]; - + p = (char*) & ((BYTE*) sectionNames)[sizeof(char*) * ini->nSections]; + for (index = 0; index < ini->nSections; index++) { sectionNames[index] = p; @@ -523,9 +499,7 @@ char** IniFile_GetSectionNames(wIniFile* ini, int* count) } *p = '\0'; - *count = ini->nSections; - return sectionNames; } @@ -538,27 +512,27 @@ char** IniFile_GetSectionKeyNames(wIniFile* ini, const char* section, int* count char** keyNames; wIniFileKey* pKey = NULL; wIniFileSection* pSection = NULL; - pSection = IniFile_GetSection(ini, section); - + if (!pSection) return NULL; - + length = (sizeof(char*) * pSection->nKeys) + sizeof(char); - + for (index = 0; index < pSection->nKeys; index++) { pKey = pSection->keys[index]; nameLength = (int) strlen(pKey->name); length += (nameLength + 1); } - + keyNames = (char**) malloc(length); + if (!keyNames) return NULL; - p = (char*) &((BYTE*) keyNames)[sizeof(char*) * pSection->nKeys]; - + p = (char*) & ((BYTE*) keyNames)[sizeof(char*) * pSection->nKeys]; + for (index = 0; index < pSection->nKeys; index++) { keyNames[index] = p; @@ -569,9 +543,7 @@ char** IniFile_GetSectionKeyNames(wIniFile* ini, const char* section, int* count } *p = '\0'; - *count = pSection->nKeys; - return keyNames; } @@ -580,48 +552,44 @@ const char* IniFile_GetKeyValueString(wIniFile* ini, const char* section, const const char* value = NULL; wIniFileKey* pKey = NULL; wIniFileSection* pSection = NULL; - pSection = IniFile_GetSection(ini, section); - + if (!pSection) return NULL; - + pKey = IniFile_GetKey(ini, pSection, key); - + if (!pKey) return NULL; - + value = (const char*) pKey->value; - return value; } int IniFile_GetKeyValueInt(wIniFile* ini, const char* section, const char* key) { - int value = 0; + long value = 0; wIniFileKey* pKey = NULL; wIniFileSection* pSection = NULL; - pSection = IniFile_GetSection(ini, section); - + if (!pSection) return 0; - + pKey = IniFile_GetKey(ini, pSection, key); - + if (!pKey) return 0; - - value = atoi(pKey->value); - + + value = strtol(pKey->value, NULL, 0); return value; } -int IniFile_SetKeyValueString(wIniFile* ini, const char* section, const char* key, const char* value) +int IniFile_SetKeyValueString(wIniFile* ini, const char* section, const char* key, + const char* value) { wIniFileKey* pKey = NULL; wIniFileSection* pSection = NULL; - pSection = IniFile_GetSection(ini, section); if (!pSection) @@ -643,9 +611,7 @@ int IniFile_SetKeyValueInt(wIniFile* ini, const char* section, const char* key, char strVal[128]; wIniFileKey* pKey = NULL; wIniFileSection* pSection = NULL; - sprintf_s(strVal, sizeof(strVal), "%d", value); - pSection = IniFile_GetSection(ini, section); if (!pSection) @@ -665,30 +631,28 @@ int IniFile_SetKeyValueInt(wIniFile* ini, const char* section, const char* key, char* IniFile_WriteBuffer(wIniFile* ini) { int i, j; - int offset; - int size; + size_t offset; + size_t size; char* buffer; wIniFileKey* key; wIniFileSection* section; - size = 0; for (i = 0; i < ini->nSections; i++) { section = ini->sections[i]; - size += (int) (strlen(section->name) + 3); + size += (strlen(section->name) + 3); for (j = 0; j < section->nKeys; j++) { key = section->keys[j]; - size += (int) (strlen(key->name) + strlen(key->value) + 2); + size += (strlen(key->name) + strlen(key->value) + 2); } size += 1; } size += 1; - buffer = malloc(size + 1); if (!buffer) @@ -700,13 +664,13 @@ char* IniFile_WriteBuffer(wIniFile* ini) { section = ini->sections[i]; sprintf_s(&buffer[offset], size - offset, "[%s]\n", section->name); - offset += (int) (strlen(section->name) + 3); + offset += (strlen(section->name) + 3); for (j = 0; j < section->nKeys; j++) { key = section->keys[j]; sprintf_s(&buffer[offset], size - offset, "%s=%s\n", key->name, key->value); - offset += (int) (strlen(key->name) + strlen(key->value) + 2); + offset += (strlen(key->name) + strlen(key->value) + 2); } sprintf_s(&buffer[offset], size - offset, "\n"); @@ -714,7 +678,6 @@ char* IniFile_WriteBuffer(wIniFile* ini) } buffer[offset] = '\0'; - return buffer; } @@ -723,14 +686,12 @@ int IniFile_WriteFile(wIniFile* ini, const char* filename) int length; char* buffer; int ret = 1; - buffer = IniFile_WriteBuffer(ini); if (!buffer) return -1; length = (int) strlen(buffer); - ini->readOnly = FALSE; if (!filename) @@ -746,9 +707,7 @@ int IniFile_WriteFile(wIniFile* ini, const char* filename) ret = -1; fclose(ini->fp); - free(buffer); - return ret; } @@ -787,6 +746,5 @@ void IniFile_Free(wIniFile* ini) } free(ini->sections); - free(ini); } diff --git a/winpr/libwinpr/utils/test/TestCmdLine.c b/winpr/libwinpr/utils/test/TestCmdLine.c index 538e500..a22315a 100644 --- a/winpr/libwinpr/utils/test/TestCmdLine.c +++ b/winpr/libwinpr/utils/test/TestCmdLine.c @@ -1,9 +1,10 @@ +#include #include #include #include -const char* testArgv[] = +static const char* testArgv[] = { "mstsc.exe", "+z", @@ -17,7 +18,7 @@ const char* testArgv[] = "/v:localhost:3389" }; -COMMAND_LINE_ARGUMENT_A args[] = +static COMMAND_LINE_ARGUMENT_A args[] = { { "v", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "destination server" }, { "port", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "server port" }, @@ -60,10 +61,9 @@ int TestCmdLine(int argc, char* argv[]) { int status; DWORD flags; - int width = 0; - int height = 0; + long width = 0; + long height = 0; COMMAND_LINE_ARGUMENT_A* arg; - flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_SIGIL_PLUS_MINUS; status = CommandLineParseArgumentsA(testArgc, testArgv, args, flags, NULL, NULL, NULL); @@ -146,6 +146,7 @@ int TestCmdLine(int argc, char* argv[]) } arg = args; + errno = 0; do { @@ -153,33 +154,34 @@ int TestCmdLine(int argc, char* argv[]) continue; printf("Argument: %s\n", arg->Name); - CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "v") { - } CommandLineSwitchCase(arg, "w") { - width = atoi(arg->Value); + width = strtol(arg->Value, NULL, 0); + + if (errno != 0) + return -1; } CommandLineSwitchCase(arg, "h") { - height = atoi(arg->Value); + height = strtol(arg->Value, NULL, 0); + + if (errno != 0) + return -1; } CommandLineSwitchDefault(arg) { - } - CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); if ((width != 1024) || (height != 768)) { - printf("Unexpected width and height: Actual: (%dx%d), Expected: (1024x768)\n", width, height); + printf("Unexpected width and height: Actual: (%ldx%ld), Expected: (1024x768)\n", width, height); return -1; } diff --git a/winpr/tools/hash-cli/hash.c b/winpr/tools/hash-cli/hash.c index d54b30e..162696f 100644 --- a/winpr/tools/hash-cli/hash.c +++ b/winpr/tools/hash-cli/hash.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -46,16 +47,16 @@ void usage_and_exit() { - printf("winpr-hash: NTLM hashing tool\n"); - printf("Usage: winpr-hash -u -p [-d ] [-f <_default_,sam>] [-v <_1_,2>]\n"); - exit(1); + printf("winpr-hash: NTLM hashing tool\n"); + printf("Usage: winpr-hash -u -p [-d ] [-f <_default_,sam>] [-v <_1_,2>]\n"); + exit(1); } int main(int argc, char* argv[]) { int index = 1; int format = 0; - int version = 1; + unsigned long version = 1; BYTE NtHash[16]; char* User = NULL; UINT32 UserLength; @@ -63,6 +64,7 @@ int main(int argc, char* argv[]) UINT32 DomainLength; char* Password = NULL; UINT32 PasswordLength; + errno = 0; while (index < argc) { @@ -112,11 +114,11 @@ int main(int argc, char* argv[]) usage_and_exit(); } - version = atoi(argv[index]); + version = strtoul(argv[index], NULL, 0); - if ((version != 1) && (version != 2)) + if (((version != 1) && (version != 2)) || (errno != 0)) { - printf("unknown version %d \n\n", version); + printf("unknown version %lu \n\n", version); usage_and_exit(); } } @@ -172,6 +174,7 @@ int main(int argc, char* argv[]) { for (index = 0; index < 16; index++) printf("%02"PRIx8"", NtHash[index]); + printf("\n"); } else if (format == 1) diff --git a/winpr/tools/makecert/makecert.c b/winpr/tools/makecert/makecert.c index f1bfcf2..48cd5cf 100644 --- a/winpr/tools/makecert/makecert.c +++ b/winpr/tools/makecert/makecert.c @@ -17,6 +17,8 @@ * limitations under the License. */ +#include + #include #include #include @@ -441,6 +443,7 @@ static int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, } arg = args; + errno = 0; do { @@ -515,17 +518,31 @@ static int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, } CommandLineSwitchCase(arg, "y") { + long val; + if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)) continue; - context->duration_years = atoi(arg->Value); + val = strtol(arg->Value, NULL, 0); + + if ((errno != 0) || (val < 0) || (val > INT32_MAX)) + return -1; + + context->duration_years = strtol(arg->Value, NULL, 0); } CommandLineSwitchCase(arg, "m") { + long val; + if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)) continue; - context->duration_months = atoi(arg->Value); + val = strtol(arg->Value, NULL, 0); + + if ((errno != 0) || (val < 1) || (val > 12)) + return -1; + + context->duration_months = val; } CommandLineSwitchDefault(arg) { @@ -952,7 +969,7 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) #ifdef WITH_OPENSSL int length; char* entry; - int key_length; + unsigned long key_length; long serial = 0; X509_NAME* name = NULL; const EVP_MD* md = NULL; @@ -1005,7 +1022,10 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) { - key_length = atoi(arg->Value); + key_length = strtoul(arg->Value, NULL, 0); + + if (errno != 0) + return -1; } #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) @@ -1019,11 +1039,13 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) return -1; context->rsa = RSA_new(); + if (!context->rsa) { BN_clear_free(rsa); return -1; } + BN_set_word(rsa, RSA_F4); rc = RSA_generate_key_ex(context->rsa, key_length, rsa, NULL); BN_clear_free(rsa); @@ -1041,7 +1063,12 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) arg = CommandLineFindArgumentA(args, "#"); if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) - serial = atoi(arg->Value); + { + serial = strtol(arg->Value, NULL, 0); + + if (errno != 0) + return -1; + } else serial = (long) GetTickCount64(); -- 2.7.4