2 * START.C - start internal command.
7 * 24-Jul-1999 (Eric Kohl)
10 * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
11 * Remove all hardcode string to En.rc
16 #ifdef INCLUDE_CMD_START
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
)
22 BOOL bInQuote
= FALSE
;
23 TCHAR
*start
= *pPointer
;
25 for (p
= start
; *p
; p
++)
27 if (!bInQuote
&& (*p
== _T('/') || _istspace(*p
)))
29 bInQuote
^= (*p
== _T('"'));
37 INT
cmd_start (LPTSTR Rest
)
39 TCHAR szFullName
[CMDLINE_LENGTH
];
40 TCHAR szUnquotedName
[CMDLINE_LENGTH
];
48 TCHAR szFullCmdLine
[CMDLINE_LENGTH
];
49 PROCESS_INFORMATION prci
;
52 DWORD dwCreationFlags
= CREATE_NEW_CONSOLE
| CREATE_UNICODE_ENVIRONMENT
;
54 DWORD dwCreationFlags
= CREATE_NEW_CONSOLE
;
56 DWORD dwAffinityMask
= 0;
57 LPTSTR lpTitle
= NULL
;
58 LPTSTR lpDirectory
= NULL
;
59 LPTSTR lpEnvironment
= NULL
;
60 WORD wShowWindow
= SW_SHOWNORMAL
;
68 else if (*Rest
== _T('"') && !lpTitle
)
70 lpTitle
= GetParameter(&Rest
);
73 else if (*Rest
== L
'/')
77 option
= GetParameter(&Rest
);
78 if (*option
== _T('?'))
80 ConOutResPaging(TRUE
,STRING_START_HELP1
);
83 else if (_totupper(*option
) == _T('D'))
85 lpDirectory
= option
+ 1;
88 while (_istspace(*Rest
))
90 lpDirectory
= GetParameter(&Rest
);
92 StripQuotes(lpDirectory
);
94 else if (_totupper(*option
) == _T('I'))
96 /* rest of the option is apparently ignored */
97 lpEnvironment
= lpOriginalEnvironment
;
99 else if (!_tcsicmp(option
, _T("MIN")))
101 wShowWindow
= SW_MINIMIZE
;
103 else if (!_tcsicmp(option
, _T("MAX")))
105 wShowWindow
= SW_MAXIMIZE
;
107 else if (!_tcsicmp(option
, _T("AFFINITY")))
110 while (_istspace(*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)
118 ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT
, option
);
121 dwCreationFlags
|= CREATE_SUSPENDED
;
123 else if (!_tcsicmp(option
, _T("B")))
125 dwCreationFlags
&= ~CREATE_NEW_CONSOLE
;
126 dwCreationFlags
|= CREATE_NEW_PROCESS_GROUP
;
128 else if (!_tcsicmp(option
, _T("LOW")))
130 dwCreationFlags
|= IDLE_PRIORITY_CLASS
;
132 else if (!_tcsicmp(option
, _T("NORMAL")))
134 dwCreationFlags
|= NORMAL_PRIORITY_CLASS
;
136 else if (!_tcsicmp(option
, _T("HIGH")))
138 dwCreationFlags
|= HIGH_PRIORITY_CLASS
;
140 else if (!_tcsicmp(option
, _T("REALTIME")))
142 dwCreationFlags
|= REALTIME_PRIORITY_CLASS
;
144 else if (!_tcsicmp(option
, _T("ABOVENORMAL")))
146 dwCreationFlags
|= ABOVE_NORMAL_PRIORITY_CLASS
;
148 else if (!_tcsicmp(option
, _T("BELOWNORMAL")))
150 dwCreationFlags
|= BELOW_NORMAL_PRIORITY_CLASS
;
152 else if (!_tcsicmp(option
, _T("SEPARATE")))
154 dwCreationFlags
|= CREATE_SEPARATE_WOW_VDM
;
156 else if (!_tcsicmp(option
, _T("SHARED")))
158 dwCreationFlags
|= CREATE_SHARED_WOW_VDM
;
160 else if (!_tcsicmp(option
, _T("W")) ||
161 !_tcsicmp(option
, _T("WAIT")))
167 ConErrResPrintf(STRING_TYPE_ERROR1
, option
);
173 /* It's not an option - must be the beginning of
174 * the actual command. Leave the loop. */
180 comspec
= cmd_alloc ( MAX_PATH
* sizeof(TCHAR
));
183 error_out_of_memory();
187 size
= GetEnvironmentVariable (_T("COMSPEC"), comspec
, MAX_PATH
);
188 if(GetLastError() == ERROR_ENVVAR_NOT_FOUND
)
190 _tcscpy(comspec
, _T("cmd"));
196 comspec
= cmd_realloc(comspec
,size
* sizeof(TCHAR
) );
201 size
= GetEnvironmentVariable (_T("COMSPEC"), comspec
, size
);
209 Rest
= _T("cmd.exe");
212 /* Parsing the command that gets called by start, and it's parameters */
214 BOOL bInside
= FALSE
;
216 /* find the end of the command and put the arguments in param */
217 for (i
= 0; Rest
[i
]; i
++)
219 if (Rest
[i
] == _T('\"'))
221 if (_istspace(Rest
[i
]) && !bInside
)
230 _tcscpy(szUnquotedName
, Rest
);
231 StripQuotes(szUnquotedName
);
233 /* get the PATH environment variable and parse it */
234 /* search the PATH environment variable for the binary */
235 if (SearchForExecutable(szUnquotedName
, szFullName
))
237 /* check if this is a .BAT or .CMD file */
238 dot
= _tcsrchr(szFullName
, _T('.'));
239 if (dot
&& (!_tcsicmp(dot
, _T(".bat")) || !_tcsicmp(dot
, _T(".cmd"))))
242 _stprintf(szFullCmdLine
, _T("\"%s\" /K %s"), comspec
, Rest
);
243 TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName
), debugstr_aw(Rest
));
247 TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName
), debugstr_aw(Rest
));
248 _tcscpy(szFullCmdLine
, szFullName
);
251 /* build command line for CreateProcess() */
254 _tcsncat(szFullCmdLine
, _T(" "), CMDLINE_LENGTH
- _tcslen(szFullCmdLine
));
255 _tcsncat(szFullCmdLine
, param
, CMDLINE_LENGTH
- _tcslen(szFullCmdLine
));
258 /* fill startup info */
259 memset (&stui
, 0, sizeof (STARTUPINFO
));
260 stui
.cb
= sizeof (STARTUPINFO
);
261 stui
.dwFlags
= STARTF_USESHOWWINDOW
;
262 stui
.lpTitle
= lpTitle
;
263 stui
.wShowWindow
= wShowWindow
;
265 bCreate
= CreateProcess(bBat
? comspec
: szFullName
,
266 szFullCmdLine
, NULL
, NULL
, TRUE
, dwCreationFlags
,
267 lpEnvironment
, lpDirectory
, &stui
, &prci
);
272 SetProcessAffinityMask(prci
.hProcess
, dwAffinityMask
);
273 ResumeThread(prci
.hThread
);
275 CloseHandle(prci
.hThread
);
280 /* The file name did not seem to be valid, but maybe it's actually a
281 * directory or URL, so we still want to pass it to ShellExecute. */
282 _tcscpy(szFullName
, szUnquotedName
);
287 /* CreateProcess didn't work; try ShellExecute */
288 DWORD flags
= SEE_MASK_NOCLOSEPROCESS
;
289 if (!(dwCreationFlags
& CREATE_NEW_CONSOLE
))
290 flags
|= SEE_MASK_NO_CONSOLE
;
291 prci
.hProcess
= RunFile(flags
, szFullName
, param
, lpDirectory
, wShowWindow
);
294 if (prci
.hProcess
!= NULL
)
299 WaitForSingleObject (prci
.hProcess
, INFINITE
);
300 GetExitCodeProcess (prci
.hProcess
, &dwExitCode
);
301 nErrorLevel
= (INT
)dwExitCode
;
303 CloseHandle (prci
.hProcess
);
304 /* Get New code page if it has change */
305 InputCodePage
= GetConsoleCP();
306 OutputCodePage
= GetConsoleOutputCP();
310 ErrorMessage(GetLastError (),
311 _T("Error executing CreateProcess()!!\n"));