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