//++ ------------------------------------------------------------------------------------ // 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; }
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('.'); } }
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; }
/*--------------------------------------------------------------------------------------------- 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('.')); } }
/*--------------------------------------------------------------------------------------------- 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); } }
/*----------------------------------------------------------------------- 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; }
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; }
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; }
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; }
// 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; }
/*----------------------------------------------------------------------- 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; }
/*----------------------------------------------------------------------- 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); }
/*----------------------------------------------------------------------- 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); }
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; }
BOOL CPathFinder::ExistFile() { if (!IsFilePath()) return FALSE; return PathFileExists(GetPath()); }
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; }