ReactOS  0.4.13-dev-101-g0ca4b50
start.c
Go to the documentation of this file.
1 /*
2  * START.C - start internal command.
3  *
4  *
5  * History:
6  *
7  * 24-Jul-1999 (Eric Kohl)
8  * Started.
9  *
10  * 30-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
11  * Remove all hardcoded strings in En.rc
12  */
13 
14 #include "precomp.h"
15 
16 #ifdef INCLUDE_CMD_START
17 
18 /* Find the end of an option, and turn it into a nul-terminated string
19  * in place. (It's moved back one character, to make room for the nul) */
20 static TCHAR *GetParameter(TCHAR **pPointer)
21 {
22  BOOL bInQuote = FALSE;
23  TCHAR *start = *pPointer;
24  TCHAR *p;
25  for (p = start; *p; p++)
26  {
27  if (!bInQuote && (*p == _T('/') || _istspace(*p)))
28  break;
29  bInQuote ^= (*p == _T('"'));
30  p[-1] = *p;
31  }
32  p[-1] = _T('\0');
33  *pPointer = p;
34  return start - 1;
35 }
36 
38 {
39  TCHAR szFullName[CMDLINE_LENGTH];
40  TCHAR szUnquotedName[CMDLINE_LENGTH];
41  TCHAR *param = NULL;
42  TCHAR *dot;
43  INT size;
44  LPTSTR comspec;
45  BOOL bWait = FALSE;
46  BOOL bBat = FALSE;
47  BOOL bCreate = FALSE;
48  TCHAR szFullCmdLine[CMDLINE_LENGTH];
50  STARTUPINFO stui;
51 #ifdef UNICODE
53 #else
54  DWORD dwCreationFlags = CREATE_NEW_CONSOLE;
55 #endif
56  DWORD dwAffinityMask = 0;
59  LPTSTR lpEnvironment = NULL;
60  WORD wShowWindow = SW_SHOWNORMAL;
61 
62  while (1)
63  {
64  if (_istspace(*Rest))
65  {
66  Rest++;
67  }
68  else if (*Rest == _T('"') && !lpTitle)
69  {
70  lpTitle = GetParameter(&Rest);
72  }
73  else if (*Rest == _T('/'))
74  {
75  LPTSTR option;
76  Rest++;
77  option = GetParameter(&Rest);
78  if (*option == _T('?'))
79  {
81  return 0;
82  }
83  else if (_totupper(*option) == _T('D'))
84  {
85  lpDirectory = option + 1;
86  if (!*lpDirectory)
87  {
88  while (_istspace(*Rest))
89  Rest++;
90  lpDirectory = GetParameter(&Rest);
91  }
93  }
94  else if (_totupper(*option) == _T('I'))
95  {
96  /* rest of the option is apparently ignored */
97  lpEnvironment = lpOriginalEnvironment;
98  }
99  else if (!_tcsicmp(option, _T("MIN")))
100  {
101  wShowWindow = SW_MINIMIZE;
102  }
103  else if (!_tcsicmp(option, _T("MAX")))
104  {
105  wShowWindow = SW_MAXIMIZE;
106  }
107  else if (!_tcsicmp(option, _T("AFFINITY")))
108  {
109  TCHAR *end;
110  while (_istspace(*Rest))
111  Rest++;
112  option = GetParameter(&Rest);
113  /* Affinity mask is given in hexadecimal */
114  dwAffinityMask = _tcstoul(option, &end, 16);
115  if (*end != _T('\0') || dwAffinityMask == 0 ||
116  dwAffinityMask == (DWORD)-1)
117  {
119  return 1;
120  }
121  dwCreationFlags |= CREATE_SUSPENDED;
122  }
123  else if (!_tcsicmp(option, _T("B")))
124  {
125  dwCreationFlags &= ~CREATE_NEW_CONSOLE;
126  dwCreationFlags |= CREATE_NEW_PROCESS_GROUP;
127  }
128  else if (!_tcsicmp(option, _T("LOW")))
129  {
130  dwCreationFlags |= IDLE_PRIORITY_CLASS;
131  }
132  else if (!_tcsicmp(option, _T("NORMAL")))
133  {
134  dwCreationFlags |= NORMAL_PRIORITY_CLASS;
135  }
136  else if (!_tcsicmp(option, _T("HIGH")))
137  {
138  dwCreationFlags |= HIGH_PRIORITY_CLASS;
139  }
140  else if (!_tcsicmp(option, _T("REALTIME")))
141  {
142  dwCreationFlags |= REALTIME_PRIORITY_CLASS;
143  }
144  else if (!_tcsicmp(option, _T("ABOVENORMAL")))
145  {
146  dwCreationFlags |= ABOVE_NORMAL_PRIORITY_CLASS;
147  }
148  else if (!_tcsicmp(option, _T("BELOWNORMAL")))
149  {
150  dwCreationFlags |= BELOW_NORMAL_PRIORITY_CLASS;
151  }
152  else if (!_tcsicmp(option, _T("SEPARATE")))
153  {
154  dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
155  }
156  else if (!_tcsicmp(option, _T("SHARED")))
157  {
158  dwCreationFlags |= CREATE_SHARED_WOW_VDM;
159  }
160  else if (!_tcsicmp(option, _T("W")) ||
161  !_tcsicmp(option, _T("WAIT")))
162  {
163  bWait = TRUE;
164  }
165  else
166  {
168  return 0;
169  }
170  }
171  else
172  {
173  /* It's not an option - must be the beginning of
174  * the actual command. Leave the loop. */
175  break;
176  }
177  }
178 
179  /* get comspec */
180  comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR));
181  if (!comspec)
182  {
183  WARN("Cannot allocate memory for start comspec!\n");
185  return 1;
186  }
187  SetLastError(0);
188  size = GetEnvironmentVariable (_T("COMSPEC"), comspec, MAX_PATH);
190  {
191  _tcscpy(comspec, _T("cmd"));
192  }
193  else
194  {
195  if (size > MAX_PATH)
196  {
197  LPTSTR Oldcomspec = comspec;
198  comspec = cmd_realloc(comspec,size * sizeof(TCHAR) );
199  if (comspec==NULL)
200  {
201  cmd_free(Oldcomspec);
202  return 1;
203  }
204  size = GetEnvironmentVariable (_T("COMSPEC"), comspec, size);
205  }
206  }
207 
208  nErrorLevel = 0;
209 
210  if (!*Rest)
211  {
212  Rest = _T("cmd.exe");
213  }
214  else
215  /* Parsing the command that gets called by start, and it's parameters */
216  {
217  BOOL bInside = FALSE;
218  INT i;
219  /* find the end of the command and put the arguments in param */
220  for (i = 0; Rest[i]; i++)
221  {
222  if (Rest[i] == _T('\"'))
223  bInside = !bInside;
224  if (_istspace(Rest[i]) && !bInside)
225  {
226  param = &Rest[i+1];
227  Rest[i] = _T('\0');
228  break;
229  }
230  }
231  }
232 
233  _tcscpy(szUnquotedName, Rest);
234  StripQuotes(szUnquotedName);
235 
236  /* get the PATH environment variable and parse it */
237  /* search the PATH environment variable for the binary */
238  if (SearchForExecutable(szUnquotedName, szFullName))
239  {
240  /* check if this is a .BAT or .CMD file */
241  dot = _tcsrchr(szFullName, _T('.'));
242  if (dot && (!_tcsicmp(dot, _T(".bat")) || !_tcsicmp(dot, _T(".cmd"))))
243  {
244  bBat = TRUE;
245  _stprintf(szFullCmdLine, _T("\"%s\" /K %s"), comspec, Rest);
246  TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest));
247  }
248  else
249  {
250  TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest));
251  _tcscpy(szFullCmdLine, szFullName);
252  }
253 
254  /* build command line for CreateProcess() */
255  if (param != NULL)
256  {
257  _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine));
258  _tcsncat(szFullCmdLine, param, CMDLINE_LENGTH - _tcslen(szFullCmdLine));
259  }
260 
261  /* fill startup info */
262  memset (&stui, 0, sizeof (STARTUPINFO));
263  stui.cb = sizeof (STARTUPINFO);
265  stui.lpTitle = lpTitle;
266  stui.wShowWindow = wShowWindow;
267 
268  bCreate = CreateProcess(bBat ? comspec : szFullName,
269  szFullCmdLine, NULL, NULL, TRUE, dwCreationFlags,
270  lpEnvironment, lpDirectory, &stui, &prci);
271  if (bCreate)
272  {
273  if (dwAffinityMask)
274  {
275  SetProcessAffinityMask(prci.hProcess, dwAffinityMask);
276  ResumeThread(prci.hThread);
277  }
278  CloseHandle(prci.hThread);
279  }
280  }
281  else
282  {
283  /* The file name did not seem to be valid, but maybe it's actually a
284  * directory or URL, so we still want to pass it to ShellExecute. */
285  _tcscpy(szFullName, szUnquotedName);
286  }
287 
288  if (!bCreate)
289  {
290  /* CreateProcess didn't work; try ShellExecute */
292  if (!(dwCreationFlags & CREATE_NEW_CONSOLE))
294  prci.hProcess = RunFile(flags, szFullName, param, lpDirectory, wShowWindow);
295  }
296 
297  if (prci.hProcess != NULL)
298  {
299  if (bWait)
300  {
301  DWORD dwExitCode;
303  GetExitCodeProcess (prci.hProcess, &dwExitCode);
304  nErrorLevel = (INT)dwExitCode;
305  }
306  CloseHandle (prci.hProcess);
307 
308  /* Update our local codepage cache */
309  {
310  UINT uNewInputCodePage = GetConsoleCP();
311  UINT uNewOutputCodePage = GetConsoleOutputCP();
312 
313  if ((InputCodePage != uNewInputCodePage) ||
314  (OutputCodePage != uNewOutputCodePage))
315  {
316  /* Update the locale as well */
317  InitLocale();
318  }
319 
320  InputCodePage = uNewInputCodePage;
321  OutputCodePage = uNewOutputCodePage;
322 
323  /* Update the streams codepage cache as well */
327  }
328  }
329  else
330  {
332  _T("Error executing CreateProcess()!!\n"));
333  }
334 
335  cmd_free(comspec);
336  return 0;
337 }
338 
339 #endif
340 
341 /* EOF */
VOID InitLocale(VOID)
Definition: locale.c:25
INT nErrorLevel
Definition: cmd.c:157
#define REALTIME_PRIORITY_CLASS
Definition: winbase.h:184
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
LPSTR lpTitle
Definition: winbase.h:799
static TCHAR * GetParameter(TCHAR **pPointer)
Definition: start.c:20
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:187
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:186
#define _tcsicmp
Definition: xmlstorage.h:205
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:31
VOID ErrorMessage(DWORD, LPTSTR,...)
Definition: error.c:26
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1198
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:38
#define WARN(fmt,...)
Definition: debug.h:111
#define INT
Definition: polytest.cpp:20
#define debugstr_aw
Definition: precomp.h:43
#define CMDLINE_LENGTH
Definition: help.h:12
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
DWORD dwFlags
Definition: winbase.h:807
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
GLuint GLuint end
Definition: gl.h:1545
#define NORMAL_PRIORITY_CLASS
Definition: winbase.h:181
#define _totupper
Definition: tchar.h:1509
#define ERROR_ENVVAR_NOT_FOUND
Definition: winerror.h:261
HANDLE RunFile(DWORD flags, LPTSTR filename, LPTSTR params, LPTSTR directory, INT show)
Definition: cmd.c:265
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:185
static VOID StripQuotes(LPSTR in)
Definition: cmdcons.c:116
int32_t INT
Definition: typedefs.h:56
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define ABOVE_NORMAL_PRIORITY_CLASS
Definition: winbase.h:191
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
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 CREATE_SUSPENDED
Definition: winbase.h:178
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ConErrResPrintf(uID,...)
Definition: console.h:51
BOOL WINAPI SetProcessAffinityMask(IN HANDLE hProcess, IN DWORD_PTR dwProcessAffinityMask)
Definition: proc.c:924
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(VOID)
Definition: console.c:2453
BOOL ConStreamSetCacheCodePage(IN PCON_STREAM Stream, IN UINT CacheCodePage)
Definition: stream.c:215
#define HIGH_PRIORITY_CLASS
Definition: winbase.h:183
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
Definition: getopt.h:108
VOID error_out_of_memory(VOID)
Definition: error.c:136
BOOL SearchForExecutable(LPCTSTR, LPTSTR)
Definition: where.c:142
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleCP(VOID)
Definition: console.c:2393
#define STARTF_USESHOWWINDOW
Definition: winbase.h:472
UINT InputCodePage
Definition: console.c:25
#define STRING_TYPE_ERROR1
Definition: resource.h:58
GLuint GLenum option
Definition: glext.h:11211
_In_opt_ LPCSTR lpDirectory
Definition: shellapi.h:482
#define CREATE_SHARED_WOW_VDM
Definition: winbase.h:188
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
_TCHAR * _tcsncat(_TCHAR *dst, const _TCHAR *src, size_t n)
Definition: tcsncat.h:5
#define TRACE(s)
Definition: solgame.cpp:4
#define IDLE_PRIORITY_CLASS
Definition: winbase.h:182
GLsizeiptr size
Definition: glext.h:5919
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
DWORD cb
Definition: winbase.h:796
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:26
LPTSTR lpOriginalEnvironment
Definition: cmd.c:163
UINT OutputCodePage
Definition: console.c:26
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:409
#define StdErr
Definition: stream.h:77
#define SW_MINIMIZE
Definition: winuser.h:770
GLbitfield flags
Definition: glext.h:7161
#define STRING_ERROR_INVALID_PARAM_FORMAT
Definition: resource.h:5
#define cmd_realloc(ptr, size)
Definition: cmddbg.h:30
#define _tcstoul
Definition: tchar.h:595
#define CreateProcess
Definition: winbase.h:3572
INT cmd_start(LPTSTR Rest)
Definition: start.c:37
#define _stprintf
Definition: utility.h:124
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define cmd_free(ptr)
Definition: cmddbg.h:31
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1435
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3533
GLuint start
Definition: gl.h:1545
unsigned int UINT
Definition: ndis.h:50
WORD wShowWindow
Definition: winbase.h:808
#define STRING_START_HELP1
Definition: resource.h:180
_TCHAR * _tcsrchr(const _TCHAR *s, _XINT c)
Definition: tcsrchr.h:4
#define StdOut
Definition: stream.h:76
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:529
TCHAR lpTitle[80]
Definition: ctm.c:69
#define _istspace
Definition: tchar.h:1504
#define BELOW_NORMAL_PRIORITY_CLASS
Definition: winbase.h:190
#define GetEnvironmentVariable
Definition: winbase.h:3628
GLfloat GLfloat p
Definition: glext.h:8902
#define INFINITE
Definition: serial.h:102
#define memset(x, y, z)
Definition: compat.h:39
#define SW_MAXIMIZE
Definition: winuser.h:766
#define StdIn
Definition: stream.h:75