FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
comm_sercx2_sys.c
1
23#include <winpr/assert.h>
24#include <winpr/wlog.h>
25
26#include "comm_serial_sys.h"
27#include "comm_sercx_sys.h"
28
29#include "comm_sercx2_sys.h"
30
31/* http://msdn.microsoft.com/en-us/library/dn265347%28v=vs.85%29.aspx
32 *
33 * SerCx2 does not support special characters. SerCx2 always completes
34 * an IOCTL_SERIAL_SET_CHARS request with a STATUS_SUCCESS status
35 * code, but does not set any special characters or perform any other
36 * operation in response to this request. For an
37 * IOCTL_SERIAL_GET_CHARS request, SerCx2 sets all the character
38 * values in the SERIAL_CHARS structure to null, and completes the
39 * request with a STATUS_SUCCESS status code.
40 */
41
42static BOOL set_serial_chars(WINPR_ATTR_UNUSED WINPR_COMM* pComm,
43 WINPR_ATTR_UNUSED const SERIAL_CHARS* pSerialChars)
44{
45 WINPR_ASSERT(pComm);
46 WINPR_ASSERT(pSerialChars);
47
48 return TRUE;
49}
50
51static BOOL get_serial_chars(WINPR_ATTR_UNUSED WINPR_COMM* pComm, SERIAL_CHARS* pSerialChars)
52{
53 WINPR_ASSERT(pComm);
54 WINPR_ASSERT(pSerialChars);
55
56 ZeroMemory(pSerialChars, sizeof(SERIAL_CHARS));
57 return TRUE;
58}
59
60/* http://msdn.microsoft.com/en-us/library/windows/hardware/hh439605%28v=vs.85%29.aspx */
61/* FIXME: only using the Serial.sys' events, complete the support of the remaining events */
62static const ULONG SERCX2_SYS_SUPPORTED_EV_MASK =
63 SERIAL_EV_RXCHAR | SERIAL_EV_RXFLAG | SERIAL_EV_TXEMPTY | SERIAL_EV_CTS | SERIAL_EV_DSR |
64 SERIAL_EV_RLSD | SERIAL_EV_BREAK | SERIAL_EV_ERR | SERIAL_EV_RING |
65 /* SERIAL_EV_PERR | */
66 SERIAL_EV_RX80FULL /*|
67 SERIAL_EV_EVENT1 |
68 SERIAL_EV_EVENT2*/
69 ;
70
71/* use Serial.sys for basis (not SerCx.sys) */
72static BOOL set_wait_mask(WINPR_COMM* pComm, const ULONG* pWaitMask)
73{
74 const SERIAL_DRIVER* pSerialSys = SerialSys_s();
75
76 WINPR_ASSERT(pComm);
77 WINPR_ASSERT(pWaitMask);
78 WINPR_ASSERT(pSerialSys);
79
80 const ULONG possibleMask = *pWaitMask & SERCX2_SYS_SUPPORTED_EV_MASK;
81
82 if (possibleMask != *pWaitMask)
83 {
84 CommLog_Print(WLOG_WARN,
85 "Not all wait events supported (SerCx2.sys), requested events= 0x%08" PRIX32
86 ", possible events= 0x%08" PRIX32 "",
87 *pWaitMask, possibleMask);
88
89 /* FIXME: shall we really set the possibleMask and return FALSE? */
90 pComm->WaitEventMask = possibleMask;
91 return FALSE;
92 }
93
94 /* NB: All events that are supported by SerCx.sys are supported by Serial.sys*/
95 return pSerialSys->set_wait_mask(pComm, pWaitMask);
96}
97
98static BOOL purge(WINPR_COMM* pComm, const ULONG* pPurgeMask)
99{
100 const SERIAL_DRIVER* pSerialSys = SerialSys_s();
101
102 WINPR_ASSERT(pComm);
103 WINPR_ASSERT(pPurgeMask);
104 WINPR_ASSERT(pSerialSys);
105
106 /* http://msdn.microsoft.com/en-us/library/windows/hardware/ff546655%28v=vs.85%29.aspx */
107
108 if ((*pPurgeMask & SERIAL_PURGE_RXCLEAR) && !(*pPurgeMask & SERIAL_PURGE_RXABORT))
109 {
110 CommLog_Print(WLOG_WARN,
111 "Expecting SERIAL_PURGE_RXABORT since SERIAL_PURGE_RXCLEAR is set");
112 SetLastError(ERROR_INVALID_DEVICE_OBJECT_PARAMETER);
113 return FALSE;
114 }
115
116 if ((*pPurgeMask & SERIAL_PURGE_TXCLEAR) && !(*pPurgeMask & SERIAL_PURGE_TXABORT))
117 {
118 CommLog_Print(WLOG_WARN,
119 "Expecting SERIAL_PURGE_TXABORT since SERIAL_PURGE_TXCLEAR is set");
120 SetLastError(ERROR_INVALID_DEVICE_OBJECT_PARAMETER);
121 return FALSE;
122 }
123
124 return pSerialSys->purge(pComm, pPurgeMask);
125}
126
127/* specific functions only */
128static SERIAL_DRIVER SerCx2Sys = {
129 .id = SerialDriverSerCx2Sys,
130 .name = _T("SerCx2.sys"),
131 .set_baud_rate = NULL,
132 .get_baud_rate = NULL,
133 .get_properties = NULL,
134 .set_serial_chars = set_serial_chars,
135 .get_serial_chars = get_serial_chars,
136 .set_line_control = NULL,
137 .get_line_control = NULL,
138 .set_handflow = NULL,
139 .get_handflow = NULL,
140 .set_timeouts = NULL,
141 .get_timeouts = NULL,
142 .set_dtr = NULL,
143 .clear_dtr = NULL,
144 .set_rts = NULL,
145 .clear_rts = NULL,
146 .get_modemstatus = NULL,
147 .set_wait_mask = set_wait_mask,
148 .get_wait_mask = NULL,
149 .wait_on_mask = NULL,
150 .set_queue_size = NULL,
151 .purge = purge,
152 .get_commstatus = NULL,
153 .set_break_on = NULL,
154 .set_break_off = NULL,
155 .set_xoff = NULL, /* not supported by SerCx2.sys */
156 .set_xon = NULL, /* not supported by SerCx2.sys */
157 .get_dtrrts = NULL,
158 .config_size = NULL, /* not supported by SerCx2.sys */
159 .immediate_char = NULL, /* not supported by SerCx2.sys */
160 .reset_device = NULL, /* not supported by SerCx2.sys */
161};
162
163const SERIAL_DRIVER* SerCx2Sys_s(void)
164{
165 /* SerCx2Sys completed with inherited functions from SerialSys or SerCxSys */
166 const SERIAL_DRIVER* pSerialSys = SerialSys_s();
167 const SERIAL_DRIVER* pSerCxSys = SerCxSys_s();
168 if (!pSerialSys || !pSerCxSys)
169 return NULL;
170
171 SerCx2Sys.set_baud_rate = pSerialSys->set_baud_rate;
172 SerCx2Sys.get_baud_rate = pSerialSys->get_baud_rate;
173
174 SerCx2Sys.get_properties = pSerialSys->get_properties;
175
176 SerCx2Sys.set_line_control = pSerCxSys->set_line_control;
177 SerCx2Sys.get_line_control = pSerCxSys->get_line_control;
178
179 /* Only SERIAL_CTS_HANDSHAKE, SERIAL_RTS_CONTROL and SERIAL_RTS_HANDSHAKE flags are really
180 * required by SerCx2.sys http://msdn.microsoft.com/en-us/library/jj680685%28v=vs.85%29.aspx
181 */
182 SerCx2Sys.set_handflow = pSerialSys->set_handflow;
183 SerCx2Sys.get_handflow = pSerialSys->get_handflow;
184
185 SerCx2Sys.set_timeouts = pSerialSys->set_timeouts;
186 SerCx2Sys.get_timeouts = pSerialSys->get_timeouts;
187
188 SerCx2Sys.set_dtr = pSerialSys->set_dtr;
189 SerCx2Sys.clear_dtr = pSerialSys->clear_dtr;
190
191 SerCx2Sys.set_rts = pSerialSys->set_rts;
192 SerCx2Sys.clear_rts = pSerialSys->clear_rts;
193
194 SerCx2Sys.get_modemstatus = pSerialSys->get_modemstatus;
195
196 SerCx2Sys.set_wait_mask = pSerialSys->set_wait_mask;
197 SerCx2Sys.get_wait_mask = pSerialSys->get_wait_mask;
198 SerCx2Sys.wait_on_mask = pSerialSys->wait_on_mask;
199
200 SerCx2Sys.set_queue_size = pSerialSys->set_queue_size;
201
202 SerCx2Sys.get_commstatus = pSerialSys->get_commstatus;
203
204 SerCx2Sys.set_break_on = pSerialSys->set_break_on;
205 SerCx2Sys.set_break_off = pSerialSys->set_break_off;
206
207 SerCx2Sys.get_dtrrts = pSerialSys->get_dtrrts;
208
209 return &SerCx2Sys;
210}