ReactOS 0.4.15-dev-7928-g68a8619
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) */
20static 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;
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 {
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++;
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 the local code page cache */
309 {
310 UINT uNewInputCodePage = GetConsoleCP();
311 UINT uNewOutputCodePage = GetConsoleOutputCP();
312
313 if ((InputCodePage != uNewInputCodePage) ||
314 (OutputCodePage != uNewOutputCodePage))
315 {
316 InputCodePage = uNewInputCodePage;
317 OutputCodePage = uNewOutputCodePage;
318
319 /* Reset the current thread UI language */
322 {
324 }
325 /* Update the streams cached code page */
327
328 /* Update the locale as well */
329 InitLocale();
330 }
331 }
332 }
333 else
334 {
336 _T("Error executing CreateProcess()!!\n"));
337 }
338
339 cmd_free(comspec);
340 return 0;
341}
342
343#endif
344
345/* EOF */
static VOID ErrorMessage(_In_ DWORD dwErrorCode, _In_opt_ PCWSTR pszMsg,...)
Definition: attrib.c:33
#define STRING_ERROR_INVALID_PARAM_FORMAT
Definition: resource.h:5
#define StdOut
Definition: fc.c:14
#define StdErr
Definition: fc.c:15
#define CMDLINE_LENGTH
Definition: help.h:12
INT nErrorLevel
Definition: cmd.c:158
LPTSTR lpOriginalEnvironment
Definition: cmd.c:164
HANDLE RunFile(DWORD flags, LPTSTR filename, LPTSTR params, LPTSTR directory, INT show)
Definition: cmd.c:266
BOOL SearchForExecutable(LPCTSTR, LPTSTR)
Definition: where.c:142
VOID InitLocale(VOID)
Definition: locale.c:25
VOID error_out_of_memory(VOID)
Definition: error.c:138
UINT InputCodePage
Definition: console.c:25
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
UINT OutputCodePage
Definition: console.c:26
#define ConErrResPrintf(uID,...)
Definition: console.h:50
#define debugstr_aw
Definition: precomp.h:43
#define STRING_TYPE_ERROR
Definition: resource.h:58
#define STRING_START_HELP1
Definition: resource.h:173
#define WARN(fmt,...)
Definition: debug.h:112
static VOID StripQuotes(LPSTR in)
Definition: cmdcons.c:116
#define cmd_realloc(ptr, size)
Definition: cmddbg.h:30
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
TCHAR lpTitle[80]
Definition: ctm.c:69
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define SetLastError(x)
Definition: compat.h:752
#define MAX_PATH
Definition: compat.h:34
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(VOID)
Definition: console.c:2451
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleCP(VOID)
Definition: console.c:2391
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
BOOL WINAPI SetProcessAffinityMask(IN HANDLE hProcess, IN DWORD_PTR dwProcessAffinityMask)
Definition: proc.c:894
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint start
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
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 _istspace
Definition: tchar.h:1504
#define _tcscpy
Definition: tchar.h:623
#define _tcstoul
Definition: tchar.h:595
#define _tcsncat
Definition: tchar.h:1408
#define _totupper
Definition: tchar.h:1509
#define _stprintf
Definition: utility.h:124
#define _tcsrchr
Definition: utility.h:116
unsigned int UINT
Definition: ndis.h:50
#define INT
Definition: polytest.cpp:20
#define IsConsoleHandle(h)
Definition: console.h:14
HANDLE ConStreamGetOSHandle(IN PCON_STREAM Stream)
Definition: stream.c:240
#define ConStdStreamsSetCacheCodePage(InputCodePage, OutputCodePage)
Definition: stream.h:152
LANGID ConSetThreadUILanguage(IN LANGID LangId OPTIONAL)
Definition: utils.c:352
#define memset(x, y, z)
Definition: compat.h:39
static TCHAR * GetParameter(TCHAR **pPointer)
Definition: start.c:20
INT cmd_start(LPTSTR Rest)
Definition: start.c:37
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:31
_In_opt_ LPCSTR lpDirectory
Definition: shellapi.h:484
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:38
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1511
#define TRACE(s)
Definition: solgame.cpp:4
LPSTR lpTitle
Definition: winbase.h:834
DWORD dwFlags
Definition: winbase.h:842
DWORD cb
Definition: winbase.h:831
WORD wShowWindow
Definition: winbase.h:843
Definition: getopt.h:109
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
int32_t INT
Definition: typedefs.h:58
#define _T(x)
Definition: vfdio.h:22
#define GetEnvironmentVariable
Definition: winbase.h:3814
#define CreateProcess
Definition: winbase.h:3758
#define NORMAL_PRIORITY_CLASS
Definition: winbase.h:181
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define STARTF_USESHOWWINDOW
Definition: winbase.h:491
#define REALTIME_PRIORITY_CLASS
Definition: winbase.h:184
#define BELOW_NORMAL_PRIORITY_CLASS
Definition: winbase.h:190
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3719
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:186
#define HIGH_PRIORITY_CLASS
Definition: winbase.h:183
#define CREATE_SHARED_WOW_VDM
Definition: winbase.h:188
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:187
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:185
#define CREATE_SUSPENDED
Definition: winbase.h:178
#define IDLE_PRIORITY_CLASS
Definition: winbase.h:182
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
#define ABOVE_NORMAL_PRIORITY_CLASS
Definition: winbase.h:191
#define ERROR_ENVVAR_NOT_FOUND
Definition: winerror.h:261
#define SW_SHOWNORMAL
Definition: winuser.h:770
#define SW_MINIMIZE
Definition: winuser.h:776
#define SW_MAXIMIZE
Definition: winuser.h:772
char TCHAR
Definition: xmlstorage.h:189
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198
#define _tcsicmp
Definition: xmlstorage.h:205