Merge branch 'master' of github.com:awakecoding/FreeRDP into shadow

This commit is contained in:
Marc-André Moreau 2014-09-25 10:35:14 -04:00
commit c762a4d5a2
12 changed files with 196 additions and 389 deletions

View File

@ -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 */

View File

@ -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:<device>\n");
printf("Printer Redirection: /printer:<device>,<driver>\n");
printf("Serial Port Redirection: /serial:<device>\n");
printf("Serial Port Redirection: /serial:<name>,<device>,[SerCx2|SerCx|Serial],[permissive]\n");
printf("Serial Port Redirection: /serial:COM1,/dev/ttyS0\n");
printf("Parallel Port Redirection: /parallel:<device>\n");
printf("Printer Redirection: /printer:<device>,<driver>\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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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(&currentState, sizeof(struct termios));
if (tcgetattr(pComm->fd, &currentState) < 0)
{
SetLastError(ERROR_IO_DEVICE);
return FALSE;
}
currentSpeed = cfgetispeed(&currentState);
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;

View File

@ -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(&currentState);
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.

View File

@ -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)

View File

@ -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)

View File

@ -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;
}