Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstart.c
Go to the documentation of this file.
00001 /* 00002 * START.C - start internal command. 00003 * 00004 * 00005 * History: 00006 * 00007 * 24-Jul-1999 (Eric Kohl) 00008 * Started. 00009 * 00010 * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>) 00011 * Remove all hardcode string to En.rc 00012 */ 00013 00014 #include <precomp.h> 00015 00016 #ifdef INCLUDE_CMD_START 00017 00018 /* Find the end of an option, and turn it into a nul-terminated string 00019 * in place. (It's moved back one character, to make room for the nul) */ 00020 static TCHAR *GetParameter(TCHAR **pPointer) 00021 { 00022 BOOL bInQuote = FALSE; 00023 TCHAR *start = *pPointer; 00024 TCHAR *p; 00025 for (p = start; *p; p++) 00026 { 00027 if (!bInQuote && (*p == _T('/') || _istspace(*p))) 00028 break; 00029 bInQuote ^= (*p == _T('"')); 00030 p[-1] = *p; 00031 } 00032 p[-1] = _T('\0'); 00033 *pPointer = p; 00034 return start - 1; 00035 } 00036 00037 INT cmd_start (LPTSTR Rest) 00038 { 00039 TCHAR szFullName[CMDLINE_LENGTH]; 00040 TCHAR szUnquotedName[CMDLINE_LENGTH]; 00041 TCHAR *param = NULL; 00042 TCHAR *dot; 00043 INT size; 00044 LPTSTR comspec; 00045 BOOL bWait = FALSE; 00046 BOOL bBat = FALSE; 00047 BOOL bCreate = FALSE; 00048 TCHAR szFullCmdLine [CMDLINE_LENGTH]; 00049 PROCESS_INFORMATION prci; 00050 STARTUPINFO stui; 00051 #ifdef UNICODE 00052 DWORD dwCreationFlags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT; 00053 #else 00054 DWORD dwCreationFlags = CREATE_NEW_CONSOLE; 00055 #endif 00056 DWORD dwAffinityMask = 0; 00057 LPTSTR lpTitle = NULL; 00058 LPTSTR lpDirectory = NULL; 00059 LPTSTR lpEnvironment = NULL; 00060 WORD wShowWindow = SW_SHOWNORMAL; 00061 00062 while (1) 00063 { 00064 if (_istspace(*Rest)) 00065 { 00066 Rest++; 00067 } 00068 else if (*Rest == _T('"') && !lpTitle) 00069 { 00070 lpTitle = GetParameter(&Rest); 00071 StripQuotes(lpTitle); 00072 } 00073 else if (*Rest == L'/') 00074 { 00075 LPTSTR option; 00076 Rest++; 00077 option = GetParameter(&Rest); 00078 if (*option == _T('?')) 00079 { 00080 ConOutResPaging(TRUE,STRING_START_HELP1); 00081 return 0; 00082 } 00083 else if (_totupper(*option) == _T('D')) 00084 { 00085 lpDirectory = option + 1; 00086 if (!*lpDirectory) 00087 { 00088 while (_istspace(*Rest)) 00089 Rest++; 00090 lpDirectory = GetParameter(&Rest); 00091 } 00092 StripQuotes(lpDirectory); 00093 } 00094 else if (_totupper(*option) == _T('I')) 00095 { 00096 /* rest of the option is apparently ignored */ 00097 lpEnvironment = lpOriginalEnvironment; 00098 } 00099 else if (!_tcsicmp(option, _T("MIN"))) 00100 { 00101 wShowWindow = SW_MINIMIZE; 00102 } 00103 else if (!_tcsicmp(option, _T("MAX"))) 00104 { 00105 wShowWindow = SW_MAXIMIZE; 00106 } 00107 else if (!_tcsicmp(option, _T("AFFINITY"))) 00108 { 00109 TCHAR *end; 00110 while (_istspace(*Rest)) 00111 Rest++; 00112 option = GetParameter(&Rest); 00113 /* Affinity mask is given in hexadecimal */ 00114 dwAffinityMask = _tcstoul(option, &end, 16); 00115 if (*end != _T('\0') || dwAffinityMask == 0 || 00116 dwAffinityMask == (DWORD)-1) 00117 { 00118 ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, option); 00119 return 1; 00120 } 00121 dwCreationFlags |= CREATE_SUSPENDED; 00122 } 00123 else if (!_tcsicmp(option, _T("B"))) 00124 { 00125 dwCreationFlags &= ~CREATE_NEW_CONSOLE; 00126 dwCreationFlags |= CREATE_NEW_PROCESS_GROUP; 00127 } 00128 else if (!_tcsicmp(option, _T("LOW"))) 00129 { 00130 dwCreationFlags |= IDLE_PRIORITY_CLASS; 00131 } 00132 else if (!_tcsicmp(option, _T("NORMAL"))) 00133 { 00134 dwCreationFlags |= NORMAL_PRIORITY_CLASS; 00135 } 00136 else if (!_tcsicmp(option, _T("HIGH"))) 00137 { 00138 dwCreationFlags |= HIGH_PRIORITY_CLASS; 00139 } 00140 else if (!_tcsicmp(option, _T("REALTIME"))) 00141 { 00142 dwCreationFlags |= REALTIME_PRIORITY_CLASS; 00143 } 00144 else if (!_tcsicmp(option, _T("ABOVENORMAL"))) 00145 { 00146 dwCreationFlags |= ABOVE_NORMAL_PRIORITY_CLASS; 00147 } 00148 else if (!_tcsicmp(option, _T("BELOWNORMAL"))) 00149 { 00150 dwCreationFlags |= BELOW_NORMAL_PRIORITY_CLASS; 00151 } 00152 else if (!_tcsicmp(option, _T("SEPARATE"))) 00153 { 00154 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; 00155 } 00156 else if (!_tcsicmp(option, _T("SHARED"))) 00157 { 00158 dwCreationFlags |= CREATE_SHARED_WOW_VDM; 00159 } 00160 else if (!_tcsicmp(option, _T("W")) || 00161 !_tcsicmp(option, _T("WAIT"))) 00162 { 00163 bWait = TRUE; 00164 } 00165 else 00166 { 00167 ConErrResPrintf(STRING_TYPE_ERROR1, option); 00168 return 0; 00169 } 00170 } 00171 else 00172 { 00173 /* It's not an option - must be the beginning of 00174 * the actual command. Leave the loop. */ 00175 break; 00176 } 00177 } 00178 00179 /* get comspec */ 00180 comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR)); 00181 if (comspec == NULL) 00182 { 00183 error_out_of_memory(); 00184 return 1; 00185 } 00186 SetLastError(0); 00187 size = GetEnvironmentVariable (_T("COMSPEC"), comspec, MAX_PATH); 00188 if(GetLastError() == ERROR_ENVVAR_NOT_FOUND) 00189 { 00190 _tcscpy(comspec, _T("cmd")); 00191 } 00192 else 00193 { 00194 if (size > MAX_PATH) 00195 { 00196 comspec = cmd_realloc(comspec,size * sizeof(TCHAR) ); 00197 if (comspec==NULL) 00198 { 00199 return 1; 00200 } 00201 size = GetEnvironmentVariable (_T("COMSPEC"), comspec, size); 00202 } 00203 } 00204 00205 nErrorLevel = 0; 00206 00207 if (!*Rest) 00208 { 00209 Rest = _T("cmd.exe"); 00210 } 00211 else 00212 /* Parsing the command that gets called by start, and it's parameters */ 00213 { 00214 BOOL bInside = FALSE; 00215 INT i; 00216 /* find the end of the command and put the arguments in param */ 00217 for (i = 0; Rest[i]; i++) 00218 { 00219 if (Rest[i] == _T('\"')) 00220 bInside = !bInside; 00221 if (_istspace(Rest[i]) && !bInside) 00222 { 00223 param = &Rest[i+1]; 00224 Rest[i] = _T('\0'); 00225 break; 00226 } 00227 } 00228 } 00229 00230 _tcscpy(szUnquotedName, Rest); 00231 StripQuotes(szUnquotedName); 00232 00233 /* get the PATH environment variable and parse it */ 00234 /* search the PATH environment variable for the binary */ 00235 if (SearchForExecutable(szUnquotedName, szFullName)) 00236 { 00237 /* check if this is a .BAT or .CMD file */ 00238 dot = _tcsrchr(szFullName, _T('.')); 00239 if (dot && (!_tcsicmp(dot, _T(".bat")) || !_tcsicmp(dot, _T(".cmd")))) 00240 { 00241 bBat = TRUE; 00242 _stprintf(szFullCmdLine, _T("\"%s\" /K %s"), comspec, Rest); 00243 TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest)); 00244 } 00245 else 00246 { 00247 TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest)); 00248 _tcscpy(szFullCmdLine, szFullName); 00249 } 00250 00251 /* build command line for CreateProcess() */ 00252 if (param != NULL) 00253 { 00254 _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); 00255 _tcsncat(szFullCmdLine, param, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); 00256 } 00257 00258 /* fill startup info */ 00259 memset (&stui, 0, sizeof (STARTUPINFO)); 00260 stui.cb = sizeof (STARTUPINFO); 00261 stui.dwFlags = STARTF_USESHOWWINDOW; 00262 stui.lpTitle = lpTitle; 00263 stui.wShowWindow = wShowWindow; 00264 00265 bCreate = CreateProcess(bBat ? comspec : szFullName, 00266 szFullCmdLine, NULL, NULL, TRUE, dwCreationFlags, 00267 lpEnvironment, lpDirectory, &stui, &prci); 00268 if (bCreate) 00269 { 00270 if (dwAffinityMask) 00271 { 00272 SetProcessAffinityMask(prci.hProcess, dwAffinityMask); 00273 ResumeThread(prci.hThread); 00274 } 00275 CloseHandle(prci.hThread); 00276 } 00277 } 00278 else 00279 { 00280 /* The file name did not seem to be valid, but maybe it's actually a 00281 * directory or URL, so we still want to pass it to ShellExecute. */ 00282 _tcscpy(szFullName, szUnquotedName); 00283 } 00284 00285 if (!bCreate) 00286 { 00287 /* CreateProcess didn't work; try ShellExecute */ 00288 DWORD flags = SEE_MASK_NOCLOSEPROCESS; 00289 if (!(dwCreationFlags & CREATE_NEW_CONSOLE)) 00290 flags |= SEE_MASK_NO_CONSOLE; 00291 prci.hProcess = RunFile(flags, szFullName, param, lpDirectory, wShowWindow); 00292 } 00293 00294 if (prci.hProcess != NULL) 00295 { 00296 if (bWait) 00297 { 00298 DWORD dwExitCode; 00299 WaitForSingleObject (prci.hProcess, INFINITE); 00300 GetExitCodeProcess (prci.hProcess, &dwExitCode); 00301 nErrorLevel = (INT)dwExitCode; 00302 } 00303 CloseHandle (prci.hProcess); 00304 /* Get New code page if it has change */ 00305 InputCodePage= GetConsoleCP(); 00306 OutputCodePage = GetConsoleOutputCP(); 00307 } 00308 else 00309 { 00310 ErrorMessage(GetLastError (), 00311 _T("Error executing CreateProcess()!!\n")); 00312 } 00313 00314 00315 cmd_free(comspec); 00316 return 0; 00317 } 00318 00319 #endif 00320 00321 /* EOF */ Generated on Sun May 27 2012 04:17:03 for ReactOS by
1.7.6.1
|