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: %d\n"), dwKbdDelay
);
142 if (SystemParametersInfo(SPI_GETKEYBOARDSPEED
, 0, &dwKbdSpeed
, 0)) {
143 _tprintf(_T(" Keyboard rate: %d\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
== (HANDLE
)-1) {
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
)
202 COMMTIMEOUTS CommTimeouts
;
203 TCHAR szPortName
[MAX_PORTNAME_LEN
];
205 if (!SerialPortQuery(nPortNum
, &dcb
, &CommTimeouts
, FALSE
)) {
208 if (dcb
.Parity
> NUM_ELEMENTS(parity_strings
)) {
209 _tprintf(_T("ERROR: Invalid value for Parity Bits %d:\n"), dcb
.Parity
);
212 if (dcb
.StopBits
> NUM_ELEMENTS(stopbit_strings
)) {
213 _tprintf(_T("ERROR: Invalid value for Stop Bits %d:\n"), dcb
.StopBits
);
216 _tprintf(_T("\nStatus for device COM%d:\n"), nPortNum
);
217 _tprintf(_T("-----------------------\n"));
218 _tprintf(_T(" Baud: %d\n"), dcb
.BaudRate
);
219 _tprintf(_T(" Parity: %s\n"), parity_strings
[dcb
.Parity
]);
220 _tprintf(_T(" Data Bits: %d\n"), dcb
.ByteSize
);
221 _tprintf(_T(" Stop Bits: %s\n"), stopbit_strings
[dcb
.StopBits
]);
222 _tprintf(_T(" Timeout: %s\n"), CommTimeouts
.ReadIntervalTimeout
? _T("ON") : _T("OFF"));
223 _tprintf(_T(" XON/XOFF: %s\n"), dcb
.fOutX
? _T("ON") : _T("OFF"));
224 _tprintf(_T(" CTS handshaking: %s\n"), dcb
.fOutxCtsFlow
? _T("ON") : _T("OFF"));
225 _tprintf(_T(" DSR handshaking: %s\n"), dcb
.fOutxDsrFlow
? _T("ON") : _T("OFF"));
226 _tprintf(_T(" DSR sensitivity: %s\n"), dcb
.fDsrSensitivity
? _T("ON") : _T("OFF"));
227 _tprintf(_T(" DTR circuit: %s\n"), control_strings
[dcb
.fDtrControl
]);
228 _tprintf(_T(" RTS circuit: %s\n"), control_strings
[dcb
.fRtsControl
]);
232 int SetParallelState(int nPortNum
)
234 TCHAR szPortName
[MAX_PORTNAME_LEN
];
235 TCHAR szTargetPath
[MAX_PORTNAME_LEN
];
237 _stprintf(szPortName
, _T("LPT%d"), nPortNum
);
238 _stprintf(szTargetPath
, _T("COM%d"), nPortNum
);
239 if (!DefineDosDevice(DDD_REMOVE_DEFINITION
, szPortName
, szTargetPath
)) {
240 DWORD error
= GetLastError();
242 _tprintf(_T("SetParallelState(%d) - DefineDosDevice(%s) failed: %x\n"), nPortNum
, error
);
249 \Device\NamedPipe\Spooler\LPT1
250 BOOL DefineDosDevice(
251 DWORD dwFlags, // options
252 LPCTSTR lpDeviceName, // device name
253 LPCTSTR lpTargetPath // path string
255 DWORD QueryDosDevice(
256 LPCTSTR lpDeviceName, // MS-DOS device name string
257 LPTSTR lpTargetPath, // query results buffer
258 DWORD ucchMax // maximum size of buffer
262 int SetConsoleState()
265 "Select code page: MODE CON[:] CP SELECT=yyy",
266 "Code page status: MODE CON[:] CP [/STATUS]",
267 "Display mode: MODE CON[:] [COLS=c] [LINES=n]",
268 "Typematic rate: MODE CON[:] [RATE=r DELAY=d]",
274 int ExtractModeSerialParams(const TCHAR
* param
)
276 if ( _tcsstr(param
, _T("OFF"))) {
278 } else if (_tcsstr(param
, _T("ON"))) {
280 } else if (_tcsstr(param
, _T("HS"))) {
282 } else if (_tcsstr(param
, _T("TG"))) {
288 int SetSerialState(int nPortNum
, int args
, TCHAR
*argv
[])
293 COMMTIMEOUTS CommTimeouts
;
294 TCHAR buf
[MAX_COMPARAM_LEN
+1];
296 if (SerialPortQuery(nPortNum
, &dcb
, &CommTimeouts
, FALSE
)) {
297 for (arg
= 2; arg
< args
; arg
++) {
298 if (_tcslen(argv
[arg
]) > MAX_COMPARAM_LEN
) {
299 _tprintf(_T("Invalid parameter (too long) - %s\n"), argv
[arg
]);
302 _tcscpy(buf
, argv
[arg
]);
304 if (_tcsstr(buf
, _T("baud="))) {
305 _tscanf(buf
+5, "%lu", &dcb
.BaudRate
);
306 } else if (_tcsstr(buf
, _T("parity="))) {
307 if (_tcschr(buf
, 'D')) {
309 } else if (_tcschr(buf
, 'V')) {
311 } else if (_tcschr(buf
, 'M')) {
313 } else if (_tcschr(buf
, 'S')) {
318 } else if (_tcsstr(buf
, _T("data="))) {
319 _tscanf(buf
+5, "%lu", &dcb
.ByteSize
);
320 } else if (_tcsstr(buf
, _T("stop="))) {
321 if (_tcschr(buf
, '5')) {
323 } else if (_tcschr(buf
, '2')) {
328 } else if (_tcsstr(buf
, _T("to="))) { // to=on|off
329 value
= ExtractModeSerialParams(buf
);
332 goto invalid_serial_parameter
;
334 } else if (_tcsstr(buf
, _T("xon="))) { // xon=on|off
335 value
= ExtractModeSerialParams(buf
);
340 goto invalid_serial_parameter
;
342 } else if (_tcsstr(buf
, _T("odsr="))) { // odsr=on|off
343 value
= ExtractModeSerialParams(buf
);
345 dcb
.fOutxDsrFlow
= value
;
347 goto invalid_serial_parameter
;
349 } else if (_tcsstr(buf
, _T("octs="))) { // octs=on|off
350 value
= ExtractModeSerialParams(buf
);
352 dcb
.fOutxCtsFlow
= value
;
354 goto invalid_serial_parameter
;
356 } else if (_tcsstr(buf
, _T("dtr="))) { // dtr=on|off|hs
357 value
= ExtractModeSerialParams(buf
);
359 dcb
.fDtrControl
= value
;
361 goto invalid_serial_parameter
;
363 } else if (_tcsstr(buf
, _T("rts="))) { // rts=on|off|hs|tg
364 value
= ExtractModeSerialParams(buf
);
366 dcb
.fRtsControl
= value
;
368 goto invalid_serial_parameter
;
370 } else if (_tcsstr(buf
, _T("idsr="))) { // idsr=on|off
371 value
= ExtractModeSerialParams(buf
);
373 dcb
.fDsrSensitivity
= value
;
375 goto invalid_serial_parameter
;
378 invalid_serial_parameter
:;
379 _tprintf(_T("Invalid parameter - %s\n"), buf
);
383 SerialPortQuery(nPortNum
, &dcb
, &CommTimeouts
, TRUE
);
388 int find_portnum(const TCHAR
* cmdverb
)
392 if (cmdverb
[3] >= '0' && cmdverb
[3] <= '9') {
393 portnum
= cmdverb
[3] - '0';
394 if (cmdverb
[4] >= '0' && cmdverb
[4] <= '9') {
396 portnum
+= cmdverb
[4] - '0';
402 int main(int argc
, TCHAR
*argv
[])
405 TCHAR param1
[MAX_COMPARAM_LEN
+1];
406 TCHAR param2
[MAX_COMPARAM_LEN
+1];
409 if (_tcslen(argv
[1]) > MAX_COMPARAM_LEN
) {
410 _tprintf(_T("Invalid parameter (too long) - %s\n"), argv
[1]);
413 _tcscpy(param1
, argv
[1]);
416 if (_tcslen(argv
[2]) > MAX_COMPARAM_LEN
) {
417 _tprintf(_T("Invalid parameter (too long) - %s\n"), argv
[2]);
420 _tcscpy(param2
, argv
[2]);
425 if (_tcsstr(param1
, _T("/?")) || _tcsstr(param1
, _T("-?"))) {
427 } else if (_tcsstr(param1
, _T("/status"))) {
429 } else if (_tcsstr(param1
, _T("lpt"))) {
430 nPortNum
= find_portnum(param1
);
432 return ShowParallelStatus(nPortNum
);
433 } else if (_tcsstr(param1
, _T("con"))) {
434 return ShowConsoleStatus();
435 } else if (_tcsstr(param1
, _T("com"))) {
436 nPortNum
= find_portnum(param1
);
437 if (nPortNum
!= -1) {
438 if (param2
[0] == '\0' || _tcsstr(param2
, _T("/status"))) {
439 return ShowSerialStatus(nPortNum
);
441 return SetSerialState(nPortNum
, argc
, argv
);
445 _tprintf(_T("Invalid parameter - %s\n"), param1
);
452 ShowParallelStatus(1);
453 for (nPortNum = 0; nPortNum < MAX_COMPORT_NUM; nPortNum++) {
454 ShowSerialStatus(nPortNum + 1);