Beispiel #1
0
//++ ------------------------------------------------------------------------------------
// Details: Parse the command's argument options string and try to extract the value *this
//          argument is looking for.
// Type:    Overridden.
// Args:    vwArgContext    - (R) The command's argument options string.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmdArgValFile::Validate(CMICmdArgContext &vwArgContext)
{
    if (vwArgContext.IsEmpty())
        return m_bMandatory ? MIstatus::failure : MIstatus::success;

    // The GDB/MI spec suggests there is only parameter

    if (vwArgContext.GetNumberArgsPresent() == 1)
    {
        const CMIUtilString &rFile(vwArgContext.GetArgsLeftToParse());
        if (IsFilePath(rFile))
        {
            m_bFound = true;
            m_bValid = true;
            m_argValue = rFile.Trim('"');
            vwArgContext.RemoveArg(rFile);
            return MIstatus::success;
        }
        else
            return MIstatus::failure;
    }

    // In reality there are more than one option,  if so the file option
    // is the last one (don't handle that here - find the best looking one)
    const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
    CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
    while (it != vecOptions.end())
    {
        const CMIUtilString &rTxt(*it);
        if (IsFilePath(rTxt))
        {
            m_bFound = true;

            if (vwArgContext.RemoveArg(rTxt))
            {
                m_bValid = true;
                m_argValue = rTxt.Trim('"');
                return MIstatus::success;
            }
            else
                return MIstatus::success;
        }

        // Next
        ++it;
    }

    return MIstatus::failure;
}
Beispiel #2
0
void CPathFinder::SetPath(LPCTSTR szPath, BOOL bIsFolderPath, BOOL bHasArguments)
{
	TCHAR szParamPath[_MAX_PATH];
	TCHAR szDrive[_MAX_DRIVE], szDir[_MAX_DIR];
	TCHAR szName[_MAX_FNAME], szExt[_MAX_EXT];

	// Reset
	_sOriginalPath.Empty();
	_sDriveLabel.Empty();
	_bIsRelative = FALSE;
	_aDir.RemoveAll();
	_sExtName.Empty();
	_aArgs.RemoveAll();

	// Original path
	_sOriginalPath = szPath;

	// Get args and remove them from path
	szParamPath[0] = 0x0;
	_tcscpy(szParamPath, szPath);

	if (bHasArguments)
	{
		_sArgs = PathGetArgs(szParamPath);
		PathRemoveArgs(szParamPath);
	}

	PathUnquoteSpaces(szParamPath);
	if (szParamPath[0] == 0x0) return;

    _tsplitpath(szParamPath, szDrive, szDir, szName, szExt);

	// Drive
	_sDrive = szDrive;

	// Directory
	_sDir = szDir;
	_sDir.Replace('/', '\\');
	if (!_sDir.IsEmpty()) _bIsRelative = (_sDir[0] != '\\');
	
	// FileTitle
	if (bIsFolderPath)
	{
		_sDir = CPathFinder::AddBackSlash(_sDir);
		_sDir += szName;
		_sDir = CPathFinder::AddBackSlash(_sDir);
	}
	else
	{
		_sFileTitle = szName;
	}

	// Get extension name (e.g.: "txt")
	if (IsFilePath())
	{
		_sExtName = szExt;
		_sExtName.Remove('.');
	}
}
Beispiel #3
0
bool FileSearchInDir(LPCWSTR asFilePath, CEStr& rsFound)
{
	// Possibilities
	// a) asFilePath does not contain path, only: "far"
	// b) asFilePath contains path, but without extension: "C:\\Program Files\\Far\\Far"

	LPCWSTR pszSearchFile = asFilePath;
	LPCWSTR pszSlash = wcsrchr(asFilePath, L'\\');
	if (pszSlash)
	{
		if ((pszSlash - asFilePath) >= MAX_PATH)
		{
			// No need to continue, this is invalid path to executable
			return false;
		}

		// C:\Far\Far.exe /w /pC:\Far\Plugins\ConEmu;C:\Far\Plugins.My
		if (!IsFilePath(asFilePath, false))
		{
			return false;
		}

		// Do not allow '/' here
		LPCWSTR pszFwd = wcschr(asFilePath, L'/');
		if (pszFwd != NULL)
		{
			return false;
		}
	}

	wchar_t* pszSearchPath = NULL;
	if (pszSlash)
	{
		if ((pszSearchPath = lstrdup(asFilePath)) != NULL)
		{
			pszSearchFile = pszSlash + 1;
			pszSearchPath[pszSearchFile - asFilePath] = 0;
		}
	}

	// Попытаемся найти "по путям" (%PATH%)
	wchar_t *pszFilePart;
	wchar_t szFind[MAX_PATH+1];
	LPCWSTR pszExt = PointToExt(asFilePath);

	DWORD nLen = SearchPath(pszSearchPath, pszSearchFile, pszExt ? NULL : L".exe", countof(szFind), szFind, &pszFilePart);

	SafeFree(pszSearchPath);

	if (nLen && (nLen < countof(szFind)) && FileExists(szFind))
	{
		// asFilePath will be invalid after .Set
		rsFound.Set(szFind);
		return true;
	}

	return false;
}
Beispiel #4
0
/*---------------------------------------------------------------------------------------------
Name				:	SetPath(LPCTSTR szPath, BOOL bIsFolderPath = FALSE)
Purpose				:	// Parses a path 
Parameters			:
LPCTSTR  szPath - a null terminated string containing the path. 
BOOL  bIsFolderPath - 	must be set to TRUE if we know szPath represents 
a folder path but we are not sure if it's terminated with a 
slash or back slash character ('/' or '\').  imagine you 
pass the string "c:\\temp\\subfolder" to this method. 
If bIsFolderPath is not set to TRUE, the class interprets that 
"subfolder" is a file name with no extension.
Return				:	Void.
Globals Modified	:	None.
--------------------------------------------------------------------------------------------*/
void CPath::SetPath(LPCTSTR szPath, BOOL bIsFolderPath)
{
	TCHAR	szParamPath[_MAX_PATH];
	TCHAR	szDrive[_MAX_DRIVE], szDir[_MAX_DIR];
	TCHAR	szName[_MAX_FNAME], szExt[_MAX_EXT];

	// Reset
	_strOriginalPath.Empty();
	_strDriveLabel.Empty();
	_bIsRelative = FALSE;
	_strExtName.Empty();

	// Original path
	_strOriginalPath = szPath;

	// Get args and remove them from path
	szParamPath[0] = 0x0;
	_tcscpy(szParamPath, szPath);

	if(szParamPath[0] == 0x0)
	{
		return;
	}

	_tsplitpath(szParamPath, szDrive, szDir, szName, szExt);

	// Drive
	_strDrive = szDrive;

	// Directory
	_strDir = szDir;
	_strDir.Replace(_T("/"), _T("\\"));
	if(!_strDir.IsEmpty())
	{
		_bIsRelative = (_strDir[0] != _T('\\'));
	}

	// FileTitle
	if(bIsFolderPath)
	{
		_strDir = CPath::AddBackSlash(_strDir);
		_strDir += szName;
		_strDir = CPath::AddBackSlash(_strDir);
	}
	else
	{
		_strFileTitle = szName;
	}

	// Get extension name (e.g.: "txt")
	if(IsFilePath())
	{
		_strExtName = szExt;
		_strExtName.Remove(_T('.'));
	}
}
Beispiel #5
0
/*---------------------------------------------------------------------------------------------
Name				:	ExistFile(void)
Purpose				:	Return TRUE if the file exists
Parameters			:	None.
Return				:	Return TRUE if the file exists
Globals Modified	:	None.
--------------------------------------------------------------------------------------------*/
BOOL CPath::ExistFile()
{
	if (!IsFilePath()) return FALSE;

	if((_taccess(GetPath(), 0)) == -1)
	{
		return(FALSE);
	}
	else
	{
		return(TRUE);
	}
}
Beispiel #6
0
/*-----------------------------------------------------------------------
  LINK_SelectSourceDoc
  Selects the text that was annotated in a document.
  Returns the element corresponding to the annotation anchor in the
  source document if the return_el flag is set to TRUE.
  The parameter annot_url is a utf-8 string.
  -----------------------------------------------------------------------*/
