ReactOS  0.4.14-dev-358-gbef841c
ctty.c File Reference
#include "precomp.h"
Include dependency graph for ctty.c:

Go to the source code of this file.

Functions

static WORD CheckTerminalDeviceType (IN LPCTSTR pszName)
 
INT cmd_ctty (LPTSTR param)
 

Function Documentation

◆ CheckTerminalDeviceType()

static WORD CheckTerminalDeviceType ( IN LPCTSTR  pszName)
static

Definition at line 30 of file ctty.c.

31 {
32  /* Console reserved "file" names */
33  static const LPCWSTR DosLPTDevice = L"LPT";
34  static const LPCWSTR DosCOMDevice = L"COM";
35  static const LPCWSTR DosPRNDevice = L"PRN";
36  static const LPCWSTR DosAUXDevice = L"AUX";
37  static const LPCWSTR DosCONDevice = L"CON";
38  static const LPCWSTR DosNULDevice = L"NUL";
39 
41  ULONG DeviceNameInfo;
42  WORD DeviceType = 0; // 0: Unknown; 1: CON; 2: COM etc...
43 
44 #ifndef _UNICODE // UNICODE means that TCHAR == WCHAR == UTF-16
45  /* Convert from the current process/thread's codepage to UTF-16 */
46  DWORD len = strlen(pszName) + 1;
47  WCHAR *buffer = cmd_alloc(len * sizeof(WCHAR));
48  if (!buffer)
49  {
50  // SetLastError(ERROR_NOT_ENOUGH_MEMORY);
51  return FALSE;
52  }
53  len = (DWORD)MultiByteToWideChar(CP_THREAD_ACP, // CP_ACP, CP_OEMCP
54  0, pszName, (INT)len, buffer, (INT)len);
56 #else
57  DeviceName = pszName;
58 #endif
59 
60  /*
61  * Check whether we deal with a DOS device, and if so,
62  * strip the path till the file name.
63  * Therefore, things like \\.\CON or C:\some_path\COM1
64  * are transformed into CON or COM1, for example.
65  */
66  DeviceNameInfo = RtlIsDosDeviceName_U(DeviceName);
67  if (DeviceNameInfo != 0)
68  {
69  DeviceName = (LPCWSTR)((ULONG_PTR)DeviceName + ((DeviceNameInfo >> 16) & 0xFFFF));
70 
71  if (_wcsnicmp(DeviceName, DosCONDevice, 3) == 0)
72  {
73  DeviceType = 1;
74  }
75  else
76  if ( _wcsnicmp(DeviceName, DosLPTDevice, 3) == 0 ||
77  _wcsnicmp(DeviceName, DosCOMDevice, 3) == 0 ||
78  _wcsnicmp(DeviceName, DosPRNDevice, 3) == 0 ||
79  _wcsnicmp(DeviceName, DosAUXDevice, 3) == 0 ||
80  _wcsnicmp(DeviceName, DosNULDevice, 3) == 0 )
81  {
82  DeviceType = 2;
83  }
84  // else DeviceType = 0;
85  }
86 
87 #ifndef _UNICODE
89 #endif
90 
91  return DeviceType;
92 }
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DeviceType
Definition: mmdrv.h:41
#define INT
Definition: polytest.cpp:20
_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)
GLuint buffer
Definition: glext.h:5915
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:63
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
GLenum GLsizei len
Definition: glext.h:6722
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define MultiByteToWideChar
Definition: compat.h:100
unsigned int ULONG
Definition: retypes.h:1
#define CP_THREAD_ACP
Definition: winnls.h:230
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)

Referenced by cmd_ctty().

◆ cmd_ctty()

INT cmd_ctty ( LPTSTR  param)

Definition at line 102 of file ctty.c.

