2 * ReactOS mode console command
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define MAX_PORTNAME_LEN 20
29 #define MAX_COMPORT_NUM 10
30 #define MAX_COMPARAM_LEN 20
32 #define NUM_ELEMENTS(a) (sizeof(a)/sizeof(a[0]))
35 const TCHAR
* const usage_strings
[] = {
36 _T("Device Status: MODE [device] [/STATUS]"),
37 _T("Select code page: MODE CON[:] CP SELECT=yyy"),
38 _T("Code page status: MODE CON[:] CP [/STATUS]"),
39 _T("Display mode: MODE CON[:] [COLS=c] [LINES=n]"),
40 _T("Typematic rate: MODE CON[:] [RATE=r DELAY=d]"),
41 _T("Redirect printing: MODE LPTn[:]=COMm[:]"),
42 _T("Serial port: MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s]\n") \
43 _T(" [to=on|off] [xon=on|off] [odsr=on|off]\n") \
44 _T(" [octs=on|off] [dtr=on|off|hs]\n") \
45 _T(" [rts=on|off|hs|tg] [idsr=on|off]"),
48 const TCHAR
* const parity_strings
[] = {
49 _T("None"), // default
50 _T("Odd"), // only symbol in this set to have a 'd' in it
51 _T("Even"), // ... 'v' in it
52 _T("Mark"), // ... 'm' in it
53 _T("Space") // ... 's' and/or a 'c' in it
56 const TCHAR
* const control_strings
[] = { _T("OFF"), _T("ON"), _T("HANDSHAKE"), _T("TOGGLE") };
58 const TCHAR
* const stopbit_strings
[] = { _T("1"), _T("1.5"), _T("2") };
65 _tprintf(_T("\nConfigures system devices.\n\n"));
66 for (i
= 0; i
< NUM_ELEMENTS(usage_strings
); i
++) {
67 _tprintf(_T("%s\n"), usage_strings
[i
]);
80 if (QueryDosDevice(NULL
, buffer
, NUM_ELEMENTS(buffer
))) {
81 while (*ptr
!= '\0') {
83 if (_tcsstr(ptr
, _T("COM"))) {
84 _tprintf(_T(" Found serial device - %s\n"), ptr
);
85 } else if (_tcsstr(ptr
, _T("PRN"))) {
86 _tprintf(_T(" Found printer device - %s\n"), ptr
);
87 } else if (_tcsstr(ptr
, _T("LPT"))) {
88 _tprintf(_T(" Found parallel device - %s\n"), ptr
);
90 _tprintf(_T(" Found other device - %s\n"), ptr
);
95 _tprintf(_T(" ERROR: QueryDosDevice(...) failed.\n"));
100 int ShowParallelStatus(int nPortNum
)
103 TCHAR szPortName
[MAX_PORTNAME_LEN
];
105 _stprintf(szPortName
, _T("LPT%d"), nPortNum
);
106 _tprintf(_T("\nStatus for device LPT%d:\n"), nPortNum
);
107 _tprintf(_T("-----------------------\n"));
108 if (QueryDosDevice(szPortName
, buffer
, NUM_ELEMENTS(buffer
))) {
109 TCHAR
* ptr
= _tcsrchr(buffer
, '\\');
111 if (0 == _tcscmp(szPortName
, ++ptr
)) {
112 _tprintf(_T(" Printer output is not being rerouted.\n"));
114 _tprintf(_T(" Printer output is being rerouted to serial port %s\n"), ptr
);
118 _tprintf(_T(" QueryDosDevice(%s) returned unrecogised form %s.\n"), szPortName
, buffer
);
121 _tprintf(_T(" ERROR: QueryDosDevice(%s) failed.\n"), szPortName
);
126 int ShowConsoleStatus()
130 CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo
;
131 HANDLE hConsoleOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
133 _tprintf(_T("\nStatus for device CON:\n"));
134 _tprintf(_T("-----------------------\n"));
135 if (GetConsoleScreenBufferInfo(hConsoleOutput
, &ConsoleScreenBufferInfo
)) {
136 _tprintf(_T(" Lines: %d\n"), ConsoleScreenBufferInfo
.dwSize
.Y
);
137 _tprintf(_T(" Columns: %d\n"), ConsoleScreenBufferInfo
.dwSize
.X
);
139 if (SystemParametersInfo(SPI_GETKEYBOARDDELAY
, 0, &dwKbdDelay
, 0)) {
140 _tprintf(_T(" Keyboard delay: %ld\n"), dwKbdDelay
);
142 if (SystemParametersInfo(SPI_GETKEYBOARDSPEED
, 0, &dwKbdSpeed
, 0)) {
143 _tprintf(_T(" Keyboard rate: %ld\n"), dwKbdSpeed
);
145 _tprintf(_T(" Code page: %d\n"), GetConsoleOutputCP());
150 BOOL
SerialPortQuery(int nPortNum
, LPDCB pDCB
, LPCOMMTIMEOUTS pCommTimeouts
, BOOL bWrite
)
154 TCHAR szPortName
[MAX_PORTNAME_LEN
];
157 ASSERT(pCommTimeouts
);
159 _stprintf(szPortName
, _T("COM%d"), nPortNum
);
160 hPort
= CreateFile(szPortName
,
161 GENERIC_READ
|GENERIC_WRITE
,
166 NULL
); // no template
168 if (hPort
== INVALID_HANDLE_VALUE
) {
169 _tprintf(_T("Illegal device name - %s\n"), szPortName
);
170 _tprintf(_T("Last error = 0x%lx\n"), GetLastError());
174 result
= SetCommState(hPort
, pDCB
);
176 result
= GetCommState(hPort
, pDCB
);
179 _tprintf(_T("Failed to %s the status for device COM%d:\n"), bWrite
? _T("set") : _T("get"), nPortNum
);
184 result
= SetCommTimeouts(hPort
, pCommTimeouts
);
186 result
= GetCommTimeouts(hPort
, pCommTimeouts
);
189 _tprintf(_T("Failed to %s Timeout status for device COM%d:\n"), bWrite
? _T("set") : _T("get"), nPortNum
);
198 int ShowSerialStatus(int nPortNum
)
201 COMMTIMEOUTS CommTimeouts
;
203 if (!SerialPortQuery(nPortNum
, &dcb
, &CommTimeouts
, FALSE
)) {
206 if (dcb
.Parity
> NUM_ELEMENTS(parity_strings
)) {
207 _tprintf(_T("ERROR: Invalid value for Parity Bits %d:\n"), dcb
.Parity
);
210 if (dcb
.StopBits
> NUM_ELEMENTS(stopbit_strings
)) {
211 _tprintf(_T("ERROR: Invalid value for Stop Bits %d:\n"), dcb
.StopBits
);
214 _tprintf(_T("\nStatus for device COM%d:\n"), nPortNum
);
215 _tprintf(_T("-----------------------\n"));
216 _tprintf(_T(" Baud: %ld\n"), dcb
.BaudRate
);
217 _tprintf(_T(" Parity: %s\n"), parity_strings
[dcb
.Parity
]);
218 _tprintf(_T(" Data Bits: %d\n"), dcb
.ByteSize
);
219 _tprintf(_T(" Stop Bits: %s\n"), stopbit_strings
[dcb
.StopBits
]);
220 _tprintf(_T(" Timeout: %s\n"), CommTimeouts
.ReadIntervalTimeout
? _T("ON") : _T("OFF"));
221 _tprintf(_T(" XON/XOFF: %s\n"), dcb
.fOutX
? _T("ON") : _T("OFF"));
222 _tprintf(_T(" CTS handshaking: %s\n"), dcb
.fOutxCtsFlow
? _T("ON") : _T("OFF"));
223 _tprintf(_T(" DSR handshaking: %s\n"), dcb
.fOutxDsrFlow
? _T("ON") : _T("OFF"));
224 _tprintf(_T(" DSR sensitivity: %s\n"), dcb
.fDsrSensitivity
? _T("ON") : _T("OFF"));
225 _tprintf(_T(" DTR circuit: %s\n"), control_strings
[dcb
.fDtrControl
]);
226 _tprintf(_T(" RTS circuit: %s\n"), control_strings
[dcb
.fRtsControl
]);
230 int SetParallelState(int nPortNum
)
232 TCHAR szPortName
[MAX_PORTNAME_LEN
];
233 TCHAR szTargetPath
[MAX_PORTNAME_LEN
];
235 _stprintf(szPortName
, _T("LPT%d"), nPortNum
);
236 _stprintf(szTargetPath
, _T("COM%d"), nPortNum
);
237 if (!DefineDosDevice(DDD_REMOVE_DEFINITION
, szPortName
, szTargetPath
)) {
238 DWORD error
= GetLastError();
240 _tprintf(_T("SetParallelState(%d) - DefineDosDevice(%s) failed: 0x%lx\n"), nPortNum
, szPortName
, error
);
247 \Device\NamedPipe\Spooler\LPT1
248 BOOL DefineDosDevice(
249 DWORD dwFlags, // options
250 LPCTSTR lpDeviceName, // device name
251 LPCTSTR lpTargetPath // path string
253 DWORD QueryDosDevice(
254 LPCTSTR lpDeviceName, // MS-DOS device name string
255 LPTSTR lpTargetPath, // query results buffer
256 DWORD ucchMax // maximum size of buffer
260 int SetConsoleState()
263 "Select code page: MODE CON[:] CP SELECT=yyy",
264 "Code page status: MODE CON[:] CP [/STATUS]",
265 "Display mode: MODE CON[:] [COLS=c] [LINES=n]",
266 "Typematic rate: MODE CON[:] [RATE=r DELAY=d]",
272 int ExtractModeSerialParams(const TCHAR
* param
)
274 if ( _tcsstr(param
, _T("OFF"))) {
276 } else if (_tcsstr(param
, _T("ON"))) {
278 } else if (_tcsstr(param
, _T("HS"))) {
280 } else if (_tcsstr(param
, _T("TG"))) {
286 int SetSerialState(int nPortNum
, int args
, TCHAR
*argv
[])
291 COMMTIMEOUTS CommTimeouts
;
292 TCHAR buf
[MAX_COMPARAM_LEN
+1];
294 if (SerialPortQuery(nPortNum
, &dcb
, &CommTimeouts
, FALSE
)) {
295 for (arg
= 2; arg
< args
; arg
++) {
296 if (_tcslen(argv
[arg
]) > MAX_COMPARAM_LEN
) {
297 _tprintf(_T("Invalid parameter (too long) - %s\n"), argv
[arg
]);
300 _tcscpy(buf
, argv
[arg
]);
302 if (_tcsstr(buf
, _T("baud="))) {
303 _tscanf(buf
+5, "%lu", &dcb
.BaudRate
);
304 } else if (_tcsstr(buf
, _T("parity="))) {
305 if (_tcschr(buf
, 'D')) {
307 } else if (_tcschr(buf
, 'V')) {
309 } else if (_tcschr(buf
, 'M')) {
311 } else if (_tcschr(buf
, 'S')) {
316 } else if (_tcsstr(buf
, _T("data="))) {
317 _tscanf(buf
+5, "%lu", &dcb
.ByteSize
);
318 } else if (_tcsstr(buf
, _T("stop="))) {
319 if (_tcschr(buf
, '5')) {
321 } else if (_tcschr(buf
, '2')) {
326 } else if (_tcsstr(buf
, _T("to="))) { // to=on|off
327 value
= ExtractModeSerialParams(buf
);
330 goto invalid_serial_parameter
;
332 } else if (_tcsstr(buf
, _T("xon="))) { // xon=on|off
333 value
= ExtractModeSerialParams(buf
);
338 goto invalid_serial_parameter
;
340 } else if (_tcsstr(buf
, _T("odsr="))) { // odsr=on|off
341 value
= ExtractModeSerialParams(buf
);
343 dcb
.fOutxDsrFlow
= value
;
345 goto invalid_serial_parameter
;
347 } else if (_tcsstr(buf
, _T("octs="))) { // octs=on|off
348 value
= ExtractModeSerialParams(buf
);
350 dcb
.fOutxCtsFlow
= value
;
352 goto invalid_serial_parameter
;
354 } else if (_tcsstr(buf
, _T("dtr="))) { // dtr=on|off|hs
355 value
= ExtractModeSerialParams(buf
);
357 dcb
.fDtrControl
= value
;
359 goto invalid_serial_parameter
;
361 } else if (_tcsstr(buf
, _T("rts="))) { // rts=on|off|hs|tg
362 value
= ExtractModeSerialParams(buf
);
364 dcb
.fRtsControl
= value
;
366 goto invalid_serial_parameter
;
368 } else if (_tcsstr(buf
, _T("idsr="))) { // idsr=on|off
369 value
= ExtractModeSerialParams(buf
);
371 dcb
.fDsrSensitivity
= value
;
373 goto invalid_serial_parameter
;
376 invalid_serial_parameter
:;
377 _tprintf(_T("Invalid parameter - %s\n"), buf
);
381 SerialPortQuery(nPortNum
, &dcb
, &CommTimeouts
, TRUE
);
386 int find_portnum(const TCHAR
* cmdverb
)
390 if (cmdverb
[3] >= '0' && cmdverb
[3] <= '9') {
391 portnum
= cmdverb
[3] - '0';
392 if (cmdverb
[4] >= '0' && cmdverb
[4] <= '9') {
394 portnum
+= cmdverb
[4] - '0';
400 int main(int argc
, TCHAR
*argv
[])
403 TCHAR param1
[MAX_COMPARAM_LEN
+1];
404 TCHAR param2
[MAX_COMPARAM_LEN
+1];
407 if (_tcslen(argv
[1]) > MAX_COMPARAM_LEN
) {
408 _tprintf(_T("Invalid parameter (too long) - %s\n"), argv
[1]);
411 _tcscpy(param1
, argv
[1]);
414 if (_tcslen(argv
[2]) > MAX_COMPARAM_LEN
) {
415 _tprintf(_T("Invalid parameter (too long) - %s\n"), argv
[2]);
418 _tcscpy(param2
, argv
[2]);
423 if (_tcsstr(param1
, _T("/?")) || _tcsstr(param1
, _T("-?"))) {
425 } else if (_tcsstr(param1
, _T("/status"))) {
427 } else if (_tcsstr(param1
, _T("lpt"))) {
428 nPortNum
= find_portnum(param1
);
430 return ShowParallelStatus(nPortNum
);
431 } else if (_tcsstr(param1
, _T("con"))) {
432 return ShowConsoleStatus();
433 } else if (_tcsstr(param1
, _T("com"))) {
434 nPortNum
= find_portnum(param1
);
435 if (nPortNum
!= -1) {
436 if (param2
[0] == '\0' || _tcsstr(param2
, _T("/status"))) {
437 return ShowSerialStatus(nPortNum
);
439 return SetSerialState(nPortNum
, argc
, argv
);
443 _tprintf(_T("Invalid parameter - %s\n"), param1
);
450 ShowParallelStatus(1);
451 for (nPortNum = 0; nPortNum < MAX_COMPORT_NUM; nPortNum++) {
452 ShowSerialStatus(nPortNum + 1);