Element LINK_SelectSourceDoc (Document doc, CONST char *annot_url, 
                              ThotBool return_el)
{
  XPointerContextPtr xptr_ctx;
  AnnotMeta *annot;
  char *url;
  Element el = NULL;
  ThotBool selected = FALSE;

  if (IsW3Path (annot_url) || IsFilePath (annot_url))
    url = (char *) annot_url;
  else
    url = ANNOT_MakeFileURL (annot_url);

  annot = AnnotList_searchAnnot (AnnotMetaData[doc].annotations,
                                 url, AM_BODY_URL);
  if (url != annot_url)
    TtaFreeMemory (url);

  if (annot)
    {
      if (!annot->is_orphan)
        {
          xptr_ctx = XPointer_parse (doc, annot->xptr);
          if (!xptr_ctx->error)
            {
              XPointer_select (xptr_ctx);
              selected = TRUE;
            }
#ifdef JK_DEBUG
          else
            fprintf (stderr, 
                     "LINK_SelectSource: impossible to set XPointer\n");
#endif
          XPointer_free (xptr_ctx);
        }
    }
#ifdef JK_DEBUG
  else
    fprintf (stderr, "LINK_SelectSourceDoc: couldn't find annotation metadata\n");
#endif 

  /* search the element corresponding to the anchor in the source
     document */
  if (selected && return_el)
    el = SearchAnnotation (doc, annot->name);

  return el;
}
Beispiel #7
0
CString CPathFinder::GetRelativePath(LPCTSTR szBaseFolder)
{
	if (IsRelativePath()) return (LPCTSTR)sCEmptyString;

	TCHAR	szRelativePath[_MAX_PATH];
	CString	sRelPath;

	PathRelativePathTo(szRelativePath, szBaseFolder, FILE_ATTRIBUTE_DIRECTORY, 
					GetPath(), IsFilePath() ? 0 : FILE_ATTRIBUTE_DIRECTORY);

	sRelPath = szRelativePath;
	if (sRelPath.GetLength() > 1)
	{
		// Remove ".\" from the beginning
		if ((sRelPath[0] == '.') && (sRelPath[1] == '\\'))
			sRelPath.Right(sRelPath.GetLength() - 2);
	}

	return sRelPath;
}
Beispiel #8
0
LPCWSTR CRConFiles::GetFileFromConsole(LPCWSTR asSrc, CEStr& szFull)
{
	CEStr szWinPath;
	LPCWSTR pszWinPath = MakeWinPath(asSrc, mp_RCon ? mp_RCon->GetMntPrefix() : NULL, szWinPath);
	if (!pszWinPath || !*pszWinPath)
	{
		_ASSERTE(pszWinPath && *pszWinPath);
		return NULL;
	}

	if (IsFilePath(pszWinPath, true))
	{
		if (!FileExists(pszWinPath)) // otherwise it will cover directories too
			return NULL;
		szFull.Attach(szWinPath.Detach());
	}
	else
	{
		CEStr szDir;
		LPCWSTR pszDir = mp_RCon->GetConsoleCurDir(szDir, true);
		// We may get empty dir here if we are in "~" subdir
		if (!pszDir || !*pszDir)
		{
			_ASSERTE(pszDir && *pszDir && wcschr(pszDir,L'/')==NULL);
			return NULL;
		}

		// Попытаться просканировать один-два уровеня подпапок
		bool bFound = FileExistSubDir(pszDir, pszWinPath, 1, szFull);

		if (!bFound)
		{
			// git diffs style, but with backslashes (they are converted already)
			// "a/src/ConEmu.cpp" and "b/src/ConEmu.cpp"
			if (pszWinPath[0] && (pszWinPath[1] == L'\\') && wcschr(L"abicwo", pszWinPath[0]))
			{
				LPCWSTR pszSlash = pszWinPath;
				while (!bFound && ((pszSlash = wcschr(pszSlash, L'\\')) != NULL))
				{
					while (*pszSlash == L'\\')
						pszSlash++;
					if (!*pszSlash)
						break;
					bFound = FileExistSubDir(pszDir, pszSlash, 1, szFull);
					if (!bFound)
					{
						// Try to go to parent folder (useful while browsing git-diff-s)
						bFound = CheckParentFolders(pszDir, pszSlash, szFull);
					}
				}
			}
			else
			{
				// let's try to check some paths from #include
				// for example: #include "src/common/Common.h"
				LPCWSTR pszSlash = pszWinPath;
				while (*pszSlash == L'\\') pszSlash++;
				bFound = CheckParentFolders(pszDir, pszSlash, szFull);
			}
		}

		if (!bFound)
		{
			// If there is "src" subfolder in the current folder
			const wchar_t* predefined[] = {L"trunk", L"src", L"source", L"sources", NULL};
			for (size_t i = 0; !bFound && predefined[i]; ++i)
			{
				CEStr szSrc(JoinPath(pszDir, predefined[i]));
				if (DirectoryExists(szSrc))
					bFound = FileExistSubDir(szSrc, pszWinPath, 1, szFull);
			}
		}

		if (!bFound)
		{
			return NULL;
		}
	}

	if (!szFull.IsEmpty())
	{
		// "src\conemu\realconsole.cpp" --> "src\ConEmu\RealConsole.cpp"
		MakePathProperCase(szFull);
	}

	return szFull;
}
Beispiel #9
0
bool IsNeedCmd(BOOL bRootCmd, LPCWSTR asCmdLine, CEStr &szExe,
			   LPCWSTR* rsArguments /*= NULL*/, BOOL* rpbNeedCutStartEndQuot /*= NULL*/,
			   BOOL* rpbRootIsCmdExe /*= NULL*/, BOOL* rpbAlwaysConfirmExit /*= NULL*/, BOOL* rpbAutoDisableConfirmExit /*= NULL*/)
{
	bool rbNeedCutStartEndQuot = false;
	bool rbRootIsCmdExe = true;
	bool rbAlwaysConfirmExit = false;
	bool rbAutoDisableConfirmExit = false;

	wchar_t *pwszEndSpace;

	if (rsArguments) *rsArguments = NULL;

	bool lbRc = false;
	int iRc = 0;
	BOOL lbFirstWasGot = FALSE;
	LPCWSTR pwszCopy;
	int nLastChar;
	#ifdef _DEBUG
	CEStr szDbgFirst;
	#endif

	if (!asCmdLine || !*asCmdLine)
	{
		_ASSERTE(asCmdLine && *asCmdLine);
		goto wrap;
	}

	#ifdef _DEBUG
	// Это минимальные проверки, собственно к коду - не относятся
	bool bIsBatch = false;
	{
		LPCWSTR psz = asCmdLine;
		NextArg(&psz, szDbgFirst);
		psz = PointToExt(szDbgFirst);
		if (lstrcmpi(psz, L".cmd")==0 || lstrcmpi(psz, L".bat")==0)
			bIsBatch = true;
	}
	#endif

	if (!szExe.GetBuffer(MAX_PATH))
	{
		_ASSERTE(FALSE && "Failed to allocate MAX_PATH");
		lbRc = true;
		goto wrap;
	}
	szExe.Empty();

	if (!asCmdLine || *asCmdLine == 0)
	{
		_ASSERTE(asCmdLine && *asCmdLine);
		lbRc = true;
		goto wrap;
	}


	pwszCopy = asCmdLine;
	// cmd /c ""c:\program files\arc\7z.exe" -?"   // да еще и внутри могут быть двойными...
	// cmd /c "dir c:\"
	nLastChar = lstrlenW(pwszCopy) - 1;

	if (pwszCopy[0] == L'"' && pwszCopy[nLastChar] == L'"')
	{
		//if (pwszCopy[1] == L'"' && pwszCopy[2])
		//{
		//	pwszCopy ++; // Отбросить первую кавычку в командах типа: ""c:\program files\arc\7z.exe" -?"

		//	if (rbNeedCutStartEndQuot) *rbNeedCutStartEndQuot = TRUE;
		//}
		//else
			// глючила на ""F:\VCProject\FarPlugin\#FAR180\far.exe  -new_console""
			//if (wcschr(pwszCopy+1, L'"') == (pwszCopy+nLastChar)) {
			//	LPCWSTR pwszTemp = pwszCopy;
			//	// Получим первую команду (исполняемый файл?)
			//	if ((iRc = NextArg(&pwszTemp, szArg)) != 0) {
			//		//Parsing command line failed
			//		lbRc = true; goto wrap;
			//	}
			//	pwszCopy ++; // Отбросить первую кавычку в командах типа: "c:\arc\7z.exe -?"
			//	lbFirstWasGot = TRUE;
			//	if (rbNeedCutStartEndQuot) *rbNeedCutStartEndQuot = TRUE;
			//} else
		{
			// Will be dequoted in 'NextArg' function. Examples
			// "C:\GCC\msys\bin\make.EXE -f "makefile" COMMON="../../../plugins/common""
			// ""F:\VCProject\FarPlugin\#FAR180\far.exe  -new_console""
			// ""cmd""
			// cmd /c ""c:\program files\arc\7z.exe" -?"   // да еще и внутри могут быть двойными...
			// cmd /c "dir c:\"

			LPCWSTR pwszTemp = pwszCopy;

			// Получим первую команду (исполняемый файл?)
			if ((iRc = NextArg(&pwszTemp, szExe)) != 0)
			{
				//Parsing command line failed
				#ifdef WARN_NEED_CMD
				_ASSERTE(FALSE);
				#endif
				lbRc = true; goto wrap;
			}

			if (lstrcmpiW(szExe, L"start") == 0)
			{
				// Команду start обрабатывает только процессор
				#ifdef WARN_NEED_CMD
				_ASSERTE(FALSE);
				#endif
				lbRc = true; goto wrap;
			}

			LPCWSTR pwszQ = pwszCopy + 1 + lstrlen(szExe);
			wchar_t* pszExpand = NULL;

			if (*pwszQ != L'"' && IsExecutable(szExe, &pszExpand))
			{
				pwszCopy ++; // отбрасываем
				lbFirstWasGot = TRUE;

				if (pszExpand)
				{
					szExe.Set(pszExpand);
					SafeFree(pszExpand);
					if (rsArguments)
						*rsArguments = pwszQ;
				}

				rbNeedCutStartEndQuot = true;
			}
		}
	}

	// Получим первую команду (исполняемый файл?)
	if (!lbFirstWasGot)
	{
		szExe.Empty();

		// `start` command must be processed by processor itself
		if ((lstrcmpni(pwszCopy, L"start", 5) == 0)
			&& (!pwszCopy[5] || isSpace(pwszCopy[5])))
		{
			#ifdef WARN_NEED_CMD
			_ASSERTE(FALSE);
			#endif
			lbRc = true; goto wrap;
		}

		// 17.10.2010 - support executable file path without parameters, but with spaces in its path
		// 22.11.2015 - or some weirdness, like `C:\Program Files\CB/cb_console_runner.exe "C:\sources\app.exe"`
		LPCWSTR pchEnd = wcschr(pwszCopy, L' ');
		if (!pchEnd)
			pchEnd = pwszCopy + lstrlenW(pwszCopy);

		CEStr szTemp;
		DWORD nTempSize;
		while (pchEnd)
		{
			szTemp.Set(pwszCopy, (pchEnd - pwszCopy));
			_ASSERTE(szTemp[(pchEnd - pwszCopy)] == 0);

			// If this is a full path without environment variables
			if (((IsFilePath(szTemp, true) && !wcschr(szTemp, L'%'))
				// or file/dir may be found via env.var. substitution or searching in %PATH%
				|| FileExistsSearch((LPCWSTR)szTemp, szTemp))
				// Than check if it is a FILE (not a directory)
				&& FileExists(szTemp, &nTempSize) && nTempSize)
			{
				// OK, it an our executable?
				if (rsArguments)
					*rsArguments = pchEnd;
				szExe.Set(szTemp);
				break;
			}

			_ASSERTE(*pchEnd == 0 || *pchEnd == L' ');
			if (!*pchEnd)
				break;
			// Find next space after nonspace
			while (*(pchEnd) == L' ') pchEnd++;
			// If quoted string starts from here - it's supposed to be an argument
			if (*pchEnd == L'"')
			{
				// And we must not get here, because the executable must be already processed above
				// _ASSERTE(*pchEnd != L'"');
				break;
			}
			pchEnd = wcschr(pchEnd, L' ');
			if (!pchEnd)
				pchEnd = pwszCopy + lstrlenW(pwszCopy);
		}

		if (szExe[0] == 0)
		{
			if ((iRc = NextArg(&pwszCopy, szExe)) != 0)
			{
				//Parsing command line failed
				#ifdef WARN_NEED_CMD
				_ASSERTE(FALSE);
				#endif
				lbRc = true; goto wrap;
			}

			_ASSERTE(lstrcmpiW(szExe, L"start") != 0);

			// Обработка переменных окружения и поиск в PATH
			if (FileExistsSearch((LPCWSTR)szExe, szExe))
			{
				if (rsArguments)
					*rsArguments = pwszCopy;
			}
		}
	}

	if (!*szExe)
	{
		_ASSERTE(szExe[0] != 0);
	}
	else
	{
		// Если юзеру нужен редирект - то он должен явно указать ком.процессор
		// Иначе нереально (или достаточно сложно) определить, является ли символ
		// редиректом, или это просто один из аргументов команды...

		// "Левые" символы в имени файла (а вот в "первом аргументе" все однозначно)
		if (wcspbrk(szExe, L"?*<>|"))
		{
			rbRootIsCmdExe = TRUE; // запуск через "процессор"
			lbRc = true; goto wrap; // добавить "cmd.exe"
		}

		// если "путь" не указан
		if (wcschr(szExe, L'\\') == NULL)
		{
			bool bHasExt = (wcschr(szExe, L'.') != NULL);
			// Проверим, может это команда процессора (типа "DIR")?
			if (!bHasExt)
			{
				bool bIsCommand = false;
				wchar_t* pszUppr = lstrdup(szExe);
				if (pszUppr)
				{
					// избежать линковки на user32.dll
					//CharUpperBuff(pszUppr, lstrlen(pszUppr));
					for (wchar_t* p = pszUppr; *p; p++)
					{
						if (*p >= L'a' && *p <= 'z')
							*p -= 0x20;
					}

					const wchar_t* pszFind = gsInternalCommands;
					while (*pszFind)
					{
						if (lstrcmp(pszUppr, pszFind) == 0)
						{
							bIsCommand = true;
							break;
						}
						pszFind += lstrlen(pszFind)+1;
					}
					free(pszUppr);
				}
				if (bIsCommand)
				{
					#ifdef WARN_NEED_CMD
					_ASSERTE(FALSE);
					#endif
					rbRootIsCmdExe = TRUE; // запуск через "процессор"
					lbRc = true; goto wrap; // добавить "cmd.exe"
				}
			}

			// Try to find executable in %PATH%
			{
				#ifndef CONEMU_MINIMAL
				MWow64Disable wow; wow.Disable(); // Disable Wow64 file redirector
				#endif
				apiSearchPath(NULL, szExe, bHasExt ? NULL : L".exe", szExe);
			}
		} // end: if (wcschr(szExe, L'\\') == NULL)
	}

	// Если szExe не содержит путь к файлу - запускаем через cmd
	// "start "" C:\Utils\Files\Hiew32\hiew32.exe C:\00\Far.exe"
	if (!IsFilePath(szExe))
	{
		#ifdef WARN_NEED_CMD
		_ASSERTE(FALSE);
		#endif
		rbRootIsCmdExe = TRUE; // запуск через "процессор"
		lbRc = true; goto wrap; // добавить "cmd.exe"
	}

	//pwszCopy = wcsrchr(szArg, L'\\'); if (!pwszCopy) pwszCopy = szArg; else pwszCopy ++;
	pwszCopy = PointToName(szExe);
	//2009-08-27
	pwszEndSpace = szExe.ms_Val + lstrlenW(szExe) - 1;

	while ((*pwszEndSpace == L' ') && (pwszEndSpace > szExe))
	{
		*(pwszEndSpace--) = 0;
	}

#ifndef __GNUC__
#pragma warning( push )
#pragma warning(disable : 6400)
#endif

	if (lstrcmpiW(pwszCopy, L"cmd")==0 || lstrcmpiW(pwszCopy, L"cmd.exe")==0
		|| lstrcmpiW(pwszCopy, L"tcc")==0 || lstrcmpiW(pwszCopy, L"tcc.exe")==0)
	{
		rbRootIsCmdExe = TRUE; // уже должен быть выставлен, но проверим
		rbAlwaysConfirmExit = TRUE; rbAutoDisableConfirmExit = FALSE;
		_ASSERTE(!bIsBatch);
		lbRc = false; goto wrap; // уже указан командный процессор, cmd.exe в начало добавлять не нужно
	}


	// Issue 1211: Decide not to do weird heuristic.
	//   If user REALLY needs redirection (root command, huh?)
	//   - he must call "cmd /c ..." directly
	// Если есть одна из команд перенаправления, или слияния - нужен CMD.EXE
	if (!bRootCmd)
	{
		if (wcschr(asCmdLine, L'&') ||
			wcschr(asCmdLine, L'>') ||
			wcschr(asCmdLine, L'<') ||
			wcschr(asCmdLine, L'|') ||
			wcschr(asCmdLine, L'^') // или экранирования
			)
		{
			#ifdef WARN_NEED_CMD
			_ASSERTE(FALSE);
			#endif
			lbRc = true; goto wrap;
		}
	}

	//if (lstrcmpiW(pwszCopy, L"far")==0 || lstrcmpiW(pwszCopy, L"far.exe")==0)
	if (IsFarExe(pwszCopy))
	{
		bool bFound = (wcschr(pwszCopy, L'.') != NULL);
		// Если указали при запуске просто "far" - это может быть батник, расположенный в %PATH%
		if (!bFound)
		{
			CEStr szSearch;
			if (apiSearchPath(NULL, pwszCopy, L".exe", szSearch))
			{
				if (lstrcmpi(PointToExt(szSearch), L".exe") == 0)
					bFound = true;
			}
		}

		if (bFound)
		{
			rbAutoDisableConfirmExit = TRUE;
			rbRootIsCmdExe = FALSE; // FAR!
			_ASSERTE(!bIsBatch);
			lbRc = false; goto wrap; // уже указан исполняемый файл, cmd.exe в начало добавлять не нужно
		}
	}

	if (IsExecutable(szExe))
	{
		rbRootIsCmdExe = FALSE; // Для других программ - буфер не включаем
		_ASSERTE(!bIsBatch);
		lbRc = false; goto wrap; // Запускается конкретная консольная программа. cmd.exe не требуется
	}

	//Можно еще Доделать поиски с: SearchPath, GetFullPathName, добавив расширения .exe & .com
	//хотя фар сам формирует полные пути к командам, так что можно не заморачиваться
	#ifdef WARN_NEED_CMD
	_ASSERTE(FALSE);
	#endif
	rbRootIsCmdExe = TRUE;
#ifndef __GNUC__
#pragma warning( pop )
#endif

	lbRc = true;
wrap:
	if (rpbNeedCutStartEndQuot)
		*rpbNeedCutStartEndQuot = rbNeedCutStartEndQuot;
	if (rpbRootIsCmdExe)
		*rpbRootIsCmdExe = rbRootIsCmdExe;
	if (rpbAlwaysConfirmExit)
		*rpbAlwaysConfirmExit = rbAlwaysConfirmExit;
	if (rpbAutoDisableConfirmExit)
		*rpbAutoDisableConfirmExit = rbAutoDisableConfirmExit;
	return lbRc;
}
Beispiel #10
0
// Function checks, if we need drop first and last quotation marks
// Example: ""7z.exe" /?"
// Using cmd.exe rules
bool IsNeedDequote(LPCWSTR asCmdLine, bool abFromCmdCK, LPCWSTR* rsEndQuote/*=NULL*/)
{
	if (rsEndQuote)
		*rsEndQuote = NULL;

	if (!asCmdLine)
		return false;

	bool bDeQu = false;
	LPCWSTR pszQE, pszSP;
	if (asCmdLine[0] == L'"')
	{
		bDeQu = (asCmdLine[1] == L'"');
		// Всегда - нельзя. Иначе парсинг строки запуска некорректно идет
		// L"\"C:\\ConEmu\\ConEmuC64.exe\"  /PARENTFARPID=1 /C \"C:\\GIT\\cmdw\\ad.cmd CE12.sln & ci -m \"Solution debug build properties\"\""
		if (!bDeQu)
		{
			size_t nLen = lstrlen(asCmdLine);
			if (abFromCmdCK)
			{
				bDeQu = ((asCmdLine[nLen-1] == L'"') && (asCmdLine[nLen-2] == L'"'));
			}
			if (!bDeQu && (asCmdLine[nLen-1] == L'"'))
			{
				pszSP = wcschr(asCmdLine+1, L' ');
				pszQE = wcschr(asCmdLine+1, L'"');
				if (pszSP && pszQE && (pszSP < pszQE)
					&& ((pszSP - asCmdLine) < MAX_PATH))
				{
					CEStr lsTmp;
					lsTmp.Set(asCmdLine+1, pszSP-asCmdLine-1);
					bDeQu = (IsFilePath(lsTmp, true) && IsExecutable(lsTmp));
				}
			}
		}
	}
	if (!bDeQu)
		return false;

	// Don't dequote?
	pszQE = wcsrchr(asCmdLine+2, L'"');
	if (!pszQE)
		return false;

#if 0
	LPCWSTR pszQ1 = wcschr(asCmdLine+2, L'"');
	if (!pszQ1)
		return false;
	LPCWSTR pszQE = wcsrchr(pszQ1, L'"');
	// Only TWO quotes in asCmdLine?
	if (pszQE == pszQ1)
	{
		// Doesn't contains special symbols?
		if (!wcspbrk(asCmdLine+1, L"&<>()@^|"))
		{
			// Must contains spaces (doubt?)
			if (wcschr(asCmdLine+1, L' '))
			{
				// Cmd also checks this for executable file name. Skip this check?
				return false;
			}
		}
	}
#endif

	// Well, we get here
	_ASSERTE(asCmdLine[0]==L'"' && pszQE && *pszQE==L'"' && !wcschr(pszQE+1,L'"'));
	// Dequote it!
	if (rsEndQuote)
		*rsEndQuote = pszQE;
	return true;
}
Beispiel #11
0
/*-----------------------------------------------------------------------
  LINK_CreateMeta
  -----------------------------------------------------------------------*/
