ReactOS  0.4.12-dev-18-gf469aca
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  {
100  ConResPrintf(StdErr, IDS_ERROR_QUERY_DEVICES_FORM, szPortName, buffer);
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  */
280  Success = SetConsoleScreenBufferSize(hConOut, Resolution);
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;
718  *StopBits = ONE5STOPBITS;
719  }
720  else
721  {
722  if (*argStr == L'1')
723  *StopBits = ONESTOPBIT;
724  else if (*argStr == L'2')
725  *StopBits = TWOSTOPBITS;
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());
1091  HeapFree(GetProcessHeap(), 0, Buffer);
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");
1102  HeapFree(GetProcessHeap(), 0, Buffer);
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 */
1145  HeapFree(GetProcessHeap(), 0, Buffer);
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)
1275  ret = ShowConsoleCPStatus();
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
#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
Definition: get.c:139
#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
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
__wchar_t WCHAR
Definition: xmlstorage.h:180
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)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#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)
int SetConsoleCPState(IN PCWSTR ArgStr)
Definition: mode.c:453
int32_t INT
Definition: typedefs.h:56
#define TWOSTOPBITS
Definition: winbase.h:441
#define ONESTOPBIT
Definition: winbase.h:439
static char ** argv
Definition: ServiceArgs.c:11
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
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#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
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:308
#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)
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
unsigned int BOOL
Definition: ntddk_ex.h:94
#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
#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
unsigned int UINT
Definition: ndis.h:50
#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:1087
#define IDS_QUERY_DOSDEV_FOUND
Definition: resource.h:10
#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
unsigned char BYTE
Definition: ntddk_ex.h:96
int wmain(int argc, WCHAR *argv[])
Definition: mode.c:1149
BOOL WINAPI DefineDosDeviceW(DWORD dwFlags, LPCWSTR lpDeviceName, LPCWSTR lpTargetPath)
Definition: dosdev.c:77
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 skip(...)
Definition: CString.cpp:57
#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
#define SPIF_SENDCHANGE
Definition: winuser.h:1555
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
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
const uint16_t * PCWSTR
Definition: typedefs.h:55
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