diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index 8990ad26a..17d5692d7 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -53,6 +53,7 @@ typedef struct _SERIAL_DEVICE SERIAL_DEVICE; struct _SERIAL_DEVICE { DEVICE device; + BOOL permissive; SERIAL_DRIVER_ID ServerSerialDriverId; HANDLE* hComm; @@ -182,11 +183,7 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) _comm_setServerSerialDriver(serial->hComm, serial->ServerSerialDriverId); - /* FIXME: Appeared to be useful to setup some devices. Guess - * the device driver asked to setup some unsupported feature - * that were not eventually used. TODO: collecting more - * details, a command line argument? */ - /* _comm_set_permissive(serial->hComm, TRUE); */ + _comm_set_permissive(serial->hComm, serial->permissive); /* NOTE: binary mode/raw mode required for the redirection. On * Linux, CommCreateFileA forces this setting. @@ -817,6 +814,21 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) serial->ServerSerialDriverId = SerialDriverSerCx2Sys; } + + if (device->Permissive != NULL) + { + if (_stricmp(device->Permissive, "permissive") == 0) + { + serial->permissive = TRUE; + } + else + { + WLog_Print(serial->log, WLOG_DEBUG, "Unknown flag: %s", device->Permissive); + assert(FALSE); + } + } + + WLog_Print(serial->log, WLOG_DEBUG, "Server's serial driver: %s (id: %d)", driver, serial->ServerSerialDriverId); /* TODO: implement auto detection of the server's serial driver */ diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 1646a2fff..3af9911bd 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -256,8 +256,8 @@ int freerdp_client_print_command_line_help(int argc, char** argv) printf("Drive Redirection: /drive:home,/home/user\n"); printf("Smartcard Redirection: /smartcard:\n"); - printf("Printer Redirection: /printer:,\n"); - printf("Serial Port Redirection: /serial:\n"); + printf("Serial Port Redirection: /serial:,,[SerCx2|SerCx|Serial],[permissive]\n"); + printf("Serial Port Redirection: /serial:COM1,/dev/ttyS0\n"); printf("Parallel Port Redirection: /parallel:\n"); printf("Printer Redirection: /printer:,\n"); printf("\n"); @@ -425,6 +425,9 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p if (count > 3) serial->Driver = _strdup(params[3]); + if (count > 4) + serial->Permissive = _strdup(params[4]); + freerdp_device_collection_add(settings, (RDPDR_DEVICE*) serial); return 1; diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index f1002e1ce..f2556024e 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -471,7 +471,8 @@ struct _RDPDR_SERIAL UINT32 Type; char* Name; char* Path; - char* Driver; + char* Driver; + char* Permissive; }; typedef struct _RDPDR_SERIAL RDPDR_SERIAL; diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index d960f9435..83ba65408 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -417,7 +417,7 @@ INLINE int gdi_is_mono_pixel_set(BYTE* data, int x, int y, int width) return (data[byte] & (0x80 >> shift)) != 0; } -gdiBitmap* gdi_glyph_new(rdpGdi* gdi, GLYPH_DATA* glyph) +static gdiBitmap* gdi_glyph_new(rdpGdi* gdi, GLYPH_DATA* glyph) { BYTE* extra; gdiBitmap* gdi_bmp; @@ -442,7 +442,7 @@ gdiBitmap* gdi_glyph_new(rdpGdi* gdi, GLYPH_DATA* glyph) return gdi_bmp; } -void gdi_glyph_free(gdiBitmap* gdi_bmp) +static void gdi_glyph_free(gdiBitmap* gdi_bmp) { if (gdi_bmp) { @@ -488,7 +488,7 @@ void gdi_bitmap_free_ex(gdiBitmap* bitmap) } } -void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) +static void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) { int status; int nXDst; @@ -591,7 +591,7 @@ void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) } } -void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) +static void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) { int index; PALETTE_ENTRY* pe; @@ -609,7 +609,7 @@ void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) } } -void gdi_set_bounds(rdpContext* context, rdpBounds* bounds) +static void gdi_set_bounds(rdpContext* context, rdpBounds* bounds) { rdpGdi* gdi = context->gdi; @@ -624,7 +624,7 @@ void gdi_set_bounds(rdpContext* context, rdpBounds* bounds) } } -void gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) +static void gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) { rdpGdi* gdi = context->gdi; @@ -632,7 +632,7 @@ void gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) dstblt->nWidth, dstblt->nHeight, NULL, 0, 0, gdi_rop3_code(dstblt->bRop)); } -void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) +static void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { BYTE* data; rdpBrush* brush; @@ -712,7 +712,7 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) gdi_SetTextColor(gdi->drawing->hdc, originalColor); } -void gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) +static void gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) { rdpGdi* gdi = context->gdi; @@ -721,7 +721,7 @@ void gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) scrblt->nXSrc, scrblt->nYSrc, gdi_rop3_code(scrblt->bRop)); } -void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +static void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) { GDI_RECT rect; HGDI_BRUSH hBrush; @@ -739,7 +739,7 @@ void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) gdi_DeleteObject((HGDIOBJECT) hBrush); } -void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +static void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) { int i; GDI_RECT rect; @@ -764,7 +764,7 @@ void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_o } } -void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo) +static void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo) { UINT32 color; HGDI_PEN hPen; @@ -781,7 +781,7 @@ void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo) gdi_DeleteObject((HGDIOBJECT) hPen); } -void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) +static void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) { int i; INT32 x; @@ -812,7 +812,7 @@ void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) gdi_DeleteObject((HGDIOBJECT) hPen); } -void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) +static void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) { gdiBitmap* bitmap; rdpGdi* gdi = context->gdi; @@ -824,7 +824,7 @@ void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) memblt->nXSrc, memblt->nYSrc, gdi_rop3_code(memblt->bRop)); } -void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) +static void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) { BYTE* data; rdpBrush* brush; @@ -889,29 +889,30 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) gdi_SetTextColor(gdi->drawing->hdc, originalColor); } -void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) +static void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) { - WLog_ERR(TAG, "PolygonSC"); + WLog_VRB(TAG, "not implemented"); } -void gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) +static void gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) { - WLog_ERR(TAG, "PolygonCB"); + WLog_VRB(TAG, "not implemented"); } -void gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc) +static void gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc) { - WLog_ERR(TAG, "EllipseSC"); + WLog_VRB(TAG, "not implemented"); } -void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) +static void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) { - WLog_ERR(TAG, "EllipseCB"); + WLog_VRB(TAG, "not implemented"); } -void gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker) +static void gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker) { + } void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surfaceFrameMarker) @@ -934,7 +935,7 @@ void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface } } -void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) +static void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) { int i, j; int tx, ty; diff --git a/winpr/include/winpr/comm.h b/winpr/include/winpr/comm.h index d7b81a8d1..6f0a23077 100644 --- a/winpr/include/winpr/comm.h +++ b/winpr/include/winpr/comm.h @@ -174,29 +174,6 @@ #define BAUD_57600 ((DWORD)0x00040000) #define BAUD_USER ((DWORD)0x10000000) -/* Ntddser.h: http://msdn.microsoft.com/en-us/cc308432.aspx */ -#define SERIAL_BAUD_075 ((ULONG)0x00000001) -#define SERIAL_BAUD_110 ((ULONG)0x00000002) -#define SERIAL_BAUD_134_5 ((ULONG)0x00000004) -#define SERIAL_BAUD_150 ((ULONG)0x00000008) -#define SERIAL_BAUD_300 ((ULONG)0x00000010) -#define SERIAL_BAUD_600 ((ULONG)0x00000020) -#define SERIAL_BAUD_1200 ((ULONG)0x00000040) -#define SERIAL_BAUD_1800 ((ULONG)0x00000080) -#define SERIAL_BAUD_2400 ((ULONG)0x00000100) -#define SERIAL_BAUD_4800 ((ULONG)0x00000200) -#define SERIAL_BAUD_7200 ((ULONG)0x00000400) -#define SERIAL_BAUD_9600 ((ULONG)0x00000800) -#define SERIAL_BAUD_14400 ((ULONG)0x00001000) -#define SERIAL_BAUD_19200 ((ULONG)0x00002000) -#define SERIAL_BAUD_38400 ((ULONG)0x00004000) -#define SERIAL_BAUD_56K ((ULONG)0x00008000) -#define SERIAL_BAUD_128K ((ULONG)0x00010000) -#define SERIAL_BAUD_115200 ((ULONG)0x00020000) -#define SERIAL_BAUD_57600 ((ULONG)0x00040000) -#define SERIAL_BAUD_USER ((ULONG)0x10000000) - - #define DATABITS_5 ((WORD)0x0001) #define DATABITS_6 ((WORD)0x0002) #define DATABITS_7 ((WORD)0x0004) diff --git a/winpr/libwinpr/comm/comm.h b/winpr/libwinpr/comm/comm.h index 7714f3b55..772e62803 100644 --- a/winpr/libwinpr/comm/comm.h +++ b/winpr/libwinpr/comm/comm.h @@ -44,12 +44,17 @@ struct winpr_comm int fd_write_event; /* as of today, only used by _purge() */ CRITICAL_SECTION WriteLock; - /* permissive mode on errors if TRUE (default is FALSE). + /* permissive mode on errors. If TRUE (default is FALSE) + * CommDeviceIoControl always return TRUE. * - * Since not all features are supported, some devices and applications - * can still be functional on such errors. + * Not all features are supported yet and an error is then returned when + * an application turns them on (e.g: i/o buffers > 4096). It appeared + * though that devices and applications can be still functional on such + * errors. * - * TODO: command line switch or getting rid of it. + * see also: comm_ioctl.c + * + * FIXME: getting rid of this flag once all features supported. */ BOOL permissive; diff --git a/winpr/libwinpr/comm/comm_sercx2_sys.c b/winpr/libwinpr/comm/comm_sercx2_sys.c index 848f79647..8bdffbe97 100644 --- a/winpr/libwinpr/comm/comm_sercx2_sys.c +++ b/winpr/libwinpr/comm/comm_sercx2_sys.c @@ -163,10 +163,10 @@ SERIAL_DRIVER* SerCx2Sys_s() SERIAL_DRIVER* pSerialSys = SerialSys_s(); SERIAL_DRIVER* pSerCxSys = SerCxSys_s(); - _SerCx2Sys.set_baud_rate = pSerCxSys->set_baud_rate; - _SerCx2Sys.get_baud_rate = pSerCxSys->get_baud_rate; + _SerCx2Sys.set_baud_rate = pSerialSys->set_baud_rate; + _SerCx2Sys.get_baud_rate = pSerialSys->get_baud_rate; - _SerCx2Sys.get_properties = pSerCxSys->get_properties; + _SerCx2Sys.get_properties = pSerialSys->get_properties; _SerCx2Sys.set_line_control = pSerCxSys->set_line_control; _SerCx2Sys.get_line_control = pSerCxSys->get_line_control; diff --git a/winpr/libwinpr/comm/comm_sercx_sys.c b/winpr/libwinpr/comm/comm_sercx_sys.c index 877990c03..7d392d31e 100644 --- a/winpr/libwinpr/comm/comm_sercx_sys.c +++ b/winpr/libwinpr/comm/comm_sercx_sys.c @@ -30,207 +30,6 @@ #include "comm_serial_sys.h" -/* 0: B* (Linux termios) - * 1: CBR_* or actual baud rate - * 2: BAUD_* (similar to SERIAL_BAUD_*) - */ -static const speed_t _SERCX_SYS_BAUD_TABLE[][3] = { -#ifdef B0 - {B0, 0, 0}, /* hang up */ -#endif -#ifdef B50 - {B50, 50, 0}, -#endif -#ifdef B75 - {B75, 75, BAUD_075}, -#endif -#ifdef B110 - {B110, CBR_110, BAUD_110}, -#endif -#ifdef B134 - {B134, 134, 0 /*BAUD_134_5*/}, -#endif -#ifdef B150 - {B150, 150, BAUD_150}, -#endif -#ifdef B200 - {B200, 200, 0}, -#endif -#ifdef B300 - {B300, CBR_300, BAUD_300}, -#endif -#ifdef B600 - {B600, CBR_600, BAUD_600}, -#endif -#ifdef B1200 - {B1200, CBR_1200, BAUD_1200}, -#endif -#ifdef B1800 - {B1800, 1800, BAUD_1800}, -#endif -#ifdef B2400 - {B2400, CBR_2400, BAUD_2400}, -#endif -#ifdef B4800 - {B4800, CBR_4800, BAUD_4800}, -#endif - /* {, ,BAUD_7200} */ -#ifdef B9600 - {B9600, CBR_9600, BAUD_9600}, -#endif - /* {, CBR_14400, BAUD_14400}, /\* unsupported on Linux *\/ */ -#ifdef B19200 - {B19200, CBR_19200, BAUD_19200}, -#endif -#ifdef B38400 - {B38400, CBR_38400, BAUD_38400}, -#endif - /* {, CBR_56000, BAUD_56K}, /\* unsupported on Linux *\/ */ -#ifdef B57600 - {B57600, CBR_57600, BAUD_57600}, -#endif -#ifdef B115200 - {B115200, CBR_115200, BAUD_115200}, -#endif - /* {, CBR_128000, BAUD_128K}, /\* unsupported on Linux *\/ */ - /* {, CBR_256000, BAUD_USER}, /\* unsupported on Linux *\/ */ -#ifdef B230400 - {B230400, 230400, BAUD_USER}, -#endif -#ifdef B460800 - {B460800, 460800, BAUD_USER}, -#endif -#ifdef B500000 - {B500000, 500000, BAUD_USER}, -#endif -#ifdef B576000 - {B576000, 576000, BAUD_USER}, -#endif -#ifdef B921600 - {B921600, 921600, BAUD_USER}, -#endif -#ifdef B1000000 - {B1000000, 1000000, BAUD_USER}, -#endif -#ifdef B1152000 - {B1152000, 1152000, BAUD_USER}, -#endif -#ifdef B1500000 - {B1500000, 1500000, BAUD_USER}, -#endif -#ifdef B2000000 - {B2000000, 2000000, BAUD_USER}, -#endif -#ifdef B2500000 - {B2500000, 2500000, BAUD_USER}, -#endif -#ifdef B3000000 - {B3000000, 3000000, BAUD_USER}, -#endif -#ifdef B3500000 - {B3500000, 3500000, BAUD_USER}, -#endif -#ifdef B4000000 - {B4000000, 4000000, BAUD_USER}, /* __MAX_BAUD */ -#endif -}; - - -static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties) -{ - int i; - SERIAL_DRIVER* pSerialSys = SerialSys_s(); - - if (!pSerialSys->get_properties(pComm, pProperties)) - { - return FALSE; - } - - /* override some of the inherited properties from SerialSys ... */ - - pProperties->dwMaxBaud = BAUD_USER; - - pProperties->dwSettableBaud = 0; - for (i=0; _SERCX_SYS_BAUD_TABLE[i][0]<=__MAX_BAUD; i++) - { - pProperties->dwSettableBaud |= _SERCX_SYS_BAUD_TABLE[i][2]; - } - - return TRUE; -} - - -static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate) -{ - int i; - speed_t newSpeed; - struct termios futureState; - - ZeroMemory(&futureState, sizeof(struct termios)); - if (tcgetattr(pComm->fd, &futureState) < 0) /* NB: preserves current settings not directly handled by the Communication Functions */ - { - SetLastError(ERROR_IO_DEVICE); - return FALSE; - } - - for (i=0; _SERCX_SYS_BAUD_TABLE[i][0]<=__MAX_BAUD; i++) - { - if (_SERCX_SYS_BAUD_TABLE[i][1] == pBaudRate->BaudRate) - { - newSpeed = _SERCX_SYS_BAUD_TABLE[i][0]; - if (cfsetspeed(&futureState, newSpeed) < 0) - { - CommLog_Print(WLOG_WARN, "failed to set speed 0x%x (%lu)", newSpeed, pBaudRate->BaudRate); - return FALSE; - } - - assert(cfgetispeed(&futureState) == newSpeed); - - if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &futureState) < 0) - { - CommLog_Print(WLOG_WARN, "_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError()); - return FALSE; - } - - return TRUE; - } - } - - CommLog_Print(WLOG_WARN, "could not find a matching speed for the baud rate %lu", pBaudRate->BaudRate); - SetLastError(ERROR_INVALID_DATA); - return FALSE; -} - - -static BOOL _get_baud_rate(WINPR_COMM *pComm, SERIAL_BAUD_RATE *pBaudRate) -{ - int i; - speed_t currentSpeed; - struct termios currentState; - - ZeroMemory(¤tState, sizeof(struct termios)); - if (tcgetattr(pComm->fd, ¤tState) < 0) - { - SetLastError(ERROR_IO_DEVICE); - return FALSE; - } - - currentSpeed = cfgetispeed(¤tState); - - for (i=0; _SERCX_SYS_BAUD_TABLE[i][0]<=__MAX_BAUD; i++) - { - if (_SERCX_SYS_BAUD_TABLE[i][0] == currentSpeed) - { - pBaudRate->BaudRate = _SERCX_SYS_BAUD_TABLE[i][1]; - return TRUE; - } - } - - CommLog_Print(WLOG_WARN, "could not find a matching baud rate for the speed 0x%x", currentSpeed); - SetLastError(ERROR_INVALID_DATA); - return FALSE; -} - static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow) { SERIAL_HANDFLOW SerCxHandflow; @@ -373,9 +172,9 @@ static SERIAL_DRIVER _SerCxSys = { .id = SerialDriverSerCxSys, .name = _T("SerCx.sys"), - .set_baud_rate = _set_baud_rate, - .get_baud_rate = _get_baud_rate, - .get_properties = _get_properties, + .set_baud_rate = NULL, + .get_baud_rate = NULL, + .get_properties = NULL, .set_serial_chars = NULL, .get_serial_chars = NULL, .set_line_control = NULL, @@ -412,6 +211,11 @@ SERIAL_DRIVER* SerCxSys_s() /* _SerCxSys completed with inherited functions from SerialSys */ SERIAL_DRIVER* pSerialSys = SerialSys_s(); + _SerCxSys.set_baud_rate = pSerialSys->set_baud_rate; + _SerCxSys.get_baud_rate = pSerialSys->get_baud_rate; + + _SerCxSys.get_properties = pSerialSys->get_properties; + _SerCxSys.set_serial_chars = pSerialSys->set_serial_chars; _SerCxSys.get_serial_chars = pSerialSys->get_serial_chars; _SerCxSys.set_line_control = pSerialSys->set_line_control; diff --git a/winpr/libwinpr/comm/comm_serial_sys.c b/winpr/libwinpr/comm/comm_serial_sys.c index d32a22a73..223bf5c03 100644 --- a/winpr/libwinpr/comm/comm_serial_sys.c +++ b/winpr/libwinpr/comm/comm_serial_sys.c @@ -43,76 +43,114 @@ #define N_TTY_BUF_SIZE 4096 +#define _BAUD_TABLE_END 0010020 /* __MAX_BAUD + 1 */ -/* - * Linux, Windows speeds - * +/* 0: B* (Linux termios) + * 1: CBR_* or actual baud rate + * 2: BAUD_* (identical to SERIAL_BAUD_*) */ -static const speed_t _SERIAL_SYS_BAUD_TABLE[][2] = { +static const speed_t _BAUD_TABLE[][3] = { #ifdef B0 - {B0, 0}, /* hang up */ + {B0, 0, 0}, /* hang up */ +#endif +#ifdef B50 + {B50, 50, 0}, #endif -/* #ifdef B50 */ -/* {B50, }, /\* undefined by serial.sys *\/ */ -/* #endif */ #ifdef B75 - {B75, SERIAL_BAUD_075}, + {B75, 75, BAUD_075}, #endif #ifdef B110 - {B110, SERIAL_BAUD_110}, + {B110, CBR_110, BAUD_110}, +#endif +#ifdef B134 + {B134, 134, 0 /*BAUD_134_5*/}, #endif -/* #ifdef B134 */ -/* {B134, SERIAL_BAUD_134_5}, /\* TODO: might be the same? *\/ */ -/* #endif */ #ifdef B150 - {B150, SERIAL_BAUD_150}, + {B150, 150, BAUD_150}, +#endif +#ifdef B200 + {B200, 200, 0}, #endif -/* #ifdef B200 */ -/* {B200, }, /\* undefined by serial.sys *\/ */ -/* #endif */ #ifdef B300 - {B300, SERIAL_BAUD_300}, + {B300, CBR_300, BAUD_300}, #endif #ifdef B600 - {B600, SERIAL_BAUD_600}, + {B600, CBR_600, BAUD_600}, #endif #ifdef B1200 - {B1200, SERIAL_BAUD_1200}, + {B1200, CBR_1200, BAUD_1200}, #endif #ifdef B1800 - {B1800, SERIAL_BAUD_1800}, + {B1800, 1800, BAUD_1800}, #endif #ifdef B2400 - {B2400, SERIAL_BAUD_2400}, + {B2400, CBR_2400, BAUD_2400}, #endif #ifdef B4800 - {B4800, SERIAL_BAUD_4800}, + {B4800, CBR_4800, BAUD_4800}, #endif - /* {, SERIAL_BAUD_7200} /\* undefined on Linux *\/ */ + /* {, ,BAUD_7200} */ #ifdef B9600 - {B9600, SERIAL_BAUD_9600}, + {B9600, CBR_9600, BAUD_9600}, #endif - /* {, SERIAL_BAUD_14400} /\* undefined on Linux *\/ */ + /* {, CBR_14400, BAUD_14400}, /\* unsupported on Linux *\/ */ #ifdef B19200 - {B19200, SERIAL_BAUD_19200}, + {B19200, CBR_19200, BAUD_19200}, #endif #ifdef B38400 - {B38400, SERIAL_BAUD_38400}, + {B38400, CBR_38400, BAUD_38400}, #endif -/* {, SERIAL_BAUD_56K}, /\* undefined on Linux *\/ */ + /* {, CBR_56000, BAUD_56K}, /\* unsupported on Linux *\/ */ #ifdef B57600 - {B57600, SERIAL_BAUD_57600}, + {B57600, CBR_57600, BAUD_57600}, #endif - /* {, SERIAL_BAUD_128K} /\* undefined on Linux *\/ */ #ifdef B115200 - {B115200, SERIAL_BAUD_115200}, /* _SERIAL_MAX_BAUD */ + {B115200, CBR_115200, BAUD_115200}, #endif - - /* no greater speed defined by serial.sys */ + /* {, CBR_128000, BAUD_128K}, /\* unsupported on Linux *\/ */ + /* {, CBR_256000, BAUD_USER}, /\* unsupported on Linux *\/ */ +#ifdef B230400 + {B230400, 230400, BAUD_USER}, +#endif +#ifdef B460800 + {B460800, 460800, BAUD_USER}, +#endif +#ifdef B500000 + {B500000, 500000, BAUD_USER}, +#endif +#ifdef B576000 + {B576000, 576000, BAUD_USER}, +#endif +#ifdef B921600 + {B921600, 921600, BAUD_USER}, +#endif +#ifdef B1000000 + {B1000000, 1000000, BAUD_USER}, +#endif +#ifdef B1152000 + {B1152000, 1152000, BAUD_USER}, +#endif +#ifdef B1500000 + {B1500000, 1500000, BAUD_USER}, +#endif +#ifdef B2000000 + {B2000000, 2000000, BAUD_USER}, +#endif +#ifdef B2500000 + {B2500000, 2500000, BAUD_USER}, +#endif +#ifdef B3000000 + {B3000000, 3000000, BAUD_USER}, +#endif +#ifdef B3500000 + {B3500000, 3500000, BAUD_USER}, +#endif +#ifdef B4000000 + {B4000000, 4000000, BAUD_USER}, /* __MAX_BAUD */ +#endif + {_BAUD_TABLE_END, 0, 0} }; -#define _SERIAL_MAX_BAUD B115200 - static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties) { @@ -142,7 +180,8 @@ static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties) pProperties->dwMaxTxQueue = N_TTY_BUF_SIZE; pProperties->dwMaxRxQueue = N_TTY_BUF_SIZE; - pProperties->dwMaxBaud = SERIAL_BAUD_115200; /* _SERIAL_MAX_BAUD */ + /* FIXME: to be probe on the device? */ + pProperties->dwMaxBaud = BAUD_USER; /* FIXME: what about PST_RS232? see also: serial_struct */ pProperties->dwProvSubType = PST_UNSPECIFIED; @@ -156,9 +195,9 @@ static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties) pProperties->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY | SP_PARITY_CHECK | /*SP_RLSD |*/ SP_STOPBITS; pProperties->dwSettableBaud = 0; - for (i=0; _SERIAL_SYS_BAUD_TABLE[i][0]<=_SERIAL_MAX_BAUD; i++) + for (i=0; _BAUD_TABLE[i][0]<_BAUD_TABLE_END; i++) { - pProperties->dwSettableBaud |= _SERIAL_SYS_BAUD_TABLE[i][1]; + pProperties->dwSettableBaud |= _BAUD_TABLE[i][2]; } pProperties->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 /*| DATABITS_16 | DATABITS_16X*/; @@ -180,27 +219,29 @@ static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate) { int i; speed_t newSpeed; - struct termios upcomingTermios; + struct termios futureState; - ZeroMemory(&upcomingTermios, sizeof(struct termios)); - if (tcgetattr(pComm->fd, &upcomingTermios) < 0) + ZeroMemory(&futureState, sizeof(struct termios)); + if (tcgetattr(pComm->fd, &futureState) < 0) /* NB: preserves current settings not directly handled by the Communication Functions */ { SetLastError(ERROR_IO_DEVICE); return FALSE; } - for (i=0; _SERIAL_SYS_BAUD_TABLE[i][0]<=_SERIAL_MAX_BAUD; i++) + for (i=0; _BAUD_TABLE[i][0]<_BAUD_TABLE_END; i++) { - if (_SERIAL_SYS_BAUD_TABLE[i][1] == pBaudRate->BaudRate) + if (_BAUD_TABLE[i][1] == pBaudRate->BaudRate) { - newSpeed = _SERIAL_SYS_BAUD_TABLE[i][0]; - if (cfsetspeed(&upcomingTermios, newSpeed) < 0) + newSpeed = _BAUD_TABLE[i][0]; + if (cfsetspeed(&futureState, newSpeed) < 0) { - CommLog_Print(WLOG_WARN, "failed to set speed %u (%lu)", newSpeed, pBaudRate->BaudRate); + CommLog_Print(WLOG_WARN, "failed to set speed 0x%x (%lu)", newSpeed, pBaudRate->BaudRate); return FALSE; } - if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0) + assert(cfgetispeed(&futureState) == newSpeed); + + if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &futureState) < 0) { CommLog_Print(WLOG_WARN, "_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError()); return FALSE; @@ -231,11 +272,11 @@ static BOOL _get_baud_rate(WINPR_COMM *pComm, SERIAL_BAUD_RATE *pBaudRate) currentSpeed = cfgetispeed(¤tState); - for (i=0; _SERIAL_SYS_BAUD_TABLE[i][0]<=_SERIAL_MAX_BAUD; i++) + for (i=0; _BAUD_TABLE[i][0]<_BAUD_TABLE_END; i++) { - if (_SERIAL_SYS_BAUD_TABLE[i][0] == currentSpeed) + if (_BAUD_TABLE[i][0] == currentSpeed) { - pBaudRate->BaudRate = _SERIAL_SYS_BAUD_TABLE[i][1]; + pBaudRate->BaudRate = _BAUD_TABLE[i][1]; return TRUE; } } @@ -245,6 +286,7 @@ static BOOL _get_baud_rate(WINPR_COMM *pComm, SERIAL_BAUD_RATE *pBaudRate) return FALSE; } + /** * NOTE: Only XonChar and XoffChar are plenty supported with the Linux * N_TTY line discipline. diff --git a/winpr/libwinpr/comm/test/TestSetCommState.c b/winpr/libwinpr/comm/test/TestSetCommState.c index b1e825a5a..85fb8159a 100644 --- a/winpr/libwinpr/comm/test/TestSetCommState.c +++ b/winpr/libwinpr/comm/test/TestSetCommState.c @@ -132,76 +132,6 @@ static BOOL test_SerialSys(HANDLE hComm) return FALSE; } - /* Test 1 */ - dcb.BaudRate = SERIAL_BAUD_115200; - result = SetCommState(hComm, &dcb); - if (!result) - { - fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError()); - return FALSE; - } - - init_empty_dcb(&dcb); - result = GetCommState(hComm, &dcb); - if (!result) - { - fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError()); - return FALSE; - } - if (dcb.BaudRate != SERIAL_BAUD_115200) - { - fprintf(stderr, "SetCommState failure: could not set BaudRate=%d (SERIAL_BAUD_115200)\n", SERIAL_BAUD_115200); - return FALSE; - } - - /* Test 2 using a defferent baud rate */ - - dcb.BaudRate = SERIAL_BAUD_57600; - result = SetCommState(hComm, &dcb); - if (!result) - { - fprintf(stderr, "SetCommState failure: 0x%x\n", GetLastError()); - return FALSE; - } - - init_empty_dcb(&dcb); - result = GetCommState(hComm, &dcb); - if (!result) - { - fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError()); - return FALSE; - } - if (dcb.BaudRate != SERIAL_BAUD_57600) - { - fprintf(stderr, "SetCommState failure: could not set BaudRate=%d (SERIAL_BAUD_57600)\n", SERIAL_BAUD_57600); - return FALSE; - } - - /* Test 3 using an unsupported baud rate on Linux */ - dcb.BaudRate = SERIAL_BAUD_128K; - result = SetCommState(hComm, &dcb); - if (result) - { - fprintf(stderr, "SetCommState failure: unexpected support of BaudRate=%d (SERIAL_BAUD_128K)\n", SERIAL_BAUD_128K); - return FALSE; - } - - return TRUE; -} - -static BOOL test_SerCxSys(HANDLE hComm) -{ - DCB dcb; - BOOL result; - - init_empty_dcb(&dcb); - result = GetCommState(hComm, &dcb); - if (!result) - { - fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError()); - return FALSE; - } - /* Test 1 */ dcb.BaudRate = CBR_115200; result = SetCommState(hComm, &dcb); @@ -259,11 +189,16 @@ static BOOL test_SerCxSys(HANDLE hComm) return TRUE; } +static BOOL test_SerCxSys(HANDLE hComm) +{ + /* as of today there is no difference */ + return test_SerialSys(hComm); +} static BOOL test_SerCx2Sys(HANDLE hComm) { /* as of today there is no difference */ - return test_SerCxSys(hComm); + return test_SerialSys(hComm); } static BOOL test_generic(HANDLE hComm) diff --git a/winpr/libwinpr/utils/collections/LinkedList.c b/winpr/libwinpr/utils/collections/LinkedList.c index adb2af42f..939e85189 100644 --- a/winpr/libwinpr/utils/collections/LinkedList.c +++ b/winpr/libwinpr/utils/collections/LinkedList.c @@ -306,7 +306,7 @@ BOOL LinkedList_Enumerator_MoveNext(wLinkedList* list) { if (list->initial) list->initial = 0; - else + else if (list->current) list->current = list->current->next; if (!list->current) diff --git a/winpr/libwinpr/utils/test/TestLinkedList.c b/winpr/libwinpr/utils/test/TestLinkedList.c index 555d617e7..6697ae668 100644 --- a/winpr/libwinpr/utils/test/TestLinkedList.c +++ b/winpr/libwinpr/utils/test/TestLinkedList.c @@ -109,6 +109,33 @@ int TestLinkedList(int argc, char* argv[]) LinkedList_Free(list); + /* Test enumerator robustness */ + + /* enumerator on an empty list */ + list = LinkedList_New(); + LinkedList_Enumerator_Reset(list); + while (LinkedList_Enumerator_MoveNext(list)) + { + number = (int) (size_t) LinkedList_Enumerator_Current(list); + printf("\t%d\n", number); + } + printf("\n"); + LinkedList_Free(list); + + /* Use an enumerator without reset */ + list = LinkedList_New(); + LinkedList_AddFirst(list, (void*) (size_t) 4); + LinkedList_AddLast(list, (void*) (size_t) 5); + LinkedList_AddLast(list, (void*) (size_t) 6); + while (LinkedList_Enumerator_MoveNext(list)) + { + number = (int) (size_t) LinkedList_Enumerator_Current(list); + printf("\t%d\n", number); + } + printf("\n"); + LinkedList_Free(list); + + return 0; }