AnnotMeta *LINK_CreateMeta (Document source_doc, Document annot_doc, AnnotMode mode)

{
  AnnotMeta   *annot;
  char      *annot_user;
  char      *source_doc_url; /* the url we will use to refer to the source doc */

  /*
  **  Make a new annotation entry, add it to annotlist, and initialize it.
  */

#ifdef ANNOT_ON_ANNOT
  if (DocumentTypes[source_doc] == docAnnot && AnnotMetaData[source_doc].annot_url)
    {
      /* we reply to an annotation (using it's metadata). However, we annotate the
         body of an annotation, not its metadata */
      if (mode & ANNOT_isReplyTo)
        source_doc_url = AnnotMetaData[source_doc].annot_url;
      else
        source_doc_url = DocumentURLs[source_doc];
    }
  else
#endif /* ANNOT_ON_ANNOT */
    source_doc_url = DocumentURLs[source_doc];


  /* download the local annotations, if they do exist, but mark them
     invisible */
  if (!IsW3Path (DocumentURLs[source_doc]) && 
      (!AnnotMetaData[source_doc].annotations 
       && !AnnotMetaData[source_doc].local_annot_loaded))
    {
      char *annotIndex = NULL;

      annotIndex = LINK_GetAnnotationIndexFile (source_doc_url);
      LINK_LoadAnnotationIndex (source_doc, annotIndex, FALSE);
      AnnotMetaData[source_doc].local_annot_loaded = TRUE;
    }

  annot =  AnnotMeta_new ();
  if (source_doc_url &&
      (IsW3Path (source_doc_url) || IsFilePath(source_doc_url)))
    annot->source_url = TtaStrdup (source_doc_url);
  else
    annot->source_url = ANNOT_MakeFileURL (source_doc_url);
  
  /* get the current date... cdate = mdate at this stage */
  annot->cdate = StrdupDate ();
  annot->mdate = TtaStrdup (annot->cdate);

  /* Annotation type -- will be reassigned below for Reply */
  annot->type = DEFAULT_ANNOTATION_TYPE;

  /* Annotation XPointer */
  /* annot->xptr = XPointer_build (source_doc, 1, useDocRoot);*/

  annot_user = GetAnnotUser ();
  annot->author = TtaStrdup (annot_user);
  annot->content_type = TtaStrdup (AM_XHTML_MIME_TYPE);
  if (!IsW3Path (DocumentURLs[annot_doc]) 
      && !IsFilePath (DocumentURLs[annot_doc]))
    {
      annot->body_url = ANNOT_MakeFileURL (DocumentURLs[annot_doc]);
    }
  else
    annot->body_url = TtaStrdup (DocumentURLs[annot_doc]);

  /* the annotation is visible to the user */
  annot->is_visible = TRUE;
  /* display the annotation */
  annot->show = TRUE;
  /* it's not an orphan */
  annot->is_orphan = FALSE;
  
  /* create the reverse link name */
  LINK_CreateAName (annot);

#ifdef ANNOT_ON_ANNOT
  /* initialize the annot_url we will use to reference this annotation*/
  AnnotMetaData[annot_doc].annot_url = TtaStrdup (annot->body_url);

  if (mode & ANNOT_isReplyTo)
    {
      char *source_annot_url;

      annot->type = DEFAULT_REPLY_TYPE;

      source_annot_url = AnnotMetaData[source_doc].annot_url;
      /* initialize the thread info */
      if (!AnnotMetaData[source_doc].thread)
        {
          AnnotMetaData[source_doc].thread = &AnnotThread[source_doc];
          AnnotThread[source_doc].rootOfThread = TtaStrdup (source_annot_url);
        }
      AnnotMetaData[annot_doc].thread = AnnotMetaData[source_doc].thread;
      annot->thread = AnnotMetaData[source_doc].thread;
      AnnotMetaData[source_doc].thread->references++;
      annot->inReplyTo = TtaStrdup (source_annot_url);
      /* maybe useless */
      annot->rootOfThread = TtaStrdup (AnnotMetaData[source_doc].thread->rootOfThread);
      /* and add the annotation to the list of threads */
      List_add (&(AnnotMetaData[source_doc].thread->annotations), (void *) annot);
    }
  else
#endif /* ANNOT_ON_ANNOT */
    {
      /* add the annotation to the list of annotations */
      List_add (&(AnnotMetaData[source_doc].annotations), (void *) annot);
    }

  return annot;
}
Beispiel #12
0
/*-----------------------------------------------------------------------
  LINK_DeleteLink
  For a given source doc, deletes the index entry from the main index and
  removes the documents index file.
  -----------------------------------------------------------------------*/