103 {
104  static SECURITY_ATTRIBUTES SecAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
105 
106  BOOL Success;
108  HANDLE hDevice, hStdHandles[3]; // hStdIn, hStdOut, hStdErr;
109 
110  /* The user asked for help */
111  if (_tcsncmp(param, _T("/?"), 2) == 0)
112  {
114  return 0;
115  }
116 
117  if (!*param)
118  {
120  return 1;
121  }
122 
123  /* Check whether this is a valid terminal device name */
125  if (DeviceType == 1)
126  {
127  /*
128  * Special case for CON device.
129  *
130  * We do not open CON with GENERIC_READ or GENERIC_WRITE as is,
131  * but instead we separately open CONIN$ and CONOUT$ with both
132  * GENERIC_READ | GENERIC_WRITE access.
133  * We do so because otherwise, opening in particular CON with GENERIC_WRITE
134  * only would open CONOUT$ with an handle not passing the IsConsoleHandle()
135  * test, meaning that we could not use the full console functionalities.
136  */
137  BOOL bRetry = FALSE;
138 
139 RetryOpenConsole:
140  /*
141  * If we previously failed in opening handles to the console,
142  * this means the existing console is almost destroyed.
143  * Close the existing console and allocate and open a new one.
144  */
145  if (bRetry)
146  {
147  FreeConsole();
148  if (!AllocConsole())
149  return 1;
150  }
151 
152  /* Attempt to retrieve a handle for standard input */
153  hStdHandles[0] = CreateFile(_T("CONIN$"),
156  &SecAttr,
158  0,
159  NULL);
160  if (hStdHandles[0] == INVALID_HANDLE_VALUE)
161  {
162  // TODO: Error
163  // error_no_rw_device(param);
164 
165  if (bRetry)
166  return 1;
167  bRetry = TRUE;
168  goto RetryOpenConsole;
169  }
170 
171  /* Attempt to retrieve a handle for standard output.
172  * Note that GENERIC_READ is needed for IsConsoleHandle() to succeed afterwards. */
173  hStdHandles[1] = CreateFile(_T("CONOUT$"),
176  &SecAttr,
178  0,
179  NULL);
180  if (hStdHandles[1] == INVALID_HANDLE_VALUE)
181  {
182  // TODO: Error
183  // error_no_rw_device(param);
184 
185  CloseHandle(hStdHandles[0]);
186 
187  if (bRetry)
188  return 1;
189  bRetry = TRUE;
190  goto RetryOpenConsole;
191  }
192 
193  /* Duplicate a handle for standard error */
195  hStdHandles[1],
197  &hStdHandles[2],
198  0, // GENERIC_WRITE,
199  TRUE,
200  DUPLICATE_SAME_ACCESS /* 0 */);
201  if (!Success)
202  {
203  // TODO: Error
204  // error_no_rw_device(param);
205  CloseHandle(hStdHandles[1]);
206  CloseHandle(hStdHandles[0]);
207  return 1;
208  }
209  }
210  else if (DeviceType == 2)
211  {
212  /*
213  * COM and the other devices can only be opened once.
214  * Since we need different handles, we need to duplicate them.
215  */
216 
217  /* Attempt to retrieve a handle to the device for read/write access */
218  hDevice = CreateFile(param,
221  &SecAttr,
223  0, // FILE_FLAG_OVERLAPPED, // 0,
224  NULL);
225  if (hDevice == INVALID_HANDLE_VALUE)
226  {
227  // TODO: Error
228  // error_no_rw_device(param);
229  return 1;
230  }
231 
232  /* Duplicate a handle for standard input */
234  hDevice,
236  &hStdHandles[0],
237  GENERIC_READ,
238  TRUE,
239  0);
240  if (!Success)
241  {
242  // TODO: Error
243  // error_no_rw_device(param);
244  CloseHandle(hDevice);
245  return 1;
246  }
247 
248  /* Duplicate a handle for standard output */
250  hDevice,
252  &hStdHandles[1],
254  TRUE,
255  0);
256  if (!Success)
257  {
258  // TODO: Error
259  // error_no_rw_device(param);
260  CloseHandle(hStdHandles[0]);
261  CloseHandle(hDevice);
262  return 1;
263  }
264 
265  /* Duplicate a handle for standard error */
267  hDevice,
269  &hStdHandles[2],
271  TRUE,
272  0);
273  if (!Success)
274  {
275  // TODO: Error
276  // error_no_rw_device(param);
277  CloseHandle(hStdHandles[1]);
278  CloseHandle(hStdHandles[0]);
279  CloseHandle(hDevice);
280  return 1;
281  }
282 
283  /* Now get rid of the main device handle */
284  CloseHandle(hDevice);
285  }
286  else
287  {
288  // FIXME: Localize!
289  ConOutPrintf(L"Invalid device '%s'\n", param);
290  return 1;
291  }
292 
293 #if 0
294  /* Now change the file descriptors:
295  0 := rdonly
296  1,2 := wronly
297 
298  if CTTY is called within a pipe or its I/O is redirected,
299  oldinfd or oldoutfd is not equal to -1. In such case the
300  old*fd is modified in order to effect the file descriptor
301  after the redirections are restored. Otherwise a pipe or
302  redirection would left CTTY in a half-made status.
303  */
304  // int failed;
305  failed = dup2(f, 2); /* no redirection support */
306  if(oldinfd != -1)
307  dos_close(oldinfd);
308  oldinfd = f;
309  if(oldoutfd != -1)
310  dos_close(oldoutfd);
311  if((oldoutfd = dup(f)) == -1)
312  failed = 1;
313 
314  if(failed)
315  error_ctty_dup(param);
316 
317  return failed;
318 #endif
319 
320  /* Now set the standard handles */
321 
322  hDevice = GetHandle(0);
323  if (hDevice != INVALID_HANDLE_VALUE)
324  CloseHandle(hDevice);
325  SetHandle(0, hStdHandles[0]);
326 
327  hDevice = GetHandle(1);
328  if (hDevice != INVALID_HANDLE_VALUE)
329  CloseHandle(hDevice);
330  SetHandle(1, hStdHandles[1]);
331 
332  hDevice = GetHandle(2);
333  if (hDevice != INVALID_HANDLE_VALUE)
334  CloseHandle(hDevice);
335  SetHandle(2, hStdHandles[2]);
336 
337  return 0;
338 }
#define GetHandle(h)
Definition: treelist.c:116
#define TRUE
Definition: types.h:120
BOOL WINAPI AllocConsole(VOID)
Definition: console.c:48
#define CloseHandle
Definition: compat.h:406
DeviceType
Definition: mmdrv.h:41
static WORD CheckTerminalDeviceType(IN LPCTSTR pszName)
Definition: ctty.c:30
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
#define ConOutPrintf(szStr,...)
Definition: console.h:42
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:125
VOID SetHandle(UINT Number, HANDLE Handle)
Definition: redir.c:50
#define DUPLICATE_SAME_ACCESS
unsigned int BOOL
Definition: ntddk_ex.h:94
VOID error_req_param_missing(VOID)
Definition: error.c:108
#define GENERIC_WRITE
Definition: nt_native.h:90
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP int __cdecl dup2(_In_ int _FileHandleSrc, _In_ int _FileHandleDst)
#define OPEN_EXISTING
Definition: compat.h:434
GLfloat f
Definition: glext.h:7540
BOOL WINAPI FreeConsole(VOID)
Definition: console.c:105
#define _T(x)
Definition: vfdio.h:22
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1138
GLfloat param
Definition: glext.h:5796
unsigned short WORD
Definition: ntddk_ex.h:93
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:124
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:904
#define f
Definition: ke_i.h:83
_Check_return_ _CRTIMP int __cdecl dup(_In_ int _FileHandle)
int _tcsncmp(const _TCHAR *s1, const _TCHAR *s2, size_t n)
Definition: tcsncmp.h:9
#define STRING_CTTY_HELP
Definition: resource.h:86
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES