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
;
53 DWORD dwCreationFlags
= CREATE_NEW_CONSOLE
| CREATE_UNICODE_ENVIRONMENT
;
55 DWORD dwCreationFlags
= CREATE_NEW_CONSOLE
;
57 DWORD dwAffinityMask
= 0;
58 LPTSTR lpTitle
= NULL
;
59 LPTSTR lpDirectory
= NULL
;
60 LPTSTR lpEnvironment
= NULL
;
61 WORD wShowWindow
= SW_SHOWNORMAL
;
69 else if (*Rest
== _T('"') && !lpTitle
)
71 lpTitle
= GetParameter(&Rest
);
74 else if (*Rest
== L
'/')
78 option
= GetParameter(&Rest
);
79 if (*option
== _T('?'))
81 ConOutResPaging(TRUE
,STRING_START_HELP1
);
84 else if (_totupper(*option
) == _T('D'))
86 lpDirectory
= option
+ 1;
89 while (_istspace(*Rest
))
91 lpDirectory
= GetParameter(&Rest
);
93 StripQuotes(lpDirectory
);
95 else if (_totupper(*option
) == _T('I'))
97 /* rest of the option is apparently ignored */
98 lpEnvironment
= lpOriginalEnvironment
;
100 else if (!_tcsicmp(option
, _T("MIN")))
102 wShowWindow
= SW_MINIMIZE
;
104 else if (!_tcsicmp(option
, _T("MAX")))
106 wShowWindow
= SW_MAXIMIZE
;
108 else if (!_tcsicmp(option
, _T("AFFINITY")))
111 while (_istspace(*Rest
))
113 option
= GetParameter(&Rest
);
114 /* Affinity mask is given in hexadecimal */
115 dwAffinityMask
= _tcstoul(option
, &end
, 16);
116 if (*end
!= _T('\0') || dwAffinityMask
== 0 ||
117 dwAffinityMask
== (DWORD
)-1)
119 ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT
, option
);
122 dwCreationFlags
|= CREATE_SUSPENDED
;
124 else if (!_tcsicmp(option
, _T("B")))
126 dwCreationFlags
&= ~CREATE_NEW_CONSOLE
;
127 dwCreationFlags
|= CREATE_NEW_PROCESS_GROUP
;
129 else if (!_tcsicmp(option
, _T("LOW")))
131 dwCreationFlags
|= IDLE_PRIORITY_CLASS
;
133 else if (!_tcsicmp(option
, _T("NORMAL")))
135 dwCreationFlags
|= NORMAL_PRIORITY_CLASS
;
137 else if (!_tcsicmp(option
, _T("HIGH")))
139 dwCreationFlags
|= HIGH_PRIORITY_CLASS
;
141 else if (!_tcsicmp(option
, _T("REALTIME")))
143 dwCreationFlags
|= REALTIME_PRIORITY_CLASS
;
145 else if (!_tcsicmp(option
, _T("ABOVENORMAL")))
147 dwCreationFlags
|= ABOVE_NORMAL_PRIORITY_CLASS
;
149 else if (!_tcsicmp(option
, _T("BELOWNORMAL")))
151 dwCreationFlags
|= BELOW_NORMAL_PRIORITY_CLASS
;
153 else if (!_tcsicmp(option
, _T("SEPARATE")))
155 dwCreationFlags
|= CREATE_SEPARATE_WOW_VDM
;
157 else if (!_tcsicmp(option
, _T("SHARED")))
159 dwCreationFlags
|= CREATE_SHARED_WOW_VDM
;
161 else if (!_tcsicmp(option
, _T("W")) ||
162 !_tcsicmp(option
, _T("WAIT")))
168 ConErrResPrintf(STRING_TYPE_ERROR1
, option
);
174 /* It's not an option - must be the beginning of
175 * the actual command. Leave the loop. */
181 comspec
= cmd_alloc ( MAX_PATH
* sizeof(TCHAR
));
184 error_out_of_memory();
188 size
= GetEnvironmentVariable (_T("COMSPEC"), comspec
, MAX_PATH
);
189 if(GetLastError() == ERROR_ENVVAR_NOT_FOUND
)
191 _tcscpy(comspec
, _T("cmd"));
197 comspec
= cmd_realloc(comspec
,size
* sizeof(TCHAR
) );
202 size
= GetEnvironmentVariable (_T("COMSPEC"), comspec
, size
);
210 Rest
= _T("cmd.exe");
213 /* Parsing the command that gets called by start, and it's parameters */
215 BOOL bInside
= FALSE
;
217 /* find the end of the command and put the arguments in param */
218 for (i
= 0; Rest
[i
]; i
++)
220 if (Rest
[i
] == _T('\"'))
222 if (_istspace(Rest
[i
]) && !bInside
)
231 _tcscpy(szUnquotedName
, Rest
);
232 StripQuotes(szUnquotedName
);
234 /* get the PATH environment variable and parse it */
235 /* search the PATH environment variable for the binary */
236 if (SearchForExecutable(szUnquotedName
, szFullName
))
238 /* check if this is a .BAT or .CMD file */
239 dot
= _tcsrchr(szFullName
, _T('.'));
240 if (dot
&& (!_tcsicmp(dot
, _T(".bat")) || !_tcsicmp(dot
, _T(".cmd"))))
243 _stprintf(szFullCmdLine
, _T("\"%s\" /K %s"), comspec
, Rest
);
244 TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName
), debugstr_aw(Rest
));
248 TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName
), debugstr_aw(Rest
));
249 _tcscpy(szFullCmdLine
, szFullName
);
252 /* build command line for CreateProcess() */
255 _tcsncat(szFullCmdLine
, _T(" "), CMDLINE_LENGTH
- _tcslen(szFullCmdLine
));
256 _tcsncat(szFullCmdLine
, param
, CMDLINE_LENGTH
- _tcslen(szFullCmdLine
));
259 /* fill startup info */
260 memset (&stui
, 0, sizeof (STARTUPINFO
));
261 stui
.cb
= sizeof (STARTUPINFO
);
262 stui
.dwFlags
= STARTF_USESHOWWINDOW
;
263 stui
.lpTitle
= lpTitle
;
264 stui
.wShowWindow
= wShowWindow
;
266 bCreate
= CreateProcess(bBat
? comspec
: szFullName
,
267 szFullCmdLine
, NULL
, NULL
, TRUE
, dwCreationFlags
,
268 lpEnvironment
, lpDirectory
, &stui
, &prci
);
273 SetProcessAffinityMask(prci
.hProcess
, dwAffinityMask
);
274 ResumeThread(prci
.hThread
);
276 CloseHandle(prci
.hThread
);
281 /* The file name did not seem to be valid, but maybe it's actually a
282 * directory or URL, so we still want to pass it to ShellExecute. */
283 _tcscpy(szFullName
, szUnquotedName
);
288 /* CreateProcess didn't work; try ShellExecute */
289 DWORD flags
= SEE_MASK_NOCLOSEPROCESS
;
290 if (!(dwCreationFlags
& CREATE_NEW_CONSOLE
))
291 flags
|= SEE_MASK_NO_CONSOLE
;
292 prci
.hProcess
= RunFile(flags
, szFullName
, param
, lpDirectory
, wShowWindow
);
295 if (prci
.hProcess
!= NULL
)
300 WaitForSingleObject (prci
.hProcess
, INFINITE
);
301 GetExitCodeProcess (prci
.hProcess
, &dwExitCode
);
302 nErrorLevel
= (INT
)dwExitCode
;
304 CloseHandle (prci
.hProcess
);
305 /* Get New code page if it has change */
306 InputCodePage
= GetConsoleCP();
307 OutputCodePage
= GetConsoleOutputCP();
311 ErrorMessage(GetLastError (),
312 _T("Error executing CreateProcess()!!\n"));