void LINK_DeleteLink (Document source_doc, ThotBool isReplyTo)
{
  char   *doc_index;
  char buffer[255];
  char *annot_dir;
  char *main_index;
  char *main_index_file_old;
  char *main_index_file_new;
  char *source_doc_url;
  int len;
  int error;
  FILE *fp_old = NULL;
  FILE *fp_new;
  

  /* get the annotation index */
  doc_index = LINK_GetAnnotationIndexFile (DocumentURLs[source_doc]);
  if (!doc_index)
    doc_index = LINK_GetAnnotationIndexFile (AnnotMetaData[source_doc].annot_url);
  if (!doc_index)
    return;

  error = 0;
  annot_dir = GetAnnotDir ();
  main_index = GetAnnotMainIndex ();
  main_index_file_old = (char *)TtaGetMemory (strlen (annot_dir) 
                                              + strlen (main_index)
                                              + 10);

  main_index_file_new = (char *)TtaGetMemory (strlen (annot_dir) 
                                              + strlen (main_index)
                                              + 14);
  sprintf (main_index_file_old, 
           "%s%c%s", 
           annot_dir, 
           DIR_SEP, 
           main_index);

  sprintf (main_index_file_new, 
           "%s%c%s.tmp", 
           annot_dir, 
           DIR_SEP, 
           main_index);

  if (!(fp_new = TtaWriteOpen (main_index_file_new)))
    error++;

  if (!error)
    {
      if (!(fp_old = TtaReadOpen (main_index_file_old)))
        {
          TtaReadClose (fp_new);
          error++;
        }
    }

  if (!error)
    {
      if (IsW3Path (DocumentURLs[source_doc])
          || IsFilePath (DocumentURLs[source_doc]))
        source_doc_url = DocumentURLs[source_doc];
      else
        source_doc_url = ANNOT_MakeFileURL (DocumentURLs[source_doc]);
		    
		    
      /* search and remove the index entry */
      len = strlen (DocumentURLs[source_doc]);
      while (fgets (buffer, sizeof (buffer), fp_old))
        {
          if (strncmp (source_doc_url, buffer, len))
            fputs (buffer, fp_new);
        }
      TtaWriteClose (fp_new);
      TtaReadClose (fp_old);
      
      if (source_doc_url != DocumentURLs[source_doc])
        TtaFreeMemory (source_doc_url);

      /* rename the main index file */
      TtaFileUnlink (main_index_file_old);
      TtaFileRename (main_index_file_new, main_index_file_old);
      /* remove the index file */
      TtaFileUnlink (doc_index);
    }

  TtaFreeMemory (main_index_file_old);
  TtaFreeMemory (main_index_file_new);
  TtaFreeMemory (doc_index);
}
Beispiel #13
0
/*-----------------------------------------------------------------------
  LINK_UpdateAnnotationIndexFile
  old_source_url and new_source_url must be complete URLs.
  -----------------------------------------------------------------------*/
