/* * START.C - start internal command. * * * History: * * 24-Jul-1999 (Eric Kohl) * Started. * * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>) * Remove all hardcode string to En.rc */ #include <precomp.h> #ifdef INCLUDE_CMD_START INT cmd_start (LPTSTR First, LPTSTR Rest) { TCHAR szFullName[CMDLINE_LENGTH]; TCHAR first[CMDLINE_LENGTH]; TCHAR *rest = NULL; TCHAR *param = NULL; TCHAR RestWithoutArgs[CMDLINE_LENGTH]; INT size; LPTSTR comspec; BOOL bWait = FALSE; BOOL bBat = FALSE; BOOL bCreate = FALSE; TCHAR szFullCmdLine [CMDLINE_LENGTH]; PROCESS_INFORMATION prci; STARTUPINFO stui; LPTSTR *arg; INT argc = 0; INT i = 0; DWORD Priority = 0; RestWithoutArgs[0] = _T('\0'); _tcscpy(first,First); arg = split (Rest, &argc, FALSE); for (i = 0; i < argc; i++) { if (!_tcsncmp (arg[i], _T("/?"), 2)) { freep(arg); ConOutResPaging(TRUE,STRING_START_HELP1); return 0; } else if(!_tcsicmp(arg[i], _T("/LOW"))) { Priority = IDLE_PRIORITY_CLASS; } else if(!_tcsicmp(arg[i], _T("/NORMAL"))) { Priority = NORMAL_PRIORITY_CLASS; } else if(!_tcsicmp(arg[i], _T("/HIGH"))) { Priority = HIGH_PRIORITY_CLASS; } else if(!_tcsicmp(arg[i], _T("/REALTIME"))) { Priority = REALTIME_PRIORITY_CLASS; } else if(!_tcsicmp(arg[i], _T("/ABOVENORMAL"))) { Priority = ABOVE_NORMAL_PRIORITY_CLASS; } else if(!_tcsicmp(arg[i], _T("/BELOWNORMAL"))) { Priority = BELOW_NORMAL_PRIORITY_CLASS; } else { if(RestWithoutArgs[0] != _T('\0')) { _tcscat(RestWithoutArgs,_T(" ")); } _tcscat(RestWithoutArgs,arg[i]); } } freep (arg); /* get comspec */ comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR)); if (comspec == NULL) { error_out_of_memory(); return 1; } SetLastError(0); size = GetEnvironmentVariable (_T("COMSPEC"), comspec, MAX_PATH); if(GetLastError() == ERROR_ENVVAR_NOT_FOUND) { RestWithoutArgs[0] = _T('c'); RestWithoutArgs[1] = _T('m'); RestWithoutArgs[2] = _T('d'); RestWithoutArgs[3] = _T('\0'); } else { if (size > MAX_PATH) { comspec = cmd_realloc(comspec,size * sizeof(TCHAR) ); if (comspec==NULL) { return 1; } size = GetEnvironmentVariable (_T("COMSPEC"), comspec, size); } } nErrorLevel = 0; if(!_tcslen(RestWithoutArgs)) { _tcscpy(RestWithoutArgs,_T("\"")); _tcscat(RestWithoutArgs,comspec); _tcscat(RestWithoutArgs,_T("\"")); } rest = cmd_alloc ( (_tcslen(RestWithoutArgs) + 1) * sizeof(TCHAR)); if (rest == NULL) { if(comspec != NULL) cmd_free(comspec); error_out_of_memory(); return 1; } param = cmd_alloc ( (_tcslen(RestWithoutArgs) + 1) * sizeof(TCHAR)); if (param == NULL) { if(comspec != NULL) cmd_free(comspec); cmd_free(rest); error_out_of_memory(); return 1; } param[0] = _T('\0'); _tcscpy(rest,RestWithoutArgs); /* Parsing the command that gets called by start, and it's parameters */ if(!_tcschr(rest,_T('\"'))) { INT count = _tcslen(rest); /* find the end of the command and start of the args */ for(i = 0; i < count; i++) { if(rest[i] == _T(' ')) { _tcscpy(param,&rest[i+1]); rest[i] = _T('\0'); break; } } } else { INT count = _tcslen(rest); BOOL bInside = FALSE; /* find the end of the command and put the arguments in param */ for(i = 0; i < count; i++) { if(rest[i] == _T('\"')) bInside = !bInside; if((rest[i] == _T(' ')) && !bInside) { _tcscpy(param,&rest[i+1]); rest[i] = _T('\0'); break; } } i = 0; /* remove any slashes */ while(i < count) { if(rest[i] == _T('\"')) memmove(&rest[i],&rest[i + 1], _tcslen(&rest[i]) * sizeof(TCHAR)); else i++; } } /* check for a drive change */ if (!_tcscmp (first + 1, _T(":")) && _istalpha (*first)) { TCHAR szPath[CMDLINE_LENGTH]; _tcscpy (szPath, _T("A:")); szPath[0] = _totupper (*first); SetCurrentDirectory (szPath); GetCurrentDirectory (CMDLINE_LENGTH, szPath); if (szPath[0] != (TCHAR)_totupper (*first)) ConErrResPuts (STRING_FREE_ERROR1); if (rest != NULL) cmd_free(rest); if (param != NULL) cmd_free(param); if (comspec != NULL) cmd_free(comspec); return 0; } /* get the PATH environment variable and parse it */ /* search the PATH environment variable for the binary */ if (!SearchForExecutable (rest, szFullName)) { error_bad_command (); if (rest != NULL) cmd_free(rest); if (param != NULL) cmd_free(param); if (comspec != NULL) cmd_free(comspec); return 1; } /* check if this is a .BAT or .CMD file */ if (!_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".bat")) || !_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".cmd"))) { bBat = TRUE; memset(szFullCmdLine,0,CMDLINE_LENGTH * sizeof(TCHAR)); _tcscpy(szFullCmdLine,comspec); memcpy(&szFullCmdLine[_tcslen(szFullCmdLine)],_T("\" /K \""), 6 * sizeof(TCHAR)); memcpy(&szFullCmdLine[_tcslen(szFullCmdLine)], szFullName, _tcslen(szFullName) * sizeof(TCHAR)); memcpy(&szFullCmdLine[1], &szFullCmdLine[0], _tcslen(szFullCmdLine) * sizeof(TCHAR)); szFullCmdLine[0] = _T('\"'); szFullCmdLine[_tcslen(szFullCmdLine)] = _T('\"'); } TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest)); TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest)); /* build command line for CreateProcess() */ if (bBat == FALSE) { _tcscpy (szFullCmdLine, first); if( param != NULL ) { _tcscat(szFullCmdLine, _T(" ") ); _tcscat (szFullCmdLine, param); } } /* fill startup info */ memset (&stui, 0, sizeof (STARTUPINFO)); stui.cb = sizeof (STARTUPINFO); stui.dwFlags = STARTF_USESHOWWINDOW; stui.wShowWindow = SW_SHOWDEFAULT; if (bBat == TRUE) { bCreate = CreateProcess (NULL, szFullCmdLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | Priority, NULL, NULL, &stui, &prci); } else { bCreate = CreateProcess (szFullName, szFullCmdLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | Priority, NULL, NULL, &stui, &prci); } if (bCreate) { if (bWait) { DWORD dwExitCode; WaitForSingleObject (prci.hProcess, INFINITE); GetExitCodeProcess (prci.hProcess, &dwExitCode); nErrorLevel = (INT)dwExitCode; } CloseHandle (prci.hThread); CloseHandle (prci.hProcess); /* Get New code page if it has change */ InputCodePage= GetConsoleCP(); OutputCodePage = GetConsoleOutputCP(); } else { ErrorMessage(GetLastError (), _T("Error executing CreateProcess()!!\n")); } if (rest != NULL) cmd_free(rest); if (param != NULL) cmd_free(param); if (comspec != NULL) cmd_free(comspec); return 0; } #endif /* EOF */