ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

start.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.