void LINK_UpdateAnnotationIndexFile (char *old_source_url, char *new_source_url)
{
  char *annot_dir;
  char *annot_main_index;
  char *annot_main_index_file;
  char *annot_new_main_index_file;
  char url[MAX_LENGTH];
  char index_file[MAX_LENGTH];
  char buffer[MAX_LENGTH];
  char *tmp_url;
  char *tmp_index_file;
  FILE *fp_old, *fp_new;
  ThotBool move;

  annot_dir = GetAnnotDir ();
  annot_main_index = GetAnnotMainIndex ();
  annot_main_index_file = (char *)TtaGetMemory (strlen (annot_dir) 
                                                + strlen (annot_main_index) 
                                                + 10);
  sprintf (annot_main_index_file, "%s%c%s", 
           annot_dir, 
           DIR_SEP,  
           annot_main_index);
  annot_new_main_index_file = (char *)TtaGetMemory (strlen (annot_dir) 
                                                    + strlen (annot_main_index) 
                                                    + 11);
  sprintf (annot_new_main_index_file, "%s%ct%s", 
           annot_dir, 
           DIR_SEP,  
           annot_main_index);

  move = FALSE;
  if (TtaFileExist (annot_main_index_file))
    {
      if ((fp_old = TtaReadOpen (annot_main_index_file)))
        {
          if ((fp_new = TtaWriteOpen (annot_new_main_index_file)))
            {
              while (fgets (buffer, MAX_LENGTH, fp_old))
                {
                  sscanf (buffer, "%s %s\n", url, index_file);
                  /* convert local URLs into file: ones */
                  if (!IsFilePath (url) && !IsW3Path (url))
                    tmp_url = LocalToWWW (url);
                  else
                    tmp_url = url;
                  if (!IsFilePath (index_file) && !IsW3Path (index_file))
                    tmp_index_file = LocalToWWW (index_file);
                  else
                    tmp_index_file = index_file;
                  if (!strcasecmp (old_source_url, tmp_url))
                    fprintf (fp_new, "%s %s\n", new_source_url, tmp_index_file);
                  else
                    fprintf (fp_new, "%s %s\n", tmp_url, tmp_index_file);
                  if (tmp_url != url)
                    TtaFreeMemory (tmp_url);
                  if (tmp_index_file != index_file)
                    TtaFreeMemory (tmp_index_file);
                }
              TtaWriteClose (fp_new);
              move = TRUE;
            }
          TtaReadClose (fp_old);
        }
    }
  
  if (move)
    {
      TtaFileCopy (annot_new_main_index_file, annot_main_index_file);
      TtaFileUnlink (annot_new_main_index_file);
    }

  TtaFreeMemory (annot_main_index_file);
  TtaFreeMemory (annot_new_main_index_file);
}
Beispiel #14
0
void CSetPgDebug::debugLogShell(DWORD nParentPID, CESERVER_REQ_ONCREATEPROCESS* pInfo)
{
	CSetPgDebug* pDbgPg = (CSetPgDebug*)gpSetCls->GetPageObj(thi_Debug);
	if (!pDbgPg)
		return;
	if ((pDbgPg->GetActivityLoggingType() != glt_Processes)
		&& (pDbgPg->GetActivityLoggingType() != glt_Shell))
		return;

	LPCWSTR pszFile = pInfo->wsValue + pInfo->nActionLen;
	LPCWSTR pszParam = pInfo->wsValue + pInfo->nActionLen+pInfo->nFileLen;
	DebugLogShellActivity *shl = (DebugLogShellActivity*)calloc(sizeof(DebugLogShellActivity),1);
	shl->nParentPID = nParentPID;
	shl->nParentBits = pInfo->nSourceBits;
	wcscpy_c(shl->szFunction, pInfo->sFunction);
	shl->pszAction = lstrdup(pInfo->wsValue);
	shl->pszFile   = lstrdup(pszFile);
	shl->pszParam  = lstrdup(pszParam);
	shl->bDos = (pInfo->nImageBits == 16) && (pInfo->nImageSubsystem == IMAGE_SUBSYSTEM_DOS_EXECUTABLE);
	shl->nImageBits = pInfo->nImageBits;
	shl->nImageSubsystem = pInfo->nImageSubsystem;
	shl->nShellFlags = pInfo->nShellFlags;
	shl->nCreateFlags = pInfo->nCreateFlags;
	shl->nStartFlags = pInfo->nStartFlags;
	shl->nShowCmd = pInfo->nShowCmd;
	shl->hStdIn = (DWORD)pInfo->hStdIn;
	shl->hStdOut = (DWORD)pInfo->hStdOut;
	shl->hStdErr = (DWORD)pInfo->hStdErr;

	// Append directory and bat/tmp files contents to pszParam
	{
		LPCWSTR pszDir = (pInfo->wsValue+pInfo->nActionLen+pInfo->nFileLen+pInfo->nParamLen);
		LPCWSTR pszAppFile = NULL;
		wchar_t*& pszParamEx = shl->pszParam;

		if (pszDir && *pszDir)
		{
			CEStr lsDir((pszParamEx && *pszParamEx) ? L"\r\n\r\n" : NULL, L"CD: \"", pszDir, L"\"");
			lstrmerge(&pszParamEx, lsDir);
		}

		if (shl->pszFile)
		{
			LPCWSTR pszExt = PointToExt(shl->pszFile);
			if (pszExt && (!lstrcmpi(pszExt, L".bat") || !lstrcmpi(pszExt, L".cmd")))
				debugLogShellText(pszParamEx, (pszAppFile = shl->pszFile));
		}

		if (pszParam && *pszParam)
		{
			LPCWSTR pszNext = pszParam;
			CEStr szArg;
			while (0 == NextArg(&pszNext, szArg))
			{
				if (!*szArg || (*szArg == L'-') || (*szArg == L'/'))
					continue;
				LPCWSTR pszExt = PointToExt(szArg);

				// Perhaps process *.tmp files too? (used with VC RC compilation?)
				if (pszExt && (!lstrcmpi(pszExt, L".bat") || !lstrcmpi(pszExt, L".cmd") /*|| !lstrcmpi(pszExt, L".tmp")*/)
					&& (!pszAppFile || (lstrcmpi(szArg, pszAppFile) != 0)))
				{
					debugLogShellText(pszParamEx, szArg);
				}
				else if (szArg[0] == L'@')
				{
					CEStr lsPath;

					if (IsFilePath(szArg.Mid(1), true))
					{
						// Full path to "arguments file"
						lsPath.Set(szArg.Mid(1));
					}
					else if ((szArg[1] != L'\\' && szArg[1] != L'/')
						&& (pszDir && *pszDir))
					{
						// Relative path to "arguments file"
						lsPath = JoinPath(pszDir, szArg.Mid(1));
					}

					if (!lsPath.IsEmpty())
					{
						debugLogShellText(pszParamEx, lsPath);
					}
				}
			}
		}
	}
	// end of "Append directory and bat/tmp files contents to pszParam"

	PostMessage(pDbgPg->Dlg(), DBGMSG_LOG_ID, DBGMSG_LOG_SHELL_MAGIC, (LPARAM)shl);
}
LPCWSTR CRConFiles::GetFileFromConsole(LPCWSTR asSrc, CmdArg& szFull)
{
	CmdArg szWinPath;
	LPCWSTR pszWinPath = szWinPath.Attach(MakeWinPath(asSrc));
	if (!pszWinPath || !*pszWinPath)
	{
		_ASSERTE(pszWinPath && *pszWinPath);
		return NULL;
	}

	if (IsFilePath(pszWinPath, true))
	{
		if (!FileExists(pszWinPath)) // otherwise it will cover directories too
			return NULL;
		szFull.Attach(szWinPath.Detach());
	}
	else
	{
		CEStr szDir;
		LPCWSTR pszDir = mp_RCon->GetConsoleCurDir(szDir);
		_ASSERTE(pszDir && wcschr(pszDir,L'/')==NULL);

		// Попытаться просканировать один-два уровеня подпапок
		bool bFound = FileExistSubDir(pszDir, pszWinPath, 1, szFull);

		if (!bFound)
		{
			// git diffs style, but with backslashes (they are converted already)
			// "a/src/ConEmu.cpp" and "b/src/ConEmu.cpp"
			if (pszWinPath[0] && (pszWinPath[1] == L'\\') && wcschr(L"abicwo", pszWinPath[0]))
			{
				LPCWSTR pszSlash = pszWinPath;
				while (!bFound && ((pszSlash = wcschr(pszSlash, L'\\')) != NULL))
				{
					while (*pszSlash == L'\\')
						pszSlash++;
					if (!*pszSlash)
						break;
					bFound = FileExistSubDir(pszDir, pszSlash, 1, szFull);
				}
			}
		}

		if (!bFound)
		{
			// If there is "src" subfolder in the current folder
			CEStr szSrc = JoinPath(pszDir, L"src");
			if (DirectoryExists(szSrc))
			{
				bFound = FileExistSubDir(szSrc, pszWinPath, 1, szFull);
			}
		}

		if (!bFound)
		{
			return NULL;
		}
	}

	if (!szFull.IsEmpty())
	{
		// "src\conemu\realconsole.cpp" --> "src\ConEmu\RealConsole.cpp"
		MakePathProperCase(szFull);
	}

	return szFull;
}
Beispiel #16
0
BOOL CPathFinder::ExistFile()
{
	if (!IsFilePath()) return FALSE;

	return PathFileExists(GetPath());
}
Beispiel #17
0
bool IsNeedCmd(BOOL bRootCmd, LPCWSTR asCmdLine, CmdArg &szExe,
			   LPCWSTR* rsArguments /*= NULL*/, BOOL* rpbNeedCutStartEndQuot /*= NULL*/,
			   BOOL* rpbRootIsCmdExe /*= NULL*/, BOOL* rpbAlwaysConfirmExit /*= NULL*/, BOOL* rpbAutoDisableConfirmExit /*= NULL*/)
{
	_ASSERTE(asCmdLine && *asCmdLine);

	bool rbNeedCutStartEndQuot = false;
	bool rbRootIsCmdExe = true;
	bool rbAlwaysConfirmExit = false;
	bool rbAutoDisableConfirmExit = false;
	if (rsArguments) *rsArguments = NULL;

	bool lbRc = false;
	int iRc = 0;
	BOOL lbFirstWasGot = FALSE;
	LPCWSTR pwszCopy;
	int nLastChar;

	#ifdef _DEBUG
	// Это минимальные проверки, собственно к коду - не относятся
	CmdArg szDbgFirst;
	bool bIsBatch = false;
	{
		LPCWSTR psz = asCmdLine;
		NextArg(&psz, szDbgFirst);
		psz = PointToExt(szDbgFirst);
		if (lstrcmpi(psz, L".cmd")==0 || lstrcmpi(psz, L".bat")==0)
			bIsBatch = true;
	}
	#endif

	if (!szExe.GetBuffer(MAX_PATH))
	{
		_ASSERTE(FALSE && "Failed to allocate MAX_PATH");
		lbRc = true;
		goto wrap;
	}
	szExe.Empty();

	if (!asCmdLine || *asCmdLine == 0)
	{
		_ASSERTE(asCmdLine && *asCmdLine);
		lbRc = true;
		goto wrap;
	}


	pwszCopy = asCmdLine;
	// cmd /c ""c:\program files\arc\7z.exe" -?"   // да еще и внутри могут быть двойными...
	// cmd /c "dir c:\"
	nLastChar = lstrlenW(pwszCopy) - 1;

	if (pwszCopy[0] == L'"' && pwszCopy[nLastChar] == L'"')
	{
		//if (pwszCopy[1] == L'"' && pwszCopy[2])
		//{
		//	pwszCopy ++; // Отбросить первую кавычку в командах типа: ""c:\program files\arc\7z.exe" -?"

		//	if (rbNeedCutStartEndQuot) *rbNeedCutStartEndQuot = TRUE;
		//}
		//else
			// глючила на ""F:\VCProject\FarPlugin\#FAR180\far.exe  -new_console""
			//if (wcschr(pwszCopy+1, L'"') == (pwszCopy+nLastChar)) {
			//	LPCWSTR pwszTemp = pwszCopy;
			//	// Получим первую команду (исполняемый файл?)
			//	if ((iRc = NextArg(&pwszTemp, szArg)) != 0) {
			//		//Parsing command line failed
			//		lbRc = true; goto wrap;
			//	}
			//	pwszCopy ++; // Отбросить первую кавычку в командах типа: "c:\arc\7z.exe -?"
			//	lbFirstWasGot = TRUE;
			//	if (rbNeedCutStartEndQuot) *rbNeedCutStartEndQuot = TRUE;
			//} else
		{
			// Will be dequoted in 'NextArg' function. Examples
			// "C:\GCC\msys\bin\make.EXE -f "makefile" COMMON="../../../plugins/common""
			// ""F:\VCProject\FarPlugin\#FAR180\far.exe  -new_console""
			// ""cmd""
			// cmd /c ""c:\program files\arc\7z.exe" -?"   // да еще и внутри могут быть двойными...
			// cmd /c "dir c:\"

			LPCWSTR pwszTemp = pwszCopy;

			// Получим первую команду (исполняемый файл?)
			if ((iRc = NextArg(&pwszTemp, szExe)) != 0)
			{
				//Parsing command line failed
				#ifdef WARN_NEED_CMD
				_ASSERTE(FALSE);
				#endif
				lbRc = true; goto wrap;
			}

			if (lstrcmpiW(szExe, L"start") == 0)
			{
				// Команду start обрабатывает только процессор
				#ifdef WARN_NEED_CMD
				_ASSERTE(FALSE);
				#endif
				lbRc = true; goto wrap;
			}

			LPCWSTR pwszQ = pwszCopy + 1 + lstrlen(szExe);
			wchar_t* pszExpand = NULL;

			if (*pwszQ != L'"' && IsExecutable(szExe, &pszExpand))
			{
				pwszCopy ++; // отбрасываем
				lbFirstWasGot = TRUE;

				if (pszExpand)
				{
					szExe.Set(pszExpand);
					SafeFree(pszExpand);
					if (rsArguments)
						*rsArguments = pwszQ;
				}

				rbNeedCutStartEndQuot = true;
			}
		}
	}

	// Получим первую команду (исполняемый файл?)
	if (!lbFirstWasGot)
	{
		szExe.Empty();
		// 17.10.2010 - поддержка переданного исполняемого файла без параметров, но с пробелами в пути
		LPCWSTR pchEnd = pwszCopy + lstrlenW(pwszCopy);

		while (pchEnd > pwszCopy && *(pchEnd-1) == L' ') pchEnd--;

		if ((pchEnd - pwszCopy) < MAX_PATH)
		{

			szExe.Set(pwszCopy, (pchEnd - pwszCopy));
			_ASSERTE(szExe[(pchEnd - pwszCopy)] == 0);

			if (lstrcmpiW(szExe, L"start") == 0)
			{
				// Команду start обрабатывает только процессор
				#ifdef WARN_NEED_CMD
				_ASSERTE(FALSE);
				#endif
				lbRc = true; goto wrap;
			}

			// Обработка переменных окружения и поиск в PATH
			if (FileExistsSearch((LPCWSTR)szExe, szExe))
			{
				if (rsArguments)
					*rsArguments = pchEnd;
			}
			else
			{
				szExe.Empty();
			}
		}

		if (szExe[0] == 0)
		{
			if ((iRc = NextArg(&pwszCopy, szExe)) != 0)
			{
				//Parsing command line failed
				#ifdef WARN_NEED_CMD
				_ASSERTE(FALSE);
				#endif
				lbRc = true; goto wrap;
			}

			if (lstrcmpiW(szExe, L"start") == 0)
			{
				// Команду start обрабатывает только процессор
				#ifdef WARN_NEED_CMD
				_ASSERTE(FALSE);
				#endif
				lbRc = true; goto wrap;
			}

			// Обработка переменных окружения и поиск в PATH
			if (FileExistsSearch((LPCWSTR)szExe, szExe))
			{
				if (rsArguments)
					*rsArguments = pwszCopy;
			}
		}
	}

	if (!*szExe)
	{
		_ASSERTE(szExe[0] != 0);
	}
	else
	{
		// Если юзеру нужен редирект - то он должен явно указать ком.процессор
		// Иначе нереально (или достаточно сложно) определить, является ли символ
		// редиректом, или это просто один из аргументов команды...

		// "Левые" символы в имени файла (а вот в "первом аргументе" все однозначно)
		if (wcspbrk(szExe, L"?*<>|"))
		{
			rbRootIsCmdExe = TRUE; // запуск через "процессор"
			lbRc = true; goto wrap; // добавить "cmd.exe"
		}

		// если "путь" не указан
		if (wcschr(szExe, L'\\') == NULL)
		{
			bool bHasExt = (wcschr(szExe, L'.') != NULL);
			// Проверим, может это команда процессора (типа "DIR")?
			if (!bHasExt)
			{
				bool bIsCommand = false;
				wchar_t* pszUppr = lstrdup(szExe);
				if (pszUppr)
				{
					// избежать линковки на user32.dll
					//CharUpperBuff(pszUppr, lstrlen(pszUppr));
					for (wchar_t* p = pszUppr; *p; p++)
					{
						if (*p >= L'a' && *p <= 'z')
							*p -= 0x20;
					}

					const wchar_t* pszFind = gsInternalCommands;
					while (*pszFind)
					{
						if (lstrcmp(pszUppr, pszFind) == 0)
						{
							bIsCommand = true;
							break;
						}
						pszFind += lstrlen(pszFind)+1;
					}
					free(pszUppr);
				}
				if (bIsCommand)
				{
					#ifdef WARN_NEED_CMD
					_ASSERTE(FALSE);
					#endif
					rbRootIsCmdExe = TRUE; // запуск через "процессор"
					lbRc = true; goto wrap; // добавить "cmd.exe"
				}
			}

			// Пробуем найти "по путям" соответствующий exe-шник.
			DWORD nCchMax = szExe.mn_MaxLen; // выделить память, длинее чем szExe вернуть не сможем
			wchar_t* pszSearch = (wchar_t*)malloc(nCchMax*sizeof(wchar_t));
			if (pszSearch)
			{
				#ifndef CONEMU_MINIMAL
				MWow64Disable wow; wow.Disable(); // Отключить редиректор!
				#endif
				wchar_t *pszName = NULL;
				DWORD nRc = SearchPath(NULL, szExe, bHasExt ? NULL : L".exe", nCchMax, pszSearch, &pszName);
				if (nRc && (nRc < nCchMax))
				{
					// Нашли, возвращаем что нашли
					szExe.Set(pszSearch);
				}
				free(pszSearch);
			}
		} // end: if (wcschr(szExe, L'\\') == NULL)
	}

	// Если szExe не содержит путь к файлу - запускаем через cmd
	// "start "" C:\Utils\Files\Hiew32\hiew32.exe C:\00\Far.exe"
	if (!IsFilePath(szExe))
	{
		#ifdef WARN_NEED_CMD
		_ASSERTE(FALSE);
		#endif
		rbRootIsCmdExe = TRUE; // запуск через "процессор"
		lbRc = true; goto wrap; // добавить "cmd.exe"
	}

	//pwszCopy = wcsrchr(szArg, L'\\'); if (!pwszCopy) pwszCopy = szArg; else pwszCopy ++;
	pwszCopy = PointToName(szExe);
	//2009-08-27
	wchar_t *pwszEndSpace = szExe.ms_Arg + lstrlenW(szExe) - 1;

	while ((*pwszEndSpace == L' ') && (pwszEndSpace > szExe))
	{
		*(pwszEndSpace--) = 0;
	}

#ifndef __GNUC__
#pragma warning( push )
#pragma warning(disable : 6400)
#endif

	if (lstrcmpiW(pwszCopy, L"cmd")==0 || lstrcmpiW(pwszCopy, L"cmd.exe")==0
		|| lstrcmpiW(pwszCopy, L"tcc")==0 || lstrcmpiW(pwszCopy, L"tcc.exe")==0)
	{
		rbRootIsCmdExe = TRUE; // уже должен быть выставлен, но проверим
		rbAlwaysConfirmExit = TRUE; rbAutoDisableConfirmExit = FALSE;
		_ASSERTE(!bIsBatch);
		lbRc = false; goto wrap; // уже указан командный процессор, cmd.exe в начало добавлять не нужно
	}


	// Issue 1211: Decide not to do weird heuristic.
	//   If user REALLY needs redirection (root command, huh?)
	//   - he must call "cmd /c ..." directly
	// Если есть одна из команд перенаправления, или слияния - нужен CMD.EXE
	if (!bRootCmd)
	{
		if (wcschr(asCmdLine, L'&') ||
			wcschr(asCmdLine, L'>') ||
			wcschr(asCmdLine, L'<') ||
			wcschr(asCmdLine, L'|') ||
			wcschr(asCmdLine, L'^') // или экранирования
			)
		{
			#ifdef WARN_NEED_CMD
			_ASSERTE(FALSE);
			#endif
			lbRc = true; goto wrap;
		}
	}

	//if (lstrcmpiW(pwszCopy, L"far")==0 || lstrcmpiW(pwszCopy, L"far.exe")==0)
	if (IsFarExe(pwszCopy))
	{
		bool bFound = (wcschr(pwszCopy, L'.') != NULL);
		// Если указали при запуске просто "far" - это может быть батник, расположенный в %PATH%
		if (!bFound)
		{
			wchar_t szSearch[MAX_PATH+1], *pszPart = NULL;
			DWORD n = SearchPath(NULL, pwszCopy, L".exe", countof(szSearch), szSearch, &pszPart);
			if (n && (n < countof(szSearch)))
			{
				if (lstrcmpi(PointToExt(pszPart), L".exe") == 0)
					bFound = true;
			}
		}

		if (bFound)
		{
			rbAutoDisableConfirmExit = TRUE;
			rbRootIsCmdExe = FALSE; // FAR!
			_ASSERTE(!bIsBatch);
			lbRc = false; goto wrap; // уже указан исполняемый файл, cmd.exe в начало добавлять не нужно
		}
	}

	if (IsExecutable(szExe))
	{
		rbRootIsCmdExe = FALSE; // Для других программ - буфер не включаем
		_ASSERTE(!bIsBatch);
		lbRc = false; goto wrap; // Запускается конкретная консольная программа. cmd.exe не требуется
	}

	//Можно еще Доделать поиски с: SearchPath, GetFullPathName, добавив расширения .exe & .com
	//хотя фар сам формирует полные пути к командам, так что можно не заморачиваться
	#ifdef WARN_NEED_CMD
	_ASSERTE(FALSE);
	#endif
	rbRootIsCmdExe = TRUE;
#ifndef __GNUC__
#pragma warning( pop )
#endif

	lbRc = true;
wrap:
	if (rpbNeedCutStartEndQuot)
		*rpbNeedCutStartEndQuot = rbNeedCutStartEndQuot;
	if (rpbRootIsCmdExe)
		*rpbRootIsCmdExe = rbRootIsCmdExe;
	if (rpbAlwaysConfirmExit)
		*rpbAlwaysConfirmExit = rbAlwaysConfirmExit;
	if (rpbAutoDisableConfirmExit)
		*rpbAutoDisableConfirmExit = rbAutoDisableConfirmExit;
	return lbRc;
}