ReactOS  0.4.15-dev-3308-g9455def
mode.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Mode Utility
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Provides fast mode setup for DOS devices.
5  * COPYRIGHT: Copyright 2002 Robert Dickenson
6  * Copyright 2016-2021 Hermes Belusca-Maito
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 <winuser.h>
36 #include <wincon.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(...)
48 VOID
49 __cdecl
52  IN UINT uID,
53  ...)
54 {
55  INT Len;
56  va_list args;
57 
58 #define MAX_BUFFER_SIZE 4096
59  INT i;
60  WCHAR szMsgBuffer[MAX_BUFFER_SIZE];
61 
62  va_start(args, uID);
63  Len = ConResPrintfV(Stream, uID, args);
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 
74 int ShowParallelStatus(INT nPortNum)
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 
111 int SetParallelState(INT nPortNum)
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 
128 static 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
143 BOOL DefineDosDevice(
144  DWORD dwFlags, // options
145  LPCTSTR lpDeviceName, // device name
146  LPCTSTR lpTargetPath // path string
147 );
148 DWORD 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 
201 static 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  */
224 static BOOL
226  IN HANDLE hConOut,
229 {
230  BOOL Success;
231  SHORT Width, Height;
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;
326  Resolution.X = (SHORT)value;
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;
337  Resolution.Y = (SHORT)value;
338 
339  /* This should be the end of the string */
340  while (*argStr == L' ') argStr++;
341  if (*argStr) goto invalid_parameter;
342 
343 Quit:
344  ClearScreen(hConOut, &csbi);
345  if (!ResizeTextConsole(hConOut, &csbi, Resolution))
347 
348  return 0;
349 
350 invalid_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;
396  Resolution.X = (SHORT)value;
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;
405  Resolution.Y = (SHORT)value;
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  {
423 invalid_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  {
470 invalid_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 
521 static BOOL
522 SerialPortQuery(INT nPortNum, LPDCB pDCB, LPCOMMTIMEOUTS pCommTimeouts, BOOL bWrite)
523 {
524  BOOL Success;
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 
570 Quit:
571  CloseHandle(hPort);
572  return Success;
573 }
574 
575 int ShowSerialStatus(INT nPortNum)
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 
613  ConResPrintf(StdOut, IDS_COM_STATUS_BAUD, dcb.BaudRate);
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 
641 static 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 
665  return NULL;
666 }
667 
668 static PCWSTR
669 ParseBaudRate(PCWSTR argStr, PDWORD BaudRate)
670 {
671  argStr = ParseNumber(argStr, BaudRate);
672  if (!argStr) return NULL;
673 
674  /*
675  * Check for Baud Rate abbreviations. This means that using
676  * those values as real baud rates is impossible using MODE.
677  */
678  switch (*BaudRate)
679  {
680  /* BaudRate = 110, 150, 300, 600 */
681  case 11: case 15: case 30: case 60:
682  *BaudRate *= 10;
683  break;
684 
685  /* BaudRate = 1200, 2400, 4800, 9600 */
686  case 12: case 24: case 48: case 96:
687  *BaudRate *= 100;
688  break;
689 
690  case 19:
691  *BaudRate = 19200;
692  break;
693  }
694 
695  return argStr;
696 }
697 
698 static PCWSTR
699 ParseParity(PCWSTR argStr, PBYTE Parity)
700 {
701  switch (towupper(*argStr++))
702  {
703  case L'N':
704  *Parity = NOPARITY;
705  break;
706 
707  case L'O':
708  *Parity = ODDPARITY;
709  break;
710 
711  case L'E':
712  *Parity = EVENPARITY;
713  break;
714 
715  case L'M':
716  *Parity = MARKPARITY;
717  break;
718 
719  case L'S':
720  *Parity = SPACEPARITY;
721  break;
722 
723  default:
724  return NULL;
725  }
726 
727  return argStr;
728 }
729 
730 static PCWSTR
732 {
733  DWORD value = 0;
734 
735  argStr = ParseNumber(argStr, &value);
736  if (!argStr) return NULL;
737 
738  *ByteSize = (BYTE)value;
739  if (*ByteSize < 5 || *ByteSize > 8)
740  return NULL;
741 
742  return argStr;
743 }
744 
745 static PCWSTR
747 {
748  if (_wcsnicmp(argStr, L"1.5", 3) == 0)
749  {
750  argStr += 3;
752  }
753  else
754  {
755  if (*argStr == L'1')
756  *StopBits = ONESTOPBIT;
757  else if (*argStr == L'2')
759  else
760  return NULL;
761 
762  argStr++;
763  }
764 
765  return argStr;
766 }
767 
768 /*
769  * Build a DCB using the old style settings string eg: "96,n,8,1"
770  *
771  * See dll/win32/kernel32/wine/comm.c!COMM_BuildOldCommDCB()
772  * for more information.
773  */
774 static BOOL
776  OUT LPDCB pDCB,
777  IN PCWSTR ArgStr)
778 {
779  PCWSTR argStr = ArgStr;
780  BOOL stop = FALSE;
781 
782  /*
783  * Parse the baud rate (only MANDATORY argument)
784  */
785  argStr = ParseBaudRate(argStr, &pDCB->BaudRate);
786  if (!argStr) return FALSE;
787 
788 
789  /*
790  * Now parse the rest (OPTIONAL arguments)
791  */
792 
793  while (*argStr == L' ') argStr++;
794  if (!*argStr) goto Quit;
795  if (*argStr++ != L',') return FALSE;
796  while (*argStr == L' ') argStr++;
797  if (!*argStr) goto Quit;
798 
799  /* Parse the parity */
800  // Default: EVENPARITY
801  pDCB->Parity = EVENPARITY;
802  if (*argStr != L',')
803  {
804  argStr = ParseParity(argStr, &pDCB->Parity);
805  if (!argStr) return FALSE;
806  }
807 
808  while (*argStr == L' ') argStr++;
809  if (!*argStr) goto Quit;
810  if (*argStr++ != L',') return FALSE;
811  while (*argStr == L' ') argStr++;
812  if (!*argStr) goto Quit;
813 
814  /* Parse the data bits */
815  // Default: 7
816  pDCB->ByteSize = 7;
817  if (*argStr != L',')
818  {
819  argStr = ParseByteSize(argStr, &pDCB->ByteSize);
820  if (!argStr) return FALSE;
821  }
822 
823  while (*argStr == L' ') argStr++;
824  if (!*argStr) goto Quit;
825  if (*argStr++ != L',') return FALSE;
826  while (*argStr == L' ') argStr++;
827  if (!*argStr) goto Quit;
828 
829  /* Parse the stop bits */
830  // Default: 1, or 2 for BAUD=110
831  // pDCB->StopBits = ONESTOPBIT;
832  if (*argStr != L',')
833  {
834  stop = TRUE;
835  argStr = ParseStopBits(argStr, &pDCB->StopBits);
836  if (!argStr) return FALSE;
837  }
838 
839  /* The last parameter (flow control "retry") is really optional */
840  while (*argStr == L' ') argStr++;
841  if (!*argStr) goto Quit;
842  if (*argStr++ != L',') return FALSE;
843  while (*argStr == L' ') argStr++;
844  if (!*argStr) goto Quit;
845 
846 Quit:
847  switch (towupper(*argStr))
848  {
849  case L'\0':
850  pDCB->fInX = FALSE;
851  pDCB->fOutX = FALSE;
852  pDCB->fOutxCtsFlow = FALSE;
853  pDCB->fOutxDsrFlow = FALSE;
854  pDCB->fDtrControl = DTR_CONTROL_ENABLE;
855  pDCB->fRtsControl = RTS_CONTROL_ENABLE;
856  break;
857 
858  case L'X':
859  pDCB->fInX = TRUE;
860  pDCB->fOutX = TRUE;
861  pDCB->fOutxCtsFlow = FALSE;
862  pDCB->fOutxDsrFlow = FALSE;
863  pDCB->fDtrControl = DTR_CONTROL_ENABLE;
864  pDCB->fRtsControl = RTS_CONTROL_ENABLE;
865  break;
866 
867  case L'P':
868  pDCB->fInX = FALSE;
869  pDCB->fOutX = FALSE;
870  pDCB->fOutxCtsFlow = TRUE;
871  pDCB->fOutxDsrFlow = TRUE;
872  pDCB->fDtrControl = DTR_CONTROL_HANDSHAKE;
873  pDCB->fRtsControl = RTS_CONTROL_HANDSHAKE;
874  break;
875 
876  default:
877  /* Unsupported */
878  return FALSE;
879  }
880  if (*argStr) argStr++;
881 
882  /* This should be the end of the string */
883  while (*argStr == L' ') argStr++;
884  if (*argStr) return FALSE;
885 
886  /* If stop bits were not specified, a default is always supplied */
887  if (!stop)
888  {
889  if (pDCB->BaudRate == 110)
890  pDCB->StopBits = TWOSTOPBITS;
891  else
892  pDCB->StopBits = ONESTOPBIT;
893  }
894  return TRUE;
895 }
896 
897 /*
898  * Build a DCB using the new style settings string.
899  * eg: "baud=9600 parity=n data=8 stop=1 xon=on to=on"
900  *
901  * See dll/win32/kernel32/wine/comm.c!COMM_BuildNewCommDCB()
902  * for more information.
903  */
904 static BOOL
906  OUT LPDCB pDCB,
907  OUT LPCOMMTIMEOUTS pCommTimeouts,
908  IN PCWSTR ArgStr)
909 {
910  PCWSTR argStr = ArgStr;
911  BOOL baud = FALSE, stop = FALSE;
912  BYTE value;
913 
914  while (argStr && *argStr)
915  {
916  while (*argStr == L' ') argStr++;
917  if (!*argStr) break;
918 
919  if (_wcsnicmp(argStr, L"BAUD=", 5) == 0)
920  {
921  baud = TRUE;
922  argStr = ParseBaudRate(argStr+5, &pDCB->BaudRate);
923  if (!argStr) return FALSE;
924  }
925  else if (_wcsnicmp(argStr, L"PARITY=", 7) == 0)
926  {
927  // Default: EVENPARITY
928  argStr = ParseParity(argStr+7, &pDCB->Parity);
929  if (!argStr) return FALSE;
930  }
931  else if (_wcsnicmp(argStr, L"DATA=", 5) == 0)
932  {
933  // Default: 7
934  argStr = ParseByteSize(argStr+5, &pDCB->ByteSize);
935  if (!argStr) return FALSE;
936  }
937  else if (_wcsnicmp(argStr, L"STOP=", 5) == 0)
938  {
939  // Default: 1, or 2 for BAUD=110
940  stop = TRUE;
941  argStr = ParseStopBits(argStr+5, &pDCB->StopBits);
942  if (!argStr) return FALSE;
943  }
944  else if (_wcsnicmp(argStr, L"TO=", 3) == 0) // TO=ON|OFF
945  {
946  /* Only total time-outs are get/set by Windows' MODE.COM */
947  argStr = ParseModes(argStr+3, &value);
948  if (!argStr) return FALSE;
949  if (value == 0) // OFF
950  {
951  pCommTimeouts->ReadTotalTimeoutConstant = 0;
952  pCommTimeouts->WriteTotalTimeoutConstant = 0;
953  }
954  else if (value == 1) // ON
955  {
956  pCommTimeouts->ReadTotalTimeoutConstant = 60000;
957  pCommTimeouts->WriteTotalTimeoutConstant = 60000;
958  }
959  else
960  {
961  return FALSE;
962  }
963  }
964  else if (_wcsnicmp(argStr, L"XON=", 4) == 0) // XON=ON|OFF
965  {
966  argStr = ParseModes(argStr+4, &value);
967  if (!argStr) return FALSE;
968  if ((value == 0) || (value == 1))
969  {
970  pDCB->fOutX = value;
971  pDCB->fInX = value;
972  }
973  else
974  {
975  return FALSE;
976  }
977  }
978  else if (_wcsnicmp(argStr, L"ODSR=", 5) == 0) // ODSR=ON|OFF
979  {
980  value = 0;
981  argStr = ParseModes(argStr+5, &value);
982  if (!argStr) return FALSE;
983  if ((value == 0) || (value == 1))
984  pDCB->fOutxDsrFlow = value;
985  else
986  return FALSE;
987  }
988  else if (_wcsnicmp(argStr, L"OCTS=", 5) == 0) // OCTS=ON|OFF
989  {
990  value = 0;
991  argStr = ParseModes(argStr+5, &value);
992  if (!argStr) return FALSE;
993  if ((value == 0) || (value == 1))
994  pDCB->fOutxCtsFlow = value;
995  else
996  return FALSE;
997  }
998  else if (_wcsnicmp(argStr, L"DTR=", 4) == 0) // DTR=ON|OFF|HS
999  {
1000  value = 0;
1001  argStr = ParseModes(argStr+4, &value);
1002  if (!argStr) return FALSE;
1003  if ((value == 0) || (value == 1) || (value == 2))
1004  pDCB->fDtrControl = value;
1005  else
1006  return FALSE;
1007  }
1008  else if (_wcsnicmp(argStr, L"RTS=", 4) == 0) // RTS=ON|OFF|HS|TG
1009  {
1010  value = 0;
1011  argStr = ParseModes(argStr+4, &value);
1012  if (!argStr) return FALSE;
1013  if ((value == 0) || (value == 1) || (value == 2) || (value == 3))
1014  pDCB->fRtsControl = value;
1015  else
1016  return FALSE;
1017  }
1018  else if (_wcsnicmp(argStr, L"IDSR=", 5) == 0) // IDSR=ON|OFF
1019  {
1020  value = 0;
1021  argStr = ParseModes(argStr+5, &value);
1022  if (!argStr) return FALSE;
1023  if ((value == 0) || (value == 1))
1024  pDCB->fDsrSensitivity = value;
1025  else
1026  return FALSE;
1027  }
1028  else
1029  {
1030  return FALSE;
1031  }
1032  }
1033 
1034  /* If stop bits were not specified, a default is always supplied */
1035  if (!stop)
1036  {
1037  if (baud && pDCB->BaudRate == 110)
1038  pDCB->StopBits = TWOSTOPBITS;
1039  else
1040  pDCB->StopBits = ONESTOPBIT;
1041  }
1042  return TRUE;
1043 }
1044 
1045 int SetSerialState(INT nPortNum, IN PCWSTR ArgStr)
1046 {
1047  BOOL Success;
1048  DCB dcb;
1049  COMMTIMEOUTS CommTimeouts;
1050 
1051  if (!SerialPortQuery(nPortNum, &dcb, &CommTimeouts, FALSE))
1052  {
1053  // TODO: Error message?
1054  return 0;
1055  }
1056 
1057  /*
1058  * Check whether we should use the old or the new MODE syntax:
1059  * in the old syntax, the separators are both spaces and commas.
1060  */
1061  if (wcschr(ArgStr, L','))
1062  Success = BuildOldCommDCB(&dcb, ArgStr);
1063  else
1064  Success = BuildNewCommDCB(&dcb, &CommTimeouts, ArgStr);
1065 
1066  if (!Success)
1067  {
1069  return 1;
1070  }
1071 
1072  SerialPortQuery(nPortNum, &dcb, &CommTimeouts, TRUE);
1073  ShowSerialStatus(nPortNum);
1074 
1075  return 0;
1076 }
1077 
1078 
1079 /*****************************************************************************\
1080  ** E N T R Y P O I N T **
1081 \*****************************************************************************/
1082 
1083 static PCWSTR
1084 FindPortNum(PCWSTR argStr, PINT PortNum)
1085 {
1086  PWSTR endptr = NULL;
1087 
1088  *PortNum = wcstol(argStr, &endptr, 10);
1089  if (endptr == argStr)
1090  {
1091  *PortNum = -1;
1092  return NULL;
1093  }
1094 
1095  return endptr;
1096 }
1097 
1099 {
1100  PWSTR Buffer, ptr;
1101  PCWSTR argStr;
1102  DWORD dwLen = MAX_PATH;
1103  INT nPortNum;
1104 
1105  /* Pre-allocate a buffer for QueryDosDeviceW() */
1106  Buffer = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
1107  if (Buffer == NULL)
1108  {
1109  /* We failed, bail out */
1110  ConPuts(StdErr, L"ERROR: Not enough memory\n");
1111  return 0;
1112  }
1113 
1114  for (;;)
1115  {
1116  *Buffer = UNICODE_NULL;
1117  if (QueryDosDeviceW(NULL, Buffer, dwLen))
1118  break;
1119 
1121  {
1122  /* We failed, bail out */
1123  ConPrintf(StdErr, L"ERROR: QueryDosDeviceW(...) failed: 0x%lx\n", GetLastError());
1125  return 0;
1126  }
1127 
1128  /* The buffer was too small, try to re-allocate it */
1129  dwLen *= 2;
1130  ptr = HeapReAlloc(GetProcessHeap(), 0, Buffer, dwLen * sizeof(WCHAR));
1131  if (ptr == NULL)
1132  {
1133  /* We failed, bail out */
1134  ConPuts(StdErr, L"ERROR: Not enough memory\n");
1136  return 0;
1137  }
1138  Buffer = ptr;
1139  }
1140 
1141  for (ptr = Buffer; *ptr != UNICODE_NULL; ptr += wcslen(ptr) + 1)
1142  {
1143  if (_wcsnicmp(ptr, L"COM", 3) == 0)
1144  {
1145  argStr = FindPortNum(ptr+3, &nPortNum);
1146  if (!argStr || *argStr || nPortNum == -1)
1147  continue;
1148 
1149  // ConResPrintf(StdOut, IDS_QUERY_SERIAL_FOUND, ptr);
1150  ShowSerialStatus(nPortNum);
1151  }
1152  else if (_wcsicmp(ptr, L"PRN") == 0)
1153  {
1155  }
1156  else if (_wcsnicmp(ptr, L"LPT", 3) == 0)
1157  {
1158  argStr = FindPortNum(ptr+3, &nPortNum);
1159  if (!argStr || *argStr || nPortNum == -1)
1160  continue;
1161 
1162  // ConResPrintf(StdOut, IDS_QUERY_PARALLEL_FOUND, ptr);
1163  ShowParallelStatus(nPortNum);
1164  }
1165  else if (_wcsicmp(ptr, L"AUX") == 0 || _wcsicmp(ptr, L"NUL") == 0)
1166  {
1168  }
1169  else
1170  {
1171  // ConResPrintf(StdOut, IDS_QUERY_MISC_FOUND, ptr);
1172  }
1173  }
1174 
1176 
1177  /* Free the buffer and return success */
1179  return 1;
1180 }
1181 
1182 int wmain(int argc, WCHAR* argv[])
1183 {
1184  int ret = 0;
1185  int arg;
1186  SIZE_T ArgStrSize;
1187  PCWSTR ArgStr, argStr;
1188 
1189  INT nPortNum;
1190 
1191  /* Initialize the Console Standard Streams */
1193 
1194  /*
1195  * MODE.COM has a very peculiar way of parsing its arguments,
1196  * as they can be even not separated by any space. This extreme
1197  * behaviour certainly is present for backwards compatibility
1198  * with the oldest versions of the utility present on MS-DOS.
1199  *
1200  * For example, such a command:
1201  * "MODE.COM COM1baud=9600parity=ndata=8stop=1xon=onto=on"
1202  * will be correctly understood as:
1203  * "MODE.COM COM1 baud=9600 parity=n data=8 stop=1 xon=on to=on"
1204  *
1205  * Note also that the "/STATUS" switch is actually really "/STA".
1206  *
1207  * However we will not use GetCommandLine() because we do not want
1208  * to deal with the prepended application path and try to find
1209  * where the arguments start. Our approach here will consist in
1210  * flattening the arguments vector.
1211  */
1212  ArgStrSize = 0;
1213 
1214  /* Compute the space needed for the new string, and allocate it */
1215  for (arg = 1; arg < argc; arg++)
1216  {
1217  ArgStrSize += wcslen(argv[arg]) + 1; // 1 for space
1218  }
1219  ArgStr = HeapAlloc(GetProcessHeap(), 0, (ArgStrSize + 1) * sizeof(WCHAR));
1220  if (ArgStr == NULL)
1221  {
1222  ConPuts(StdErr, L"ERROR: Not enough memory\n");
1223  return 1;
1224  }
1225 
1226  /* Copy the contents and NULL-terminate the string */
1227  argStr = ArgStr;
1228  for (arg = 1; arg < argc; arg++)
1229  {
1230  wcscpy((PWSTR)argStr, argv[arg]);
1231  argStr += wcslen(argv[arg]);
1232  *(PWSTR)argStr++ = L' ';
1233  }
1234  *(PWSTR)argStr = L'\0';
1235 
1236  /* Parse the command line */
1237  argStr = ArgStr;
1238 
1239  while (*argStr == L' ') argStr++;
1240  if (!*argStr) goto show_status;
1241 
1242  if (wcsstr(argStr, L"/?") || wcsstr(argStr, L"-?"))
1243  {
1245  goto Quit;
1246  }
1247  else if (_wcsnicmp(argStr, L"/STA", 4) == 0)
1248  {
1249  /* Skip this parameter */
1250  while (*argStr != L' ') argStr++;
1251  /* Skip any delimiter */
1252  while (*argStr == L' ') argStr++;
1253 
1254  /* The presence of any other parameter is invalid */
1255  if (*argStr)
1256  goto invalid_parameter;
1257 
1258  goto show_status;
1259  }
1260  else if (_wcsnicmp(argStr, L"LPT", 3) == 0)
1261  {
1262  argStr = FindPortNum(argStr+3, &nPortNum);
1263  if (!argStr || nPortNum == -1)
1264  goto invalid_parameter;
1265 
1266  if (*argStr == L':') argStr++;
1267  while (*argStr == L' ') argStr++;
1268 
1269  if (!*argStr || _wcsnicmp(argStr, L"/STA", 4) == 0)
1270  ret = ShowParallelStatus(nPortNum);
1271  else
1272  ConPuts(StdErr, L"ERROR: LPT port redirection is not implemented!\n");
1273  // TODO: Implement setting LPT port redirection using SetParallelState().
1274  goto Quit;
1275  }
1276  else if (_wcsnicmp(argStr, L"COM", 3) == 0)
1277  {
1278  argStr = FindPortNum(argStr+3, &nPortNum);
1279  if (!argStr || nPortNum == -1)
1280  goto invalid_parameter;
1281 
1282  if (*argStr == L':') argStr++;
1283  while (*argStr == L' ') argStr++;
1284 
1285  if (!*argStr || _wcsnicmp(argStr, L"/STA", 4) == 0)
1286  ret = ShowSerialStatus(nPortNum);
1287  else
1288  ret = SetSerialState(nPortNum, argStr);
1289  goto Quit;
1290  }
1291  else if (_wcsnicmp(argStr, L"CON", 3) == 0)
1292  {
1293  argStr += 3;
1294 
1295  if (*argStr == L':') argStr++;
1296  while (*argStr == L' ') argStr++;
1297 
1298  if (!*argStr || _wcsnicmp(argStr, L"/STA", 4) == 0)
1299  {
1300  ret = ShowConsoleStatus();
1301  }
1302  else if ( (_wcsnicmp(argStr, L"CP", 2) == 0 && (argStr += 2)) ||
1303  (_wcsnicmp(argStr, L"CODEPAGE", 8) == 0 && (argStr += 8)) )
1304  {
1305  while (*argStr == L' ') argStr++;
1306 
1307  if (!*argStr || _wcsnicmp(argStr, L"/STA", 4) == 0)
1309  else
1310  ret = SetConsoleCPState(argStr);
1311  }
1312  else
1313  {
1314  ret = SetConsoleState(argStr);
1315  }
1316  goto Quit;
1317  }
1318  // else if (wcschr(argStr, L','))
1319  else
1320  {
1321  /* Old syntax: MODE [COLS],[LINES] */
1322  ret = SetConsoleStateOld(argStr);
1323  goto Quit;
1324  }
1325 
1326 show_status:
1327  EnumerateDevices();
1328  goto Quit;
1329 
1330 invalid_parameter:
1332  goto Quit;
1333 
1334 Quit:
1335  /* Free the string and quit */
1336  HeapFree(GetProcessHeap(), 0, (PWSTR)ArgStr);
1337  return ret;
1338 }
#define MARKPARITY
Definition: winbase.h:453
#define IDS_ERROR_TIMEOUT_GET_DEVICE
Definition: resource.h:44
#define IDS_QUERY_PRINTER_FOUND
Definition: resource.h:7
static int argc
Definition: ServiceArgs.c:12
static PCWSTR ParseByteSize(PCWSTR argStr, PBYTE ByteSize)
Definition: mode.c:731
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
BOOL WINAPI SetConsoleOutputCP(IN UINT wCodepage)
Definition: console.c:692
#define IDS_PRINTER_OUTPUT_REROUTED_SERIAL
Definition: resource.h:34
#define max(a, b)
Definition: svc.c:63
Definition: pdh_main.c:93
#define CloseHandle
Definition: compat.h:598
#define IDS_ERROR_DEVICE_NOT_AVAILABLE
Definition: resource.h:41
BOOL WINAPI FillConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN WORD wAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: console.c:522
#define args
Definition: format.c:66
#define SPI_GETKEYBOARDSPEED
Definition: winuser.h:1342
#define IDS_CONSOLE_CODEPAGE
Definition: resource.h:32
INT ConResPrintfV(IN PCON_STREAM Stream, IN UINT uID, IN va_list args)
Definition: outstream.c:695
#define __cdecl
Definition: accygwin.h:79
_In_ ULONG Mode
Definition: hubbusif.h:303
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL WINAPI SetCommState(HANDLE handle, LPDCB lpdcb)
Definition: comm.c:807
#define RTS_CONTROL_ENABLE
Definition: winbase.h:534
BOOL WINAPI SetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
Definition: comm.c:1060
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define IDS_COM_STATUS_DTR_CIRCUIT
Definition: resource.h:26
#define TRUE
Definition: types.h:120
#define EVENPARITY
Definition: winbase.h:452
Definition: cdstruc.h:902
Definition: winbase.h:639
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define DDD_REMOVE_DEFINITION
Definition: winbase.h:521
static PCWSTR ParseModes(PCWSTR argStr, PBYTE Mode)
Definition: mode.c:642
uint16_t * PWSTR
Definition: typedefs.h:56
#define RTS_CONTROL_HANDSHAKE
Definition: winbase.h:535
#define IDS_ERROR_INVALID_STOP_BITS
Definition: resource.h:47
#define IDS_CONSOLE_KBD_RATE
Definition: resource.h:30
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:200
GLuint buffer
Definition: glext.h:5915
#define IDS_COM_STATUS_DSR_SENSITIVITY
Definition: resource.h:25
#define MAX_PORTNAME_LEN
Definition: mode.c:42
void * arg
Definition: msvc.h:10
#define IDS_USAGE
Definition: resource.h:3
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define swprintf
Definition: precomp.h:40
#define argv
Definition: mplay32.c:18
int SetConsoleCPState(IN PCWSTR ArgStr)
Definition: mode.c:452
Definition: match.c:390
int32_t INT
Definition: typedefs.h:58
#define TWOSTOPBITS
Definition: winbase.h:457
#define ONESTOPBIT
Definition: winbase.h:455
PWSTR StopBits[]
Definition: serial.c:37
void ConPuts(FILE *fp, LPCWSTR psz)
Definition: fc.c:16
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleScreenBufferSize(HANDLE hConsoleOutput, COORD dwSize)
Definition: console.c:1857
#define IDS_COM_STATUS_XON_XOFF
Definition: resource.h:22
#define SPI_SETKEYBOARDDELAY
Definition: winuser.h:1355
#define ONE5STOPBITS
Definition: winbase.h:456
#define IDS_COM_STATUS_RTS_CIRCUIT
Definition: resource.h:27
#define IDS_ERROR_INVALID_PARAMETER
Definition: resource.h:39
#define va_end(ap)
Definition: acmsvcex.h:90
int ShowConsoleCPStatus(VOID)
Definition: mode.c:189
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
unsigned int BOOL
Definition: ntddk_ex.h:94
VOID __cdecl UnderlinedResPrintf(IN PCON_STREAM Stream, IN UINT uID,...)
Definition: mode.c:50
#define DTR_CONTROL_ENABLE
Definition: winbase.h:531
#define IDS_PRINTER_OUTPUT_NOT_REROUTED
Definition: resource.h:33
short SHORT
Definition: pedump.c:59
#define GENERIC_WRITE
Definition: nt_native.h:90
static PCWSTR ParseNumber(PCWSTR argStr, PDWORD Number)
Definition: mode.c:129
#define IDS_CONSOLE_STATUS_LINES
Definition: resource.h:28
int SetConsoleStateOld(IN PCWSTR ArgStr)
Definition: mode.c:305
static PVOID ptr
Definition: dispmode.c:27
#define IDS_COM_STATUS_CTS_HANDSHAKING
Definition: resource.h:23
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(VOID)
Definition: console.c:2453
static BOOL ResizeTextConsole(IN HANDLE hConOut, IN OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi, IN COORD Resolution)
Definition: mode.c:225
BOOL WINAPI SetConsoleCursorPosition(IN HANDLE hConsoleOutput, IN COORD dwCursorPosition)
Definition: console.c:638
static VOID ClearScreen(IN HANDLE hConOut, IN PCONSOLE_SCREEN_BUFFER_INFO pcsbi)
Definition: mode.c:202
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:542
#define IDS_COM_STATUS_DATA_BITS
Definition: resource.h:19
INT ConStreamWrite(IN PCON_STREAM Stream, IN PCTCH szStr, IN DWORD len)
Definition: outstream.c:398
char * va_list
Definition: acmsvcex.h:78
Definition: bufpool.h:45
int ShowSerialStatus(INT nPortNum)
Definition: mode.c:575
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleCP(VOID)
Definition: console.c:2393
BOOL WINAPI GetCommState(HANDLE handle, LPDCB lpdcb)
Definition: comm.c:902
BOOL WINAPI GetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts)
Definition: comm.c:1018
void ConResPuts(FILE *fp, UINT nID)
Definition: fc.c:27
#define NOPARITY
Definition: winbase.h:450
#define OPEN_EXISTING
Definition: compat.h:634
int EnumerateDevices(VOID)
Definition: mode.c:1098
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:592
SHORT Left
Definition: blue.h:32
ULONG X
Definition: bl.h:1340
#define IDS_DEVICE_STATUS_HEADER
Definition: resource.h:16
#define IDS_CONSOLE_KBD_DELAY
Definition: resource.h:31
BOOL WINAPI SystemParametersInfoW(_In_ UINT, _In_ UINT, _Inout_opt_ PVOID, _In_ UINT)
int * PINT
Definition: windef.h:177
void ConResPrintf(FILE *fp, UINT nID,...)
Definition: fc.c:33
#define SPI_GETKEYBOARDDELAY
Definition: winuser.h:1354
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
SHORT Bottom
Definition: blue.h:35
#define ASSERT(a)
Definition: mode.c:44
#define IDS_COM_STATUS_STOP_BITS
Definition: resource.h:20
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SPI_SETKEYBOARDSPEED
Definition: winuser.h:1343
#define IDS_COM_STATUS_DSR_HANDSHAKING
Definition: resource.h:24
#define IDS_ERROR_TIMEOUT_SET_DEVICE
Definition: resource.h:45
#define MAX_PATH
Definition: compat.h:34
static BOOL SerialPortQuery(INT nPortNum, LPDCB pDCB, LPCOMMTIMEOUTS pCommTimeouts, BOOL bWrite)
Definition: mode.c:522
#define IDS_ERROR_STATUS_GET_DEVICE
Definition: resource.h:42
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD ReadTotalTimeoutConstant
Definition: winbase.h:705
#define Len
Definition: deflate.h:82
va_start(ap, x)
SHORT Top
Definition: blue.h:33
#define MAX_BUFFER_SIZE
int ShowConsoleStatus(VOID)
Definition: mode.c:160
int ret
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
LANGID ConSetThreadUILanguage(IN LANGID LangId OPTIONAL)
Definition: utils.c:352
#define IDS_QUERY_DOSDEV_FOUND
Definition: resource.h:10
GLsizei const GLfloat * value
Definition: glext.h:6069
#define GENERIC_READ
Definition: compat.h:135
#define STD_OUTPUT_HANDLE
Definition: winbase.h:265
#define IDS_ERROR_ILLEGAL_DEVICE_NAME
Definition: resource.h:40
#define IDS_ERROR_STATUS_SET_DEVICE
Definition: resource.h:43
#define wcsrchr
Definition: compat.h:16
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
Definition: bl.h:1338
unsigned char BYTE
Definition: xxhash.c:193
int wmain(int argc, WCHAR *argv[])
Definition: mode.c:1182
BOOL WINAPI DefineDosDeviceW(DWORD dwFlags, LPCWSTR lpDeviceName, LPCWSTR lpTargetPath)
Definition: dosdev.c:232
void ConPrintf(FILE *fp, LPCWSTR psz,...)
Definition: fc.c:20
static PCWSTR FindPortNum(PCWSTR argStr, PINT PortNum)
Definition: mode.c:1084
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCP(UINT wCodePageID)
Definition: console.c:2422
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define SPIF_UPDATEINIFILE
Definition: winuser.h:1554
#define ODDPARITY
Definition: winbase.h:451
int SetConsoleState(IN PCWSTR ArgStr)
Definition: mode.c:355
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
#define IDS_COM_STATUS_TIMEOUT
Definition: resource.h:21
#define IDS_COM_STATUS_PARITY
Definition: resource.h:18
int SetParallelState(INT nPortNum)
Definition: mode.c:111
#define HeapReAlloc
Definition: compat.h:593
#define DTR_CONTROL_HANDSHAKE
Definition: winbase.h:532
static PCWSTR ParseBaudRate(PCWSTR argStr, PDWORD BaudRate)
Definition: mode.c:669
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define SPIF_SENDCHANGE
Definition: winuser.h:1555
DWORD * PDWORD
Definition: pedump.c:68
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ConStdStreamsSetCacheCodePage(InputCodePage, OutputCodePage)
Definition: stream.h:152
static PCWSTR ParseStopBits(PCWSTR argStr, PBYTE StopBits)
Definition: mode.c:746
#define CreateFileW
Definition: compat.h:600
static BOOL BuildOldCommDCB(OUT LPDCB pDCB, IN PCWSTR ArgStr)
Definition: mode.c:775
#define skip(...)
Definition: atltest.h:64
static PCWSTR ParseParity(PCWSTR argStr, PBYTE Parity)
Definition: mode.c:699
#define StdOut
Definition: fc.c:14
#define OUT
Definition: typedefs.h:40
static BYTE Resolution
Definition: mouse.c:35
#define ConInitStdStreams()
Definition: fc.c:13
#define IDS_COM_STATUS_BAUD
Definition: resource.h:17
#define IDS_ERROR_INVALID_PARITY_BITS
Definition: resource.h:46
#define towupper(c)
Definition: wctype.h:99
SHORT Right
Definition: blue.h:34
BOOL WINAPI SetConsoleWindowInfo(HANDLE hConsoleOutput, BOOL bAbsolute, CONST SMALL_RECT *lpConsoleWindow)
Definition: console.c:1972
#define show_status(counter, text)
Definition: test.h:40
DWORD WriteTotalTimeoutConstant
Definition: winbase.h:707
int SetSerialState(INT nPortNum, IN PCWSTR ArgStr)
Definition: mode.c:1045
#define IDS_CONSOLE_STATUS_COLS
Definition: resource.h:29
#define SPACEPARITY
Definition: winbase.h:454
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393
ULONG Y
Definition: bl.h:1341
_Check_return_ _CRTIMP int __cdecl swscanf(_In_z_ const wchar_t *_Src, _In_z_ _Scanf_format_string_ const wchar_t *_Format,...)
BYTE * PBYTE
Definition: pedump.c:66
#define IDS_ERROR_SCREEN_LINES_COL
Definition: resource.h:49
#define HeapFree(x, y, z)
Definition: compat.h:594
_Inout_opt_ PUNICODE_STRING _Inout_opt_ PUNICODE_STRING Stream
Definition: fltkernel.h:1092
#define IDS_ERROR_INVALID_CODEPAGE
Definition: resource.h:50
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define IDS_ERROR_QUERY_DEVICES_FORM
Definition: resource.h:37
static BOOL BuildNewCommDCB(OUT LPDCB pDCB, OUT LPCOMMTIMEOUTS pCommTimeouts, IN PCWSTR ArgStr)
Definition: mode.c:905
BOOL WINAPI DECLSPEC_HOTPATCH FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput, IN WCHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1674
int ShowParallelStatus(INT nPortNum)
Definition: mode.c:74
#define StdErr
Definition: fc.c:15
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10