ReactOS 0.4.17-dev-1133-gc25e4fd
mode.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Mode Utility
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Provides fast mode setup for DOS devices.
5 * COPYRIGHT: Copyright 2002 Robert Dickenson <robd@reactos.org>
6 * Copyright 2016-2026 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
7 */
8/*
9 * ReactOS mode console command
10 *
11 * mode.c
12 *
13 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <stdio.h>
31#include <stdlib.h>
32
33#include <windef.h>
34#include <winbase.h>
35#include <wincon.h>
36#include <winuser.h>
37
38#include <conutils.h>
39
40#include "resource.h"
41
42#define MAX_PORTNAME_LEN 20
43
44#define ASSERT(a)
45
46/*** For fixes, see also network/net/main.c ***/
47// VOID PrintPadding(...)
48VOID
52 IN UINT uID,
53 ...)
54{
55 INT Len;
57
58#define MAX_BUFFER_SIZE 4096
59 INT i;
60 WCHAR szMsgBuffer[MAX_BUFFER_SIZE];
61
64 va_end(args);
65
66 ConPuts(Stream, L"\n");
67 for (i = 0; i < Len; i++)
68 szMsgBuffer[i] = L'-';
69 szMsgBuffer[Len] = UNICODE_NULL;
70
71 ConStreamWrite(Stream, szMsgBuffer, Len);
72}
73
75{
76 WCHAR buffer[250];
77 WCHAR szPortName[MAX_PORTNAME_LEN];
78
79 _swprintf(szPortName, L"LPT%d", nPortNum);
80
81 ConPuts(StdOut, L"\n");
83 ConPuts(StdOut, L"\n");
84
85 if (QueryDosDeviceW(szPortName, buffer, ARRAYSIZE(buffer)))
86 {
87 PWSTR ptr = wcsrchr(buffer, L'\\');
88 if (ptr != NULL)
89 {
90 if (_wcsicmp(szPortName, ++ptr) == 0)
92 else
94
95 return 0;
96 }
97 else
98 {
100 }
101 }
102 else
103 {
104 ConPrintf(StdErr, L"ERROR: QueryDosDeviceW(%s) failed: 0x%lx\n", szPortName, GetLastError());
105 }
106 ConPuts(StdOut, L"\n");
107
108 return 1;
109}
110
112{
113 WCHAR szPortName[MAX_PORTNAME_LEN];
114 WCHAR szTargetPath[MAX_PORTNAME_LEN];
115
116 _swprintf(szPortName, L"LPT%d", nPortNum);
117 _swprintf(szTargetPath, L"COM%d", nPortNum);
118 if (!DefineDosDeviceW(DDD_REMOVE_DEFINITION, szPortName, szTargetPath))
119 {
120 ConPrintf(StdErr, L"ERROR: SetParallelState(%d) - DefineDosDevice(%s) failed: 0x%lx\n", nPortNum, szPortName, GetLastError());
121 }
122
123 ShowParallelStatus(nPortNum);
124 return 0;
125}
126
127
128static PCWSTR
130{
131 INT value, skip = 0;
132
133 value = swscanf(argStr, L"%lu%n", Number, &skip);
134 if (!value) return NULL;
135 argStr += skip;
136 return argStr;
137}
138
139
140/*
141 \??\COM1
142 \Device\NamedPipe\Spooler\LPT1
143BOOL DefineDosDevice(
144 DWORD dwFlags, // options
145 LPCTSTR lpDeviceName, // device name
146 LPCTSTR lpTargetPath // path string
147);
148DWORD QueryDosDevice(
149 LPCTSTR lpDeviceName, // MS-DOS device name string
150 LPTSTR lpTargetPath, // query results buffer
151 DWORD ucchMax // maximum size of buffer
152);
153 */
154
155
156/*****************************************************************************\
157 ** C O N S O L E H E L P E R S **
158\*****************************************************************************/
159
161{
164 DWORD dwKbdDelay, dwKbdSpeed;
165
166 ConPuts(StdOut, L"\n");
168 ConPuts(StdOut, L"\n");
169
170 if (GetConsoleScreenBufferInfo(hConOut, &csbi))
171 {
174 }
175 if (SystemParametersInfoW(SPI_GETKEYBOARDSPEED, 0, &dwKbdSpeed, 0))
176 {
178 }
179 if (SystemParametersInfoW(SPI_GETKEYBOARDDELAY, 0, &dwKbdDelay, 0))
180 {
182 }
184 ConPuts(StdOut, L"\n");
185
186 return 0;
187}
188
190{
191 ConPuts(StdOut, L"\n");
193 ConPuts(StdOut, L"\n");
194
196 ConPuts(StdOut, L"\n");
197
198 return 0;
199}
200
201static VOID
203 IN HANDLE hConOut,
205{
206 COORD coPos;
207 DWORD dwWritten;
208
209 coPos.X = 0;
210 coPos.Y = 0;
211 FillConsoleOutputAttribute(hConOut, pcsbi->wAttributes,
212 pcsbi->dwSize.X * pcsbi->dwSize.Y,
213 coPos, &dwWritten);
214 FillConsoleOutputCharacterW(hConOut, L' ',
215 pcsbi->dwSize.X * pcsbi->dwSize.Y,
216 coPos, &dwWritten);
217 SetConsoleCursorPosition(hConOut, coPos);
218}
219
220/*
221 * See, or adjust if needed, subsystems/mvdm/ntvdm/console/video.c!ResizeTextConsole()
222 * for more information.
223 */
224static BOOL
226 IN HANDLE hConOut,
229{
232 SMALL_RECT ConRect;
233
234 /*
235 * Use this trick to effectively resize the console buffer and window,
236 * because:
237 * - SetConsoleScreenBufferSize fails if the new console screen buffer size
238 * is smaller than the current console window size, and:
239 * - SetConsoleWindowInfo fails if the new console window size is larger
240 * than the current console screen buffer size.
241 */
242
243 /* Resize the screen buffer only if needed */
244 if (Resolution.X != pcsbi->dwSize.X || Resolution.Y != pcsbi->dwSize.Y)
245 {
246 Width = pcsbi->srWindow.Right - pcsbi->srWindow.Left + 1;
247 Height = pcsbi->srWindow.Bottom - pcsbi->srWindow.Top + 1;
248
249 /*
250 * If the current console window is too large for
251 * the new screen buffer, resize it first.
252 */
253 if (Width > Resolution.X || Height > Resolution.Y)
254 {
255 /*
256 * NOTE: This is not a problem if we move the window back to (0,0)
257 * because when we resize the screen buffer, the window will move back
258 * to where the cursor is. Or, if the screen buffer is not resized,
259 * when we readjust again the window, we will move back to a correct
260 * position. This is what we wanted after all...
261 */
262 ConRect.Left = ConRect.Top = 0;
263 ConRect.Right = ConRect.Left + min(Width , Resolution.X) - 1;
264 ConRect.Bottom = ConRect.Top + min(Height, Resolution.Y) - 1;
265
266 Success = SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
267 if (!Success) return FALSE;
268 }
269
270 /*
271 * Now resize the screen buffer.
272 *
273 * SetConsoleScreenBufferSize automatically takes into account the current
274 * cursor position when it computes starting which row it should copy text
275 * when resizing the screen buffer, and scrolls the console window such that
276 * the cursor is placed in it again. We therefore do not need to care about
277 * the cursor position and do the maths ourselves.
278 */
280 if (!Success) return FALSE;
281
282 /*
283 * Setting a new screen buffer size can change other information,
284 * so update the console screen buffer information.
285 */
286 GetConsoleScreenBufferInfo(hConOut, pcsbi);
287 }
288
289 /* Always resize the console window within the permitted maximum size */
290 Width = min(Resolution.X, pcsbi->dwMaximumWindowSize.X);
291 Height = min(Resolution.Y, pcsbi->dwMaximumWindowSize.Y);
292 ConRect.Left = 0;
293 ConRect.Right = ConRect.Left + Width - 1;
294 ConRect.Bottom = max(pcsbi->dwCursorPosition.Y, Height - 1);
295 ConRect.Top = ConRect.Bottom - Height + 1;
296
297 SetConsoleWindowInfo(hConOut, TRUE, &ConRect);
298
299 /* Update the console screen buffer information */
300 GetConsoleScreenBufferInfo(hConOut, pcsbi);
301
302 return TRUE;
303}
304
306{
307 PCWSTR argStr = ArgStr;
308
312 DWORD value;
313
314 if (!GetConsoleScreenBufferInfo(hConOut, &csbi))
315 {
316 // TODO: Error message?
317 return 0;
318 }
319
320 Resolution = csbi.dwSize;
321
322 /* Parse the column number (only MANDATORY argument) */
323 value = 0;
324 argStr = ParseNumber(argStr, &value);
325 if (!argStr) goto invalid_parameter;
327
328 /* Parse the line number (OPTIONAL argument) */
329 while (*argStr == L' ') argStr++;
330 if (!*argStr) goto Quit;
331 if (*argStr++ != L',') goto invalid_parameter;
332 while (*argStr == L' ') argStr++;
333
334 value = 0;
335 argStr = ParseNumber(argStr, &value);
336 if (!argStr) goto invalid_parameter;
338
339 /* This should be the end of the string */
340 while (*argStr == L' ') argStr++;
341 if (*argStr) goto invalid_parameter;
342
343Quit:
344 ClearScreen(hConOut, &csbi);
345 if (!ResizeTextConsole(hConOut, &csbi, Resolution))
347
348 return 0;
349
350invalid_parameter:
352 return 1;
353}
354
356{
357 PCWSTR argStr = ArgStr;
358 BOOL dispMode = FALSE, kbdMode = FALSE;
359
363 DWORD dwKbdDelay, dwKbdSpeed;
364 DWORD value;
365
366 if (!GetConsoleScreenBufferInfo(hConOut, &csbi))
367 {
368 // TODO: Error message?
369 return 0;
370 }
371 if (!SystemParametersInfoW(SPI_GETKEYBOARDDELAY, 0, &dwKbdDelay, 0))
372 {
373 // TODO: Error message?
374 return 0;
375 }
376 if (!SystemParametersInfoW(SPI_GETKEYBOARDSPEED, 0, &dwKbdSpeed, 0))
377 {
378 // TODO: Error message?
379 return 0;
380 }
381
382 Resolution = csbi.dwSize;
383
384 while (argStr && *argStr)
385 {
386 while (*argStr == L' ') argStr++;
387 if (!*argStr) break;
388
389 if (!kbdMode && _wcsnicmp(argStr, L"COLS=", 5) == 0)
390 {
391 dispMode = TRUE;
392
393 value = 0;
394 argStr = ParseNumber(argStr+5, &value);
395 if (!argStr) goto invalid_parameter;
397 }
398 else if (!kbdMode && _wcsnicmp(argStr, L"LINES=", 6) == 0)
399 {
400 dispMode = TRUE;
401
402 value = 0;
403 argStr = ParseNumber(argStr+6, &value);
404 if (!argStr) goto invalid_parameter;
406 }
407 else if (!dispMode && _wcsnicmp(argStr, L"RATE=", 5) == 0)
408 {
409 kbdMode = TRUE;
410
411 argStr = ParseNumber(argStr+5, &dwKbdSpeed);
412 if (!argStr) goto invalid_parameter;
413 }
414 else if (!dispMode && _wcsnicmp(argStr, L"DELAY=", 6) == 0)
415 {
416 kbdMode = TRUE;
417
418 argStr = ParseNumber(argStr+6, &dwKbdDelay);
419 if (!argStr) goto invalid_parameter;
420 }
421 else
422 {
423invalid_parameter:
425 return 1;
426 }
427 }
428
429 if (dispMode)
430 {
431 ClearScreen(hConOut, &csbi);
432 if (!ResizeTextConsole(hConOut, &csbi, Resolution))
434 }
435 else if (kbdMode)
436 {
437 /*
438 * Set the new keyboard settings. If those values are greater than
439 * their allowed range, they are automatically corrected as follows:
440 * dwKbdSpeed = min(dwKbdSpeed, 31);
441 * dwKbdDelay = (dwKbdDelay % 4);
442 */
444 // "Invalid keyboard delay."
446 // "Invalid keyboard rate."
447 }
448
449 return 0;
450}
451
453{
454 PCWSTR argStr = ArgStr;
455 DWORD value = 0;
456 UINT uOldCodePage, uNewCodePage;
457
458 if ( (_wcsnicmp(argStr, L"SELECT=", 7) == 0 && (argStr += 7)) ||
459 (_wcsnicmp(argStr, L"SEL=", 4) == 0 && (argStr += 4)) )
460 {
461 argStr = ParseNumber(argStr, &value);
462 if (!argStr) goto invalid_parameter;
463
464 /* This should be the end of the string */
465 while (*argStr == L' ') argStr++;
466 if (*argStr) goto invalid_parameter;
467 }
468 else
469 {
470invalid_parameter:
472 return 1;
473 }
474
475 uNewCodePage = value;
476
481 /*
482 * Save the original console code page to be restored
483 * in case SetConsoleCP() or SetConsoleOutputCP() fails.
484 */
485 uOldCodePage = GetConsoleCP();
486
487 /*
488 * Try changing the console input and output code pages.
489 * If it succeeds, refresh the local code page information.
490 */
491 if (SetConsoleCP(uNewCodePage))
492 {
493 if (SetConsoleOutputCP(uNewCodePage))
494 {
495 /* Success, reset the current thread UI language
496 * and update the streams cached code page. */
498 ConStdStreamsSetCacheCodePage(uNewCodePage, uNewCodePage);
499
500 /* Display the current console status */
502 return 0;
503 }
504 else
505 {
506 /* Failure, restore the original console code page */
507 SetConsoleCP(uOldCodePage);
508 }
509 }
510
511 /* An error happened, display an error and bail out */
513 return 1;
514}
515
516
517/*****************************************************************************\
518 ** S E R I A L P O R T H E L P E R S **
519\*****************************************************************************/
520
521static BOOL
522SerialPortQuery(INT nPortNum, LPDCB pDCB, LPCOMMTIMEOUTS pCommTimeouts, BOOL bWrite)
523{
525 HANDLE hPort;
526 WCHAR szPortName[MAX_PORTNAME_LEN];
527
528 ASSERT(pDCB);
529 ASSERT(pCommTimeouts);
530
531 _swprintf(szPortName, L"COM%d", nPortNum);
532 hPort = CreateFileW(szPortName,
533 bWrite ? GENERIC_WRITE : GENERIC_READ,
534 0, // exclusive
535 NULL, // sec attr
537 0, // no attributes
538 NULL); // no template
539
540 if (hPort == INVALID_HANDLE_VALUE)
541 {
542 DWORD dwLastError = GetLastError();
543 if (dwLastError == ERROR_ACCESS_DENIED)
545 else
546 ConResPrintf(StdErr, IDS_ERROR_ILLEGAL_DEVICE_NAME, szPortName, dwLastError);
547 return FALSE;
548 }
549
550 Success = bWrite ? SetCommState(hPort, pDCB)
551 : GetCommState(hPort, pDCB);
552 if (!Success)
553 {
556 szPortName);
557 goto Quit;
558 }
559
560 Success = bWrite ? SetCommTimeouts(hPort, pCommTimeouts)
561 : GetCommTimeouts(hPort, pCommTimeouts);
562 if (!Success)
563 {
566 szPortName);
567 goto Quit;
568 }
569
570Quit:
571 CloseHandle(hPort);
572 return Success;
573}
574
576{
577 static const LPCWSTR parity_strings[] =
578 {
579 L"None", // NOPARITY
580 L"Odd", // ODDPARITY
581 L"Even", // EVENPARITY
582 L"Mark", // MARKPARITY
583 L"Space" // SPACEPARITY
584 };
585 static const LPCWSTR control_strings[] = { L"OFF", L"ON", L"HANDSHAKE", L"TOGGLE" };
586 static const LPCWSTR stopbit_strings[] = { L"1", L"1.5", L"2" };
587
588 DCB dcb;
589 COMMTIMEOUTS CommTimeouts;
590 WCHAR szPortName[MAX_PORTNAME_LEN];
591
592 if (!SerialPortQuery(nPortNum, &dcb, &CommTimeouts, FALSE))
593 {
594 return 1;
595 }
596 if (dcb.Parity >= ARRAYSIZE(parity_strings))
597 {
599 dcb.Parity = 0;
600 }
601 if (dcb.StopBits >= ARRAYSIZE(stopbit_strings))
602 {
604 dcb.StopBits = 0;
605 }
606
607 _swprintf(szPortName, L"COM%d", nPortNum);
608
609 ConPuts(StdOut, L"\n");
611 ConPuts(StdOut, L"\n");
612
614 ConResPrintf(StdOut, IDS_COM_STATUS_PARITY, parity_strings[dcb.Parity]);
616 ConResPrintf(StdOut, IDS_COM_STATUS_STOP_BITS, stopbit_strings[dcb.StopBits]);
618 control_strings[(CommTimeouts.ReadTotalTimeoutConstant != 0) ||
619 (CommTimeouts.WriteTotalTimeoutConstant != 0) ? 1 : 0]);
621 control_strings[dcb.fOutX ? 1 : 0]);
623 control_strings[dcb.fOutxCtsFlow ? 1 : 0]);
625 control_strings[dcb.fOutxDsrFlow ? 1 : 0]);
627 control_strings[dcb.fDsrSensitivity ? 1 : 0]);
628 ConResPrintf(StdOut, IDS_COM_STATUS_DTR_CIRCUIT, control_strings[dcb.fDtrControl]);
629 ConResPrintf(StdOut, IDS_COM_STATUS_RTS_CIRCUIT, control_strings[dcb.fRtsControl]);
630 ConPuts(StdOut, L"\n");
631
632 return 0;
633}
634
635
636/*
637 * Those procedures are inspired from Wine's dll/win32/kernel32/wine/comm.c
638 * Copyright 1996 Erik Bos and Marcus Meissner.
639 */
640
641static PCWSTR
643{
644 if (_wcsnicmp(argStr, L"OFF", 3) == 0)
645 {
646 argStr += 3;
647 *Mode = 0;
648 }
649 else if (_wcsnicmp(argStr, L"ON", 2) == 0)
650 {
651 argStr += 2;
652 *Mode = 1;
653 }
654 else if (_wcsnicmp(argStr, L"HS", 2) == 0)
655 {
656 argStr += 2;
657 *Mode = 2;
658 }
659 else if (_wcsnicmp(argStr, L"TG", 2) == 0)
660 {
661 argStr += 2;
662 *Mode = 3;
663 }
664 else
665 {
666 return NULL;
667 }
668 return argStr;
669}
670
671static PCWSTR
672ParseBaudRate(PCWSTR argStr, PDWORD BaudRate)
673{
674 argStr = ParseNumber(argStr, BaudRate);
675 if (!argStr) return NULL;
676
677 /*
678 * Check for Baud Rate abbreviations. This means that using
679 * those values as real baud rates is impossible using MODE.
680 */
681 switch (*BaudRate)
682 {
683 /* BaudRate = 110, 150, 300, 600 */
684 case 11: case 15: case 30: case 60:
685 *BaudRate *= 10;
686 break;
687
688 /* BaudRate = 1200, 2400, 4800, 9600 */
689 case 12: case 24: case 48: case 96:
690 *BaudRate *= 100;
691 break;
692
693 case 19:
694 *BaudRate = 19200;
695 break;
696 }
697
698 return argStr;
699}
700
701static PCWSTR
702ParseParity(PCWSTR argStr, PBYTE Parity)
703{
704 switch (towupper(*argStr++))
705 {
706 case L'N':
707 *Parity = NOPARITY;
708 break;
709
710 case L'O':
711 *Parity = ODDPARITY;
712 break;
713
714 case L'E':
715 *Parity = EVENPARITY;
716 break;
717
718 case L'M':
719 *Parity = MARKPARITY;
720 break;
721
722 case L'S':
723 *Parity = SPACEPARITY;
724 break;
725
726 default:
727 return NULL;
728 }
729
730 return argStr;
731}
732
733static PCWSTR
735{
736 DWORD value = 0;
737
738 argStr = ParseNumber(argStr, &value);
739 if (!argStr) return NULL;
740
741 *ByteSize = (BYTE)value;
742 if (*ByteSize < 5 || *ByteSize > 8)
743 return NULL;
744
745 return argStr;
746}
747
748static PCWSTR
750{
751 if (_wcsnicmp(argStr, L"1.5", 3) == 0)
752 {
753 argStr += 3;
755 }
756 else
757 {
758 if (*argStr == L'1')
760 else if (*argStr == L'2')
762 else
763 return NULL;
764
765 argStr++;
766 }
767
768 return argStr;
769}
770
771/*
772 * Build a DCB using the old style settings string eg: "96,n,8,1"
773 *
774 * See dll/win32/kernel32/wine/comm.c!COMM_BuildOldCommDCB()
775 * for more information.
776 */
777static BOOL
779 OUT LPDCB pDCB,
780 IN PCWSTR ArgStr)
781{
782 PCWSTR argStr = ArgStr;
783 BOOL stop = FALSE;
784
785 /*
786 * Parse the baud rate (only MANDATORY argument)
787 */
788 argStr = ParseBaudRate(argStr, &pDCB->BaudRate);
789 if (!argStr) return FALSE;
790
791
792 /*
793 * Now parse the rest (OPTIONAL arguments)
794 */
795
796 while (*argStr == L' ') argStr++;
797 if (!*argStr) goto Quit;
798 if (*argStr++ != L',') return FALSE;
799 while (*argStr == L' ') argStr++;
800 if (!*argStr) goto Quit;
801
802 /* Parse the parity */
803 // Default: EVENPARITY
804 pDCB->Parity = EVENPARITY;
805 if (*argStr != L',')
806 {
807 argStr = ParseParity(argStr, &pDCB->Parity);
808 if (!argStr) return FALSE;
809 }
810
811 while (*argStr == L' ') argStr++;
812 if (!*argStr) goto Quit;
813 if (*argStr++ != L',') return FALSE;
814 while (*argStr == L' ') argStr++;
815 if (!*argStr) goto Quit;
816
817 /* Parse the data bits */
818 // Default: 7
819 pDCB->ByteSize = 7;
820 if (*argStr != L',')
821 {
822 argStr = ParseByteSize(argStr, &pDCB->ByteSize);
823 if (!argStr) return FALSE;
824 }
825
826 while (*argStr == L' ') argStr++;
827 if (!*argStr) goto Quit;
828 if (*argStr++ != L',') return FALSE;
829 while (*argStr == L' ') argStr++;
830 if (!*argStr) goto Quit;
831
832 /* Parse the stop bits */
833 // Default: 1, or 2 for BAUD=110
834 // pDCB->StopBits = ONESTOPBIT;
835 if (*argStr != L',')
836 {
837 stop = TRUE;
838 argStr = ParseStopBits(argStr, &pDCB->StopBits);
839 if (!argStr) return FALSE;
840 }
841
842 /* The last parameter (flow control "retry") is really optional */
843 while (*argStr == L' ') argStr++;
844 if (!*argStr) goto Quit;
845 if (*argStr++ != L',') return FALSE;
846 while (*argStr == L' ') argStr++;
847 if (!*argStr) goto Quit;
848
849Quit:
850 switch (towupper(*argStr))
851 {
852 case L'\0':
853 pDCB->fInX = FALSE;
854 pDCB->fOutX = FALSE;
855 pDCB->fOutxCtsFlow = FALSE;
856 pDCB->fOutxDsrFlow = FALSE;
857 pDCB->fDtrControl = DTR_CONTROL_ENABLE;
858 pDCB->fRtsControl = RTS_CONTROL_ENABLE;
859 break;
860
861 case L'X':
862 pDCB->fInX = TRUE;
863 pDCB->fOutX = TRUE;
864 pDCB->fOutxCtsFlow = FALSE;
865 pDCB->fOutxDsrFlow = FALSE;
866 pDCB->fDtrControl = DTR_CONTROL_ENABLE;
867 pDCB->fRtsControl = RTS_CONTROL_ENABLE;
868 break;
869
870 case L'P':
871 pDCB->fInX = FALSE;
872 pDCB->fOutX = FALSE;
873 pDCB->fOutxCtsFlow = TRUE;
874 pDCB->fOutxDsrFlow = TRUE;
875 pDCB->fDtrControl = DTR_CONTROL_HANDSHAKE;
876 pDCB->fRtsControl = RTS_CONTROL_HANDSHAKE;
877 break;
878
879 default:
880 /* Unsupported */
881 return FALSE;
882 }
883 if (*argStr) argStr++;
884
885 /* This should be the end of the string */
886 while (*argStr == L' ') argStr++;
887 if (*argStr) return FALSE;
888
889 /* If stop bits were not specified, a default is always supplied */
890 if (!stop)
891 {
892 if (pDCB->BaudRate == 110)
893 pDCB->StopBits = TWOSTOPBITS;
894 else
895 pDCB->StopBits = ONESTOPBIT;
896 }
897 return TRUE;
898}
899
900/*
901 * Build a DCB using the new style settings string.
902 * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
903 *
904 * See dll/win32/kernel32/wine/comm.c!COMM_BuildNewCommDCB()
905 * for more information.
906 */
907static BOOL
909 OUT LPDCB pDCB,
910 OUT LPCOMMTIMEOUTS pCommTimeouts,
911 IN PCWSTR ArgStr)
912{
913 PCWSTR argStr = ArgStr;
914 BOOL baud = FALSE, stop = FALSE;
915 BYTE value;
916
917 while (argStr && *argStr)
918 {
919 while (*argStr == L' ') argStr++;
920 if (!*argStr) break;
921
922 if (_wcsnicmp(argStr, L"BAUD=", 5) == 0)
923 {
924 baud = TRUE;
925 argStr = ParseBaudRate(argStr+5, &pDCB->BaudRate);
926 if (!argStr) return FALSE;
927 }
928 else if (_wcsnicmp(argStr, L"PARITY=", 7) == 0)
929 {
930 // Default: EVENPARITY
931 argStr = ParseParity(argStr+7, &pDCB->Parity);
932 if (!argStr) return FALSE;
933 }
934 else if (_wcsnicmp(argStr, L"DATA=", 5) == 0)
935 {
936 // Default: 7
937 argStr = ParseByteSize(argStr+5, &pDCB->ByteSize);
938 if (!argStr) return FALSE;
939 }
940 else if (_wcsnicmp(argStr, L"STOP=", 5) == 0)
941 {
942 // Default: 1, or 2 for BAUD=110
943 stop = TRUE;
944 argStr = ParseStopBits(argStr+5, &pDCB->StopBits);
945 if (!argStr) return FALSE;
946 }
947 else if (_wcsnicmp(argStr, L"TO=", 3) == 0) // TO=ON|OFF
948 {
949 /* Only total time-outs are get/set by Windows' MODE.COM */
950 argStr = ParseModes(argStr+3, &value);
951 if (!argStr) return FALSE;
952 if (value == 0) // OFF
953 {
954 pCommTimeouts->ReadTotalTimeoutConstant = 0;
955 pCommTimeouts->WriteTotalTimeoutConstant = 0;
956 }
957 else if (value == 1) // ON
958 {
959 pCommTimeouts->ReadTotalTimeoutConstant = 60000;
960 pCommTimeouts->WriteTotalTimeoutConstant = 60000;
961 }
962 else
963 {
964 return FALSE;
965 }
966 }
967 else if (_wcsnicmp(argStr, L"XON=", 4) == 0) // XON=ON|OFF
968 {
969 argStr = ParseModes(argStr+4, &value);
970 if (!argStr) return FALSE;
971 if ((value == 0) || (value == 1))
972 {
973 pDCB->fOutX = value;
974 pDCB->fInX = value;
975 }
976 else
977 {
978 return FALSE;
979 }
980 }
981 else if (_wcsnicmp(argStr, L"ODSR=", 5) == 0) // ODSR=ON|OFF
982 {
983 value = 0;
984 argStr = ParseModes(argStr+5, &value);
985 if (!argStr) return FALSE;
986 if ((value == 0) || (value == 1))
987 pDCB->fOutxDsrFlow = value;
988 else
989 return FALSE;
990 }
991 else if (_wcsnicmp(argStr, L"OCTS=", 5) == 0) // OCTS=ON|OFF
992 {
993 value = 0;
994 argStr = ParseModes(argStr+5, &value);
995 if (!argStr) return FALSE;
996 if ((value == 0) || (value == 1))
997 pDCB->fOutxCtsFlow = value;
998 else
999 return FALSE;
1000 }
1001 else if (_wcsnicmp(argStr, L"DTR=", 4) == 0) // DTR=ON|OFF|HS
1002 {
1003 value = 0;
1004 argStr = ParseModes(argStr+4, &value);
1005 if (!argStr) return FALSE;
1006 if ((value == 0) || (value == 1) || (value == 2))
1007 pDCB->fDtrControl = value;
1008 else
1009 return FALSE;
1010 }
1011 else if (_wcsnicmp(argStr, L"RTS=", 4) == 0) // RTS=ON|OFF|HS|TG
1012 {
1013 value = 0;
1014 argStr = ParseModes(argStr+4, &value);
1015 if (!argStr) return FALSE;
1016 if ((value == 0) || (value == 1) || (value == 2) || (value == 3))
1017 pDCB->fRtsControl = value;
1018 else
1019 return FALSE;
1020 }
1021 else if (_wcsnicmp(argStr, L"IDSR=", 5) == 0) // IDSR=ON|OFF
1022 {
1023 value = 0;
1024 argStr = ParseModes(argStr+5, &value);
1025 if (!argStr) return FALSE;
1026 if ((value == 0) || (value == 1))
1027 pDCB->fDsrSensitivity = value;
1028 else
1029 return FALSE;
1030 }
1031 else
1032 {
1033 return FALSE;
1034 }
1035 }
1036
1037 /* If stop bits were not specified, a default is always supplied */
1038 if (!stop)
1039 {
1040 if (baud && pDCB->BaudRate == 110)
1041 pDCB->StopBits = TWOSTOPBITS;
1042 else
1043 pDCB->StopBits = ONESTOPBIT;
1044 }
1045 return TRUE;
1046}
1047
1048int SetSerialState(INT nPortNum, IN PCWSTR ArgStr)
1049{
1050 BOOL Success;
1051 DCB dcb;
1052 COMMTIMEOUTS CommTimeouts;
1053
1054 if (!SerialPortQuery(nPortNum, &dcb, &CommTimeouts, FALSE))
1055 {
1056 // TODO: Error message?
1057 return 0;
1058 }
1059
1060 /*
1061 * Check whether we should use the old or the new MODE syntax:
1062 * in the old syntax, the separators are both spaces and commas.
1063 */
1064 if (wcschr(ArgStr, L','))
1065 Success = BuildOldCommDCB(&dcb, ArgStr);
1066 else
1067 Success = BuildNewCommDCB(&dcb, &CommTimeouts, ArgStr);
1068
1069 if (!Success)
1070 {
1072 return 1;
1073 }
1074
1075 SerialPortQuery(nPortNum, &dcb, &CommTimeouts, TRUE);
1076 ShowSerialStatus(nPortNum);
1077
1078 return 0;
1079}
1080
1081
1082/*****************************************************************************\
1083 ** E N T R Y P O I N T **
1084\*****************************************************************************/
1085
1086static PCWSTR
1087FindPortNum(PCWSTR argStr, PINT PortNum)
1088{
1089 PWSTR endptr = NULL;
1090
1091 *PortNum = wcstol(argStr, &endptr, 10);
1092 if (endptr == argStr)
1093 {
1094 *PortNum = -1;
1095 return NULL;
1096 }
1097
1098 return endptr;
1099}
1100
1102{
1103 PWSTR Buffer, ptr;
1104 PCWSTR argStr;
1105 DWORD dwLen = MAX_PATH;
1106 INT nPortNum;
1107
1108 /* Pre-allocate a buffer for QueryDosDeviceW() */
1109 Buffer = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
1110 if (Buffer == NULL)
1111 {
1112 /* We failed, bail out */
1113 ConPuts(StdErr, L"ERROR: Not enough memory\n");
1114 return 0;
1115 }
1116
1117 for (;;)
1118 {
1120 if (QueryDosDeviceW(NULL, Buffer, dwLen))
1121 break;
1122
1124 {
1125 /* We failed, bail out */
1126 ConPrintf(StdErr, L"ERROR: QueryDosDeviceW(...) failed: 0x%lx\n", GetLastError());
1128 return 0;
1129 }
1130
1131 /* The buffer was too small, try to re-allocate it */
1132 dwLen *= 2;
1133 ptr = HeapReAlloc(GetProcessHeap(), 0, Buffer, dwLen * sizeof(WCHAR));
1134 if (ptr == NULL)
1135 {
1136 /* We failed, bail out */
1137 ConPuts(StdErr, L"ERROR: Not enough memory\n");
1139 return 0;
1140 }
1141 Buffer = ptr;
1142 }
1143
1144 for (ptr = Buffer; *ptr != UNICODE_NULL; ptr += wcslen(ptr) + 1)
1145 {
1146 if (_wcsnicmp(ptr, L"COM", 3) == 0)
1147 {
1148 argStr = FindPortNum(ptr+3, &nPortNum);
1149 if (!argStr || *argStr || nPortNum == -1)
1150 continue;
1151
1152 // ConResPrintf(StdOut, IDS_QUERY_SERIAL_FOUND, ptr);
1153 ShowSerialStatus(nPortNum);
1154 }
1155 else if (_wcsicmp(ptr, L"PRN") == 0)
1156 {
1158 }
1159 else if (_wcsnicmp(ptr, L"LPT", 3) == 0)
1160 {
1161 argStr = FindPortNum(ptr+3, &nPortNum);
1162 if (!argStr || *argStr || nPortNum == -1)
1163 continue;
1164
1165 // ConResPrintf(StdOut, IDS_QUERY_PARALLEL_FOUND, ptr);
1166 ShowParallelStatus(nPortNum);
1167 }
1168 else if (_wcsicmp(ptr, L"AUX") == 0 || _wcsicmp(ptr, L"NUL") == 0)
1169 {
1171 }
1172 else
1173 {
1174 // ConResPrintf(StdOut, IDS_QUERY_MISC_FOUND, ptr);
1175 }
1176 }
1177
1179
1180 /* Free the buffer and return success */
1182 return 1;
1183}
1184
1185int wmain(int argc, WCHAR* argv[])
1186{
1187 int ret = 0;
1188 int arg;
1189 SIZE_T ArgStrSize;
1190 PCWSTR ArgStr, argStr;
1191
1192 INT nPortNum;
1193
1194 /* Initialize the Console Standard Streams */
1196
1197 /*
1198 * MODE.COM has a very peculiar way of parsing its arguments,
1199 * as they can be even not separated by any space. This extreme
1200 * behaviour certainly is present for backwards compatibility
1201 * with the oldest versions of the utility present on MS-DOS.
1202 *
1203 * For example, such a command:
1204 * "MODE.COM COM1baud=9600parity=ndata=8stop=1xon=onto=on"
1205 * will be correctly understood as:
1206 * "MODE.COM COM1 baud=9600 parity=n data=8 stop=1 xon=on to=on"
1207 *
1208 * Note also that the "/STATUS" switch is actually really "/STA".
1209 *
1210 * However we will not use GetCommandLine() because we do not want
1211 * to deal with the prepended application path and try to find
1212 * where the arguments start. Our approach here will consist in
1213 * flattening the arguments vector.
1214 */
1215 ArgStrSize = 0;
1216
1217 /* Compute the space needed for the new string, and allocate it */
1218 for (arg = 1; arg < argc; arg++)
1219 {
1220 ArgStrSize += wcslen(argv[arg]) + 1; // 1 for space
1221 }
1222 ArgStr = HeapAlloc(GetProcessHeap(), 0, (ArgStrSize + 1) * sizeof(WCHAR));
1223 if (ArgStr == NULL)
1224 {
1225 ConPuts(StdErr, L"ERROR: Not enough memory\n");
1226 return 1;
1227 }
1228
1229 /* Copy the contents and NULL-terminate the string */
1230 argStr = ArgStr;
1231 for (arg = 1; arg < argc; arg++)
1232 {
1233 wcscpy((PWSTR)argStr, argv[arg]);
1234 argStr += wcslen(argv[arg]);
1235 *(PWSTR)argStr++ = L' ';
1236 }
1237 *(PWSTR)argStr = L'\0';
1238
1239 /* Parse the command line */
1240 argStr = ArgStr;
1241
1242 while (*argStr == L' ') argStr++;
1243 if (!*argStr) goto show_status;
1244
1245 if (wcsstr(argStr, L"/?") || wcsstr(argStr, L"-?"))
1246 {
1248 goto Quit;
1249 }
1250 else if (_wcsnicmp(argStr, L"/STA", 4) == 0)
1251 {
1252 /* Skip this parameter */
1253 while (*argStr != L' ') argStr++;
1254 /* Skip any delimiter */
1255 while (*argStr == L' ') argStr++;
1256
1257 /* The presence of any other parameter is invalid */
1258 if (*argStr)
1259 goto invalid_parameter;
1260
1261 goto show_status;
1262 }
1263 else if (_wcsnicmp(argStr, L"LPT", 3) == 0)
1264 {
1265 argStr = FindPortNum(argStr+3, &nPortNum);
1266 if (!argStr || nPortNum == -1)
1267 goto invalid_parameter;
1268
1269 if (*argStr == L':') argStr++;
1270 while (*argStr == L' ') argStr++;
1271
1272 if (!*argStr || _wcsnicmp(argStr, L"/STA", 4) == 0)
1273 ret = ShowParallelStatus(nPortNum);
1274 else
1275 ConPuts(StdErr, L"ERROR: LPT port redirection is not implemented!\n");
1276 // TODO: Implement setting LPT port redirection using SetParallelState().
1277 goto Quit;
1278 }
1279 else if (_wcsnicmp(argStr, L"COM", 3) == 0)
1280 {
1281 argStr = FindPortNum(argStr+3, &nPortNum);
1282 if (!argStr || nPortNum == -1)
1283 goto invalid_parameter;
1284
1285 if (*argStr == L':') argStr++;
1286 while (*argStr == L' ') argStr++;
1287
1288 if (!*argStr || _wcsnicmp(argStr, L"/STA", 4) == 0)
1289 ret = ShowSerialStatus(nPortNum);
1290 else
1291 ret = SetSerialState(nPortNum, argStr);
1292 goto Quit;
1293 }
1294 else if (_wcsnicmp(argStr, L"CON", 3) == 0)
1295 {
1296 argStr += 3;
1297
1298 if (*argStr == L':') argStr++;
1299 while (*argStr == L' ') argStr++;
1300
1301 if (!*argStr || _wcsnicmp(argStr, L"/STA", 4) == 0)
1302 {
1304 }
1305 else if ( (_wcsnicmp(argStr, L"CP", 2) == 0 && (argStr += 2)) ||
1306 (_wcsnicmp(argStr, L"CODEPAGE", 8) == 0 && (argStr += 8)) )
1307 {
1308 while (*argStr == L' ') argStr++;
1309
1310 if (!*argStr || _wcsnicmp(argStr, L"/STA", 4) == 0)
1312 else
1313 ret = SetConsoleCPState(argStr);
1314 }
1315 else
1316 {
1317 ret = SetConsoleState(argStr);
1318 }
1319 goto Quit;
1320 }
1321 // else if (wcschr(argStr, L','))
1322 else
1323 {
1324 /* Old syntax: MODE [COLS],[LINES] */
1325 ret = SetConsoleStateOld(argStr);
1326 goto Quit;
1327 }
1328
1331 goto Quit;
1332
1333invalid_parameter:
1335 goto Quit;
1336
1337Quit:
1338 /* Free the string and quit */
1339 HeapFree(GetProcessHeap(), 0, (PWSTR)ArgStr);
1340 return ret;
1341}
#define skip(...)
Definition: atltest.h:64
#define IDS_USAGE
Definition: resource.h:3
#define IDS_COM_STATUS_BAUD
Definition: resource.h:16
#define IDS_ERROR_INVALID_PARAMETER
Definition: resource.h:38
#define IDS_CONSOLE_KBD_DELAY
Definition: resource.h:30
#define IDS_QUERY_DOSDEV_FOUND
Definition: resource.h:9
#define IDS_QUERY_PRINTER_FOUND
Definition: resource.h:6
#define IDS_COM_STATUS_XON_XOFF
Definition: resource.h:21
#define IDS_COM_STATUS_PARITY
Definition: resource.h:17
#define IDS_CONSOLE_STATUS_COLS
Definition: resource.h:28
#define IDS_PRINTER_OUTPUT_REROUTED_SERIAL
Definition: resource.h:33
#define IDS_ERROR_ILLEGAL_DEVICE_NAME
Definition: resource.h:39
#define IDS_CONSOLE_CODEPAGE
Definition: resource.h:31
#define IDS_CONSOLE_KBD_RATE
Definition: resource.h:29
#define IDS_ERROR_QUERY_DEVICES_FORM
Definition: resource.h:36
#define IDS_ERROR_INVALID_PARITY_BITS
Definition: resource.h:45
#define IDS_COM_STATUS_STOP_BITS
Definition: resource.h:19
#define IDS_DEVICE_STATUS_HEADER
Definition: resource.h:15
#define IDS_COM_STATUS_DSR_HANDSHAKING
Definition: resource.h:23
#define IDS_ERROR_TIMEOUT_GET_DEVICE
Definition: resource.h:43
#define IDS_COM_STATUS_DTR_CIRCUIT
Definition: resource.h:25
#define IDS_ERROR_TIMEOUT_SET_DEVICE
Definition: resource.h:44
#define IDS_CONSOLE_STATUS_LINES
Definition: resource.h:27
#define IDS_ERROR_DEVICE_NOT_AVAILABLE
Definition: resource.h:40
#define IDS_ERROR_INVALID_STOP_BITS
Definition: resource.h:46
#define IDS_ERROR_STATUS_SET_DEVICE
Definition: resource.h:42
#define IDS_COM_STATUS_DSR_SENSITIVITY
Definition: resource.h:24
#define IDS_ERROR_SCREEN_LINES_COL
Definition: resource.h:48
#define IDS_PRINTER_OUTPUT_NOT_REROUTED
Definition: resource.h:32
#define IDS_COM_STATUS_TIMEOUT
Definition: resource.h:20
#define IDS_COM_STATUS_CTS_HANDSHAKING
Definition: resource.h:22
#define IDS_ERROR_INVALID_CODEPAGE
Definition: resource.h:49
#define IDS_ERROR_STATUS_GET_DEVICE
Definition: resource.h:41
#define IDS_COM_STATUS_RTS_CIRCUIT
Definition: resource.h:26
#define IDS_COM_STATUS_DATA_BITS
Definition: resource.h:18
BOOL WINAPI SetConsoleOutputCP(IN UINT wCodepage)
Definition: console.c:695
BOOL WINAPI SetConsoleCursorPosition(IN HANDLE hConsoleOutput, IN COORD dwCursorPosition)
Definition: console.c:641
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
BOOL WINAPI FillConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN WORD wAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: console.c:525
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:595
#define ARRAYSIZE(a)
Definition: cat.c:25
Definition: bufpool.h:45
void ConPuts(FILE *fp, LPCWSTR psz)
Definition: conutils_noros.h:8
#define ConInitStdStreams()
Definition: conutils_noros.h:5
void ConPrintf(FILE *fp, LPCWSTR psz,...)
#define StdOut
Definition: conutils_noros.h:6
void ConResPrintf(FILE *fp, UINT nID,...)
#define StdErr
Definition: conutils_noros.h:7
void ConResPuts(FILE *fp, UINT nID)
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define Len
Definition: deflate.h:82
_Check_return_ _In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS _Out_ UINT _Out_ UINT * Height
Definition: dispmprt.h:1445
_Check_return_ _In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS _Out_ UINT * Width
Definition: dispmprt.h:1444
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define wcsrchr
Definition: compat.h:16
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOL WINAPI SetConsoleWindowInfo(HANDLE hConsoleOutput, BOOL bAbsolute, CONST SMALL_RECT *lpConsoleWindow)
Definition: console.c:1972
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleScreenBufferSize(HANDLE hConsoleOutput, COORD dwSize)
Definition: console.c:1857
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCP(UINT wCodePageID)
Definition: console.c:2422
BOOL WINAPI DECLSPEC_HOTPATCH FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput, IN WCHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1674
BOOL WINAPI DefineDosDeviceW(DWORD dwFlags, LPCWSTR lpDeviceName, LPCWSTR lpTargetPath)
Definition: dosdev.c:232
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:542
BOOL WINAPI SetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
Definition: comm.c:1062
BOOL WINAPI SetCommState(HANDLE handle, LPDCB lpdcb)
Definition: comm.c:807
BOOL WINAPI GetCommState(HANDLE handle, LPDCB lpdcb)
Definition: comm.c:904
BOOL WINAPI GetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
Definition: comm.c:1020
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleCP(void)
Definition: console.c:821
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(void)
Definition: console.c:957
MonoAssembly int argc
Definition: metahost.c:107
PWSTR StopBits[]
Definition: serial.c:37
#define __cdecl
Definition: corecrt.h:121
_ACRTIMP int __cdecl swscanf(const wchar_t *, const wchar_t *,...)
Definition: scanf.c:438
_ACRTIMP __msvcrt_long __cdecl wcstol(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2752
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2998
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint buffer
Definition: glext.h:5915
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT
Definition: sysinfo.c:13
_In_ ULONG Mode
Definition: hubbusif.h:303
int * PINT
Definition: minwindef.h:150
int SetParallelState(INT nPortNum)
Definition: mode.c:111
int SetSerialState(INT nPortNum, IN PCWSTR ArgStr)
Definition: mode.c:1048
static PCWSTR ParseModes(PCWSTR argStr, PBYTE Mode)
Definition: mode.c:642
static PCWSTR ParseBaudRate(PCWSTR argStr, PDWORD BaudRate)
Definition: mode.c:672
#define MAX_PORTNAME_LEN
Definition: mode.c:42
VOID __cdecl UnderlinedResPrintf(IN PCON_STREAM Stream, IN UINT uID,...)
Definition: mode.c:50
static BOOL SerialPortQuery(INT nPortNum, LPDCB pDCB, LPCOMMTIMEOUTS pCommTimeouts, BOOL bWrite)
Definition: mode.c:522
static VOID ClearScreen(IN HANDLE hConOut, IN PCONSOLE_SCREEN_BUFFER_INFO pcsbi)
Definition: mode.c:202
static BOOL BuildNewCommDCB(OUT LPDCB pDCB, OUT LPCOMMTIMEOUTS pCommTimeouts, IN PCWSTR ArgStr)
Definition: mode.c:908
int ShowConsoleCPStatus(VOID)
Definition: mode.c:189
int SetConsoleCPState(IN PCWSTR ArgStr)
Definition: mode.c:452
static PCWSTR FindPortNum(PCWSTR argStr, PINT PortNum)
Definition: mode.c:1087
int SetConsoleStateOld(IN PCWSTR ArgStr)
Definition: mode.c:305
static BOOL BuildOldCommDCB(OUT LPDCB pDCB, IN PCWSTR ArgStr)
Definition: mode.c:778
#define ASSERT(a)
Definition: mode.c:44
int ShowSerialStatus(INT nPortNum)
Definition: mode.c:575
static PCWSTR ParseByteSize(PCWSTR argStr, PBYTE ByteSize)
Definition: mode.c:734
int SetConsoleState(IN PCWSTR ArgStr)
Definition: mode.c:355
static PCWSTR ParseStopBits(PCWSTR argStr, PBYTE StopBits)
Definition: mode.c:749
int ShowParallelStatus(INT nPortNum)
Definition: mode.c:74
static PCWSTR ParseNumber(PCWSTR argStr, PDWORD Number)
Definition: mode.c:129
int EnumerateDevices(VOID)
Definition: mode.c:1101
#define MAX_BUFFER_SIZE
static PCWSTR ParseParity(PCWSTR argStr, PBYTE Parity)
Definition: mode.c:702
static BOOL ResizeTextConsole(IN HANDLE hConOut, IN OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi, IN COORD Resolution)
Definition: mode.c:225
int ShowConsoleStatus(VOID)
Definition: mode.c:160
static PVOID ptr
Definition: dispmode.c:27
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
#define show_status(counter, text)
Definition: test.h:40
static IStream Stream
Definition: htmldoc.c:1115
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
_In_ ULONG Number
Definition: haltypes.h:1940
#define GENERIC_WRITE
Definition: nt_native.h:90
#define UNICODE_NULL
INT ConResPrintfV(IN PCON_STREAM Stream, IN UINT uID, IN va_list args)
Definition: outstream.c:694
INT ConStreamWrite(IN PCON_STREAM Stream, IN PCTCH szStr, IN DWORD len)
Definition: outstream.c:397
BYTE * PBYTE
Definition: pedump.c:66
short WCHAR
Definition: pedump.c:58
DWORD * PDWORD
Definition: pedump.c:68
short SHORT
Definition: pedump.c:59
_In_ UINT uID
Definition: shlwapi.h:156
#define SPIF_SENDCHANGE
Definition: winuser.h:1600
#define SPI_SETKEYBOARDSPEED
Definition: winuser.h:1371
#define SPIF_UPDATEINIFILE
Definition: winuser.h:1599
#define SPI_GETKEYBOARDSPEED
Definition: winuser.h:1370
BOOL WINAPI SystemParametersInfoW(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
#define SPI_GETKEYBOARDDELAY
Definition: winuser.h:1382
#define SPI_SETKEYBOARDDELAY
Definition: winuser.h:1383
int wmain()
wcscpy
#define ConStdStreamsSetCacheCodePage(InputCodePage, OutputCodePage)
Definition: stream.h:152
LANGID ConSetThreadUILanguage(IN LANGID LangId OPTIONAL)
Definition: utils.c:362
#define towupper(c)
Definition: wctype.h:99
#define args
Definition: format.c:66
DWORD WriteTotalTimeoutConstant
Definition: winbase.h:682
DWORD ReadTotalTimeoutConstant
Definition: winbase.h:680
Definition: winbase.h:614
Definition: cdstruc.h:902
SHORT Top
Definition: tui.c:25
SHORT Right
Definition: tui.c:26
SHORT Left
Definition: tui.c:24
SHORT Bottom
Definition: tui.c:27
Definition: match.c:390
Definition: blue.h:25
SHORT Y
Definition: blue.h:27
SHORT X
Definition: blue.h:26
static BYTE Resolution
Definition: mouse.c:35
#define max(a, b)
Definition: svc.c:63
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
Definition: pdh_main.c:64
#define MARKPARITY
Definition: winbase.h:433
#define STD_OUTPUT_HANDLE
Definition: winbase.h:293
#define RTS_CONTROL_ENABLE
Definition: winbase.h:517
#define DTR_CONTROL_HANDSHAKE
Definition: winbase.h:515
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define TWOSTOPBITS
Definition: winbase.h:437
#define ONESTOPBIT
Definition: winbase.h:435
#define RTS_CONTROL_HANDSHAKE
Definition: winbase.h:518
#define EVENPARITY
Definition: winbase.h:432
#define ODDPARITY
Definition: winbase.h:431
#define ONE5STOPBITS
Definition: winbase.h:436
#define DTR_CONTROL_ENABLE
Definition: winbase.h:514
#define SPACEPARITY
Definition: winbase.h:434
#define DDD_REMOVE_DEFINITION
Definition: winbase.h:504
#define NOPARITY
Definition: winbase.h:430
void * arg
Definition: msvc.h:10
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:412
unsigned char BYTE
Definition: xxhash.c:193