Bug 2988: slovak translation for downloader by kario@szm.sk
[reactos.git] / reactos / base / shell / cmd / start.c
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 hardcode string to En.rc
12 */
13
14 #include <precomp.h>
15
16 #ifdef INCLUDE_CMD_START
17
18
19 INT cmd_start (LPTSTR First, LPTSTR Rest)
20 {
21 TCHAR szFullName[CMDLINE_LENGTH];
22 TCHAR first[CMDLINE_LENGTH];
23 TCHAR *rest = NULL;
24 TCHAR *param = NULL;
25 TCHAR RestWithoutArgs[CMDLINE_LENGTH];
26 INT size;
27 LPTSTR comspec;
28 BOOL bWait = FALSE;
29 BOOL bBat = FALSE;
30 BOOL bCreate = FALSE;
31 TCHAR szFullCmdLine [CMDLINE_LENGTH];
32 PROCESS_INFORMATION prci;
33 STARTUPINFO stui;
34 LPTSTR *arg;
35 INT argc = 0;
36 INT i = 0;
37 DWORD Priority = 0;
38
39 RestWithoutArgs[0] = _T('\0');
40 _tcscpy(first,First);
41 arg = split (Rest, &argc, FALSE);
42
43
44 for (i = 0; i < argc; i++)
45 {
46 if (!_tcsncmp (arg[i], _T("/?"), 2))
47 {
48 freep(arg);
49 ConOutResPaging(TRUE,STRING_START_HELP1);
50 return 0;
51 }
52 else if(!_tcsicmp(arg[i], _T("/LOW")))
53 {
54 Priority = IDLE_PRIORITY_CLASS;
55 }
56 else if(!_tcsicmp(arg[i], _T("/NORMAL")))
57 {
58 Priority = NORMAL_PRIORITY_CLASS;
59 }
60 else if(!_tcsicmp(arg[i], _T("/HIGH")))
61 {
62 Priority = HIGH_PRIORITY_CLASS;
63 }
64 else if(!_tcsicmp(arg[i], _T("/REALTIME")))
65 {
66 Priority = REALTIME_PRIORITY_CLASS;
67 }
68 else if(!_tcsicmp(arg[i], _T("/ABOVENORMAL")))
69 {
70 Priority = ABOVE_NORMAL_PRIORITY_CLASS;
71 }
72 else if(!_tcsicmp(arg[i], _T("/BELOWNORMAL")))
73 {
74 Priority = BELOW_NORMAL_PRIORITY_CLASS;
75 }
76 else
77 {
78 if(RestWithoutArgs[0] != _T('\0'))
79 {
80 _tcscat(RestWithoutArgs,_T(" "));
81 }
82 _tcscat(RestWithoutArgs,arg[i]);
83 }
84 }
85
86
87
88
89 freep (arg);
90
91 /* get comspec */
92 comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR));
93 if (comspec == NULL)
94 {
95 error_out_of_memory();
96 return 1;
97 }
98 SetLastError(0);
99 size = GetEnvironmentVariable (_T("COMSPEC"), comspec, MAX_PATH);
100 if(GetLastError() == ERROR_ENVVAR_NOT_FOUND)
101 {
102 RestWithoutArgs[0] = _T('c');
103 RestWithoutArgs[1] = _T('m');
104 RestWithoutArgs[2] = _T('d');
105 RestWithoutArgs[3] = _T('\0');
106 }
107 else
108 {
109 if (size > MAX_PATH)
110 {
111 comspec = cmd_realloc(comspec,size * sizeof(TCHAR) );
112 if (comspec==NULL)
113 {
114 return 1;
115 }
116 size = GetEnvironmentVariable (_T("COMSPEC"), comspec, size);
117 }
118 }
119
120 nErrorLevel = 0;
121
122 if(!_tcslen(RestWithoutArgs))
123 {
124 _tcscpy(RestWithoutArgs,_T("\""));
125 _tcscat(RestWithoutArgs,comspec);
126 _tcscat(RestWithoutArgs,_T("\""));
127 }
128
129 rest = cmd_alloc ( (_tcslen(RestWithoutArgs) + 1) * sizeof(TCHAR));
130 if (rest == NULL)
131 {
132 if(comspec != NULL)
133 cmd_free(comspec);
134 error_out_of_memory();
135 return 1;
136 }
137
138 param = cmd_alloc ( (_tcslen(RestWithoutArgs) + 1) * sizeof(TCHAR));
139 if (param == NULL)
140 {
141 if(comspec != NULL)
142 cmd_free(comspec);
143 cmd_free(rest);
144 error_out_of_memory();
145 return 1;
146 }
147
148 param[0] = _T('\0');
149
150
151 _tcscpy(rest,RestWithoutArgs);
152
153 /* Parsing the command that gets called by start, and it's parameters */
154 if(!_tcschr(rest,_T('\"')))
155 {
156 INT count = _tcslen(rest);
157
158 /* find the end of the command and start of the args */
159 for(i = 0; i < count; i++)
160 {
161 if(rest[i] == _T(' '))
162 {
163
164 _tcscpy(param,&rest[i+1]);
165 rest[i] = _T('\0');
166 break;
167 }
168 }
169 }
170 else
171 {
172 INT count = _tcslen(rest);
173 BOOL bInside = FALSE;
174
175 /* find the end of the command and put the arguments in param */
176 for(i = 0; i < count; i++)
177 {
178 if(rest[i] == _T('\"'))
179 bInside = !bInside;
180 if((rest[i] == _T(' ')) && !bInside)
181 {
182 _tcscpy(param,&rest[i+1]);
183 rest[i] = _T('\0');
184 break;
185 }
186 }
187 i = 0;
188 /* remove any slashes */
189 while(i < count)
190 {
191 if(rest[i] == _T('\"'))
192 memmove(&rest[i],&rest[i + 1], _tcslen(&rest[i]) * sizeof(TCHAR));
193 else
194 i++;
195 }
196 }
197
198 /* check for a drive change */
199
200 if (!_tcscmp (first + 1, _T(":")) && _istalpha (*first))
201 {
202 TCHAR szPath[CMDLINE_LENGTH];
203
204 _tcscpy (szPath, _T("A:"));
205 szPath[0] = _totupper (*first);
206 SetCurrentDirectory (szPath);
207 GetCurrentDirectory (CMDLINE_LENGTH, szPath);
208 if (szPath[0] != (TCHAR)_totupper (*first))
209 ConErrResPuts (STRING_FREE_ERROR1);
210
211 if (rest != NULL)
212 cmd_free(rest);
213
214 if (param != NULL)
215 cmd_free(param);
216 if (comspec != NULL)
217 cmd_free(comspec);
218 return 0;
219 }
220
221 /* get the PATH environment variable and parse it */
222 /* search the PATH environment variable for the binary */
223 if (!SearchForExecutable (rest, szFullName))
224 {
225 error_bad_command ();
226
227 if (rest != NULL)
228 cmd_free(rest);
229
230 if (param != NULL)
231 cmd_free(param);
232
233 if (comspec != NULL)
234 cmd_free(comspec);
235 return 1;
236 }
237
238
239 /* check if this is a .BAT or .CMD file */
240 if (!_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".bat")) ||
241 !_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".cmd")))
242 {
243 bBat = TRUE;
244 memset(szFullCmdLine,0,CMDLINE_LENGTH * sizeof(TCHAR));
245
246
247 _tcscpy(szFullCmdLine,comspec);
248
249 memcpy(&szFullCmdLine[_tcslen(szFullCmdLine)],_T("\" /K \""), 6 * sizeof(TCHAR));
250 memcpy(&szFullCmdLine[_tcslen(szFullCmdLine)], szFullName, _tcslen(szFullName) * sizeof(TCHAR));
251 memcpy(&szFullCmdLine[1], &szFullCmdLine[0], _tcslen(szFullCmdLine) * sizeof(TCHAR));
252 szFullCmdLine[0] = _T('\"');
253 szFullCmdLine[_tcslen(szFullCmdLine)] = _T('\"');
254 }
255
256 #ifdef _DEBUG
257 DebugPrintf (_T("[BATCH: %s %s]\n"), szFullName, rest);
258 #endif
259
260
261 #ifdef _DEBUG
262 DebugPrintf (_T("[EXEC: %s %s]\n"), szFullName, rest);
263 #endif
264 /* build command line for CreateProcess() */
265 if (bBat == FALSE)
266 {
267 _tcscpy (szFullCmdLine, first);
268 if( param != NULL )
269 {
270
271 _tcscat(szFullCmdLine, _T(" ") );
272 _tcscat (szFullCmdLine, param);
273 }
274 }
275
276 /* fill startup info */
277 memset (&stui, 0, sizeof (STARTUPINFO));
278 stui.cb = sizeof (STARTUPINFO);
279 stui.dwFlags = STARTF_USESHOWWINDOW;
280 stui.wShowWindow = SW_SHOWDEFAULT;
281
282 if (bBat == TRUE)
283 {
284 bCreate = CreateProcess (NULL, szFullCmdLine, NULL, NULL, FALSE,
285 CREATE_NEW_CONSOLE | Priority, NULL, NULL, &stui, &prci);
286 }
287 else
288 {
289 bCreate = CreateProcess (szFullName, szFullCmdLine, NULL, NULL, FALSE,
290 CREATE_NEW_CONSOLE | Priority, NULL, NULL, &stui, &prci);
291 }
292
293 if (bCreate)
294 {
295 if (bWait)
296 {
297 DWORD dwExitCode;
298 WaitForSingleObject (prci.hProcess, INFINITE);
299 GetExitCodeProcess (prci.hProcess, &dwExitCode);
300 nErrorLevel = (INT)dwExitCode;
301 }
302 CloseHandle (prci.hThread);
303 CloseHandle (prci.hProcess);
304 /* Get New code page if it has change */
305 InputCodePage= GetConsoleCP();
306 OutputCodePage = GetConsoleOutputCP();
307 }
308 else
309 {
310 ErrorMessage(GetLastError (),
311 _T("Error executing CreateProcess()!!\n"));
312 }
313
314
315 if (rest != NULL)
316 cmd_free(rest);
317
318 if (param != NULL)
319 cmd_free(param);
320
321 if (comspec != NULL)
322 cmd_free(comspec);
323 return 0;
324 }
325
326 #endif
327
328 /* EOF */