Exemple #1
0
	// Create the command to show on the Integration settings page
	LPCWSTR CreateCommand(CEStr& rsReady)
	{
		rsReady = L"";

		for (INT_PTR i = 0; i < ourSwitches.size(); i++)
		{
			Switch* ps = ourSwitches[i];
			_ASSERTE(ps && !ps->szSwitch.IsEmpty());
			bool bOpt = !ps->szOpt.IsEmpty();
			bool bQuot = (bOpt && IsQuotationNeeded(ps->szOpt));
			lstrmerge(&rsReady.ms_Val,
				ps->szSwitch,
				bOpt ? L" " : NULL,
				bQuot ? L"\"" : NULL,
				bOpt ? ps->szOpt.c_str() : NULL,
				bQuot ? L"\" " : L" ");
		}

		if (!rsReady.IsEmpty() || bCmdList)
		{
			lstrmerge(&rsReady.ms_Val,
				bCmdList ? L"-runlist " : L"-run ", szCmd);
		}
		else
		{
			rsReady.Set(szCmd);
		}

		return rsReady.c_str(L"");
	};
Exemple #2
0
int apiGetFullPathName(LPCWSTR lpFileName, CEStr& rsPath)
{
	bool bFound = false;
	wchar_t *pszFilePart, *pszBuffer = NULL;
	wchar_t szFind[MAX_PATH+1];

	DWORD nLen = GetFullPathName(lpFileName, countof(szFind), szFind, &pszFilePart);
	if (nLen)
	{
		if (nLen < countof(szFind))
		{
			bFound = true;
			rsPath.Set(szFind);
		}
		else
		{
			// Too long path, allocate more space
			pszBuffer = (wchar_t*)malloc((++nLen)*sizeof(*pszBuffer));
			if (pszBuffer)
			{
				DWORD nLen2 = GetFullPathName(lpFileName, nLen, pszBuffer, &pszFilePart);
				if (nLen2 && (nLen2 < nLen))
				{
					bFound = true;
					rsPath.Set(pszBuffer);
				}
				free(pszBuffer);
			}
		}
	}

	return bFound ? rsPath.GetLen() : 0;
}
Exemple #3
0
DWORD GetModulePathName(HMODULE hModule, CEStr& lsPathName)
{
	size_t cchMax = MAX_PATH;
	wchar_t* pszData = lsPathName.GetBuffer(cchMax);
	if (!pszData)
		return 0; // Memory allocation error

	DWORD nRc = GetModuleFileName(hModule, pszData, cchMax);
	if (!nRc)
		return 0;

	// Not enough space?
	if (nRc == cchMax)
	{
		cchMax = 32767;
		wchar_t* pszData = lsPathName.GetBuffer(cchMax);
		if (!pszData)
			return 0; // Memory allocation error
		nRc = GetModuleFileName(hModule, pszData, cchMax);
		if (!nRc || (nRc == cchMax))
			return 0;
	}

	return nRc;
}
Exemple #4
0
// Concatenate strings from array and set resource item
bool CLngRc::SetResource(MArray<LngRcItem>& arr, int idx, MJsonValue* pJson)
{
	CEStr lsValue;
	MJsonValue jStr;

	// [ "Decrease window height ", "(check ‘Resize with arrows’)" ]
	size_t iCount = pJson->getLength();

	for (size_t i = 0; i < iCount; i++)
	{
		if (!pJson->getItem(i, jStr) || (jStr.getType() != MJsonValue::json_String))
		{
			_ASSERTE(FALSE && "String format failure");
			return false;
		}
		lstrmerge(&lsValue.ms_Val, jStr.getString());
	}

	if (lsValue.IsEmpty())
	{
		_ASSERTE(FALSE && "Empty resource string (array)");
		return false;
	}

	return SetResource(arr, idx, lsValue.ms_Val, true);
}
Exemple #5
0
void DebugNeedCmdUnitTests()
{
	BOOL b;
	struct strTests { LPCWSTR pszCmd; BOOL bNeed; }
	Tests[] = {
		{L"\"C:\\windows\\notepad.exe -f \"makefile\" COMMON=\"../../../plugins/common\"\"", FALSE},
		{L"\"\"C:\\windows\\notepad.exe  -new_console\"\"", FALSE},
		{L"\"\"cmd\"\"", FALSE},
		{L"cmd /c \"\"C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe\" -?\"", FALSE},
		{L"cmd /c \"dir c:\\\"", FALSE},
		{L"abc.cmd", TRUE},
		// Do not do too many heuristic. If user really needs redirection (for 'root'!)
		// he must explicitly call "cmd /c ...". With only exception if first exe not found.
		{L"notepad text & start explorer", FALSE},
	};
	LPCWSTR psArgs;
	BOOL bNeedCut, bRootIsCmd, bAlwaysConfirm, bAutoDisable;
	CEStr szExe;
	for (INT_PTR i = 0; i < countof(Tests); i++)
	{
		szExe.Empty();
		RConStartArgs rcs; rcs.pszSpecialCmd = lstrdup(Tests[i].pszCmd);
		rcs.ProcessNewConArg();
		b = IsNeedCmd(TRUE, rcs.pszSpecialCmd, szExe, &psArgs, &bNeedCut, &bRootIsCmd, &bAlwaysConfirm, &bAutoDisable);
		_ASSERTE(b == Tests[i].bNeed);
	}
}
Exemple #6
0
void DefTermLogString(LPCSTR asMessage, LPCWSTR asLabel /*= NULL*/)
{
	if (!gpDefTerm || !asMessage || !*asMessage)
		return;
	INT_PTR iLen = lstrlenA(asMessage);
	CEStr lsMsg;
	MultiByteToWideChar(CP_ACP, 0, asMessage, iLen, lsMsg.GetBuffer(iLen), iLen);
	DefTermLogString(lsMsg.ms_Arg, asLabel);
}
Exemple #7
0
	Switch* GetNextSwitch(LPCWSTR& rpsz, CEStr& szArg)
	{
		LPCWSTR psz = rpsz;
		CEStr szNext;

		if ((0 == NextArg(&psz, szNext)) && !szNext.IsPossibleSwitch())
			rpsz = psz;
		else
			szNext.Clear();

		Switch* ps = new Switch(szArg.Detach(), szNext.Detach());
		return ps;
	};
Exemple #8
0
int RegGetStringValue(HKEY hk, LPCWSTR pszSubKey, LPCWSTR pszValueName, CEStr& rszData, DWORD Wow64Flags /*= 0*/)
{
	int iLen = -1;
	HKEY hkChild = hk;
	DWORD cbSize = 0;
	LONG lrc;

	rszData.Empty();

	if (pszSubKey && *pszSubKey)
	{
		if (hk == NULL)
		{
			lrc = RegGetStringValue(HKEY_CURRENT_USER, pszSubKey, pszValueName, rszData, 0);
			if (lrc < 0)
			{
				bool isWin64 = IsWindows64();
				lrc = RegGetStringValue(HKEY_LOCAL_MACHINE, pszSubKey, pszValueName, rszData, isWin64 ? KEY_WOW64_64KEY : 0);
				if ((lrc < 0) && isWin64)
				{
					lrc = RegGetStringValue(HKEY_LOCAL_MACHINE, pszSubKey, pszValueName, rszData, KEY_WOW64_32KEY);
				}
			}
			if (lrc > 0)
			{
				return lrc;
			}
		}

		if (0 != (lrc = RegOpenKeyEx(hk, pszSubKey, 0, KEY_READ|Wow64Flags, &hkChild)))
			hkChild = NULL;
	}

	if (hkChild && (0 == (lrc = RegQueryValueEx(hkChild, pszValueName, NULL, NULL, NULL, &cbSize))))
	{
		wchar_t* pszData = rszData.GetBuffer((cbSize>>1)+2); // +wchar_t+1byte (на возможные ошибки хранения данных в реестре)
		if (pszData)
		{
			pszData[cbSize>>1] = 0; // Make sure it will be 0-terminated
			if (0 == (lrc = RegQueryValueEx(hkChild, pszValueName, NULL, NULL, (LPBYTE)pszData, &cbSize)))
			{
				iLen = lstrlen(pszData);
			}
			else
			{
				rszData.Empty();
			}
		}
	}
Exemple #9
0
CLogFunction::CLogFunction(const char* asFnName)
{
	const int nLen = MultiByteToWideChar(CP_ACP, 0, asFnName, -1, NULL, 0);

	const int cchBuf = 80;
	wchar_t sBuf[cchBuf] = L"";
	CEStr szTemp;
	wchar_t *pszBuf = (nLen >= cchBuf)
		? szTemp.GetBuffer(nLen + 1)
		: sBuf;

	MultiByteToWideChar(CP_ACP, 0, asFnName, -1, pszBuf, nLen+1);

	DoLogFunction(pszBuf);
}
Exemple #10
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;
}
Exemple #11
0
// The function converts UTF-8 to UCS2 (CEStr) and returns pointer to allocated buffer (CEStr)
LPCWSTR SettingsXML::utf2wcs(const char* utf8, CEStr& wc)
{
	if (!utf8)
	{
		_ASSERTE(utf8 != NULL);
		wc.Clear();
		return NULL;
	}

	wc.Empty();
	int wcLen = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
	if (wcLen > 0)
	{
		wcLen = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wc.GetBuffer(wcLen), wcLen);
		if (wcLen <= 0)
			wc.Empty();
	}
	return wc.c_str();
}
Exemple #12
0
	Switch* GetNextPair(LPCWSTR& rpsz)
	{
		LPCWSTR psz = rpsz;
		CEStr szArg;

		if (0 != NextArg(&psz, szArg))
		{
			return NULL;
		}

		// Invalid switch? or first argument (our executable)
		if (!szArg.IsPossibleSwitch())
		{
			rpsz = psz;
			return NULL;
		}

		rpsz = psz;

		return GetNextSwitch(rpsz, szArg);
	};
Exemple #13
0
		void SetFKey(CEStr& lsSubst, UINT fn)
		{
			if (!Mods)
			{
				msprintf(szSubst, countof(szSubst), L"\033[%u~", fn);
			}
			else
			{
				msprintf(szSubst, countof(szSubst), L"\033[%u;%c~", fn, Mods+L'1');
			}
			lsSubst.Set(szSubst);
		}
Exemple #14
0
		void SetTilde(CEStr& lsSubst, wchar_t c)
		{
			if (!Mods)
			{
				msprintf(szSubst, countof(szSubst), L"\033[%c~", c);
			}
			else
			{
				msprintf(szSubst, countof(szSubst), L"\033[%c;%c~", c, Mods+L'1');
			}
			lsSubst.Set(szSubst);
		}
Exemple #15
0
		void SetKey(CEStr& lsSubst, wchar_t c, wchar_t prefix=L'O')
		{
			if (!Mods)
			{
				//wcscpy_c(szSubst, L"\033O*A");
				msprintf(szSubst, countof(szSubst), L"\033%c%c", prefix, c);
			}
			else
			{
				msprintf(szSubst, countof(szSubst), L"\033[1;%c%c", Mods+L'1', c);
			}
			lsSubst.Set(szSubst);
		}
Exemple #16
0
int GetDirectory(CEStr& szDir)
{
	int iRc = 0;
	DWORD nLen, nMax;

	nMax = GetCurrentDirectory(MAX_PATH, szDir.GetBuffer(MAX_PATH));
	if (!nMax)
	{
		goto wrap;
	}
	else if (nMax > MAX_PATH)
	{
		nLen = GetCurrentDirectory(nMax, szDir.GetBuffer(nMax));
		if (!nLen || (nLen > nMax))
		{
			goto wrap;
		}
	}

	iRc = lstrlen(szDir);
wrap:
	return iRc;
}
Exemple #17
0
// Used for URL wrapped on several lines
bool CMatch::GetNextLine(CRConDataGuard& data, int nLine)
{
	// Perhaps not only for "URL"?

	if (!data.isValid())
		return false;

	ConsoleLinePtr line;
	if (!data->GetConsoleLine(nLine, line) || line.nLen <= 0 || !line.pChar)
		return false;

	// ConsoleLinePtr doesn't contain Z-terminated strings, only RAW characters
	CEStr add;
	wchar_t* ptr = add.GetBuffer(line.nLen);
	if (!ptr)
		return false;
	wmemmove(ptr, line.pChar, line.nLen);
	ptr[line.nLen] = 0;
	// Append new data
	if (!lstrmerge(&m_SrcLine.ms_Val, ptr))
		return false;
	mn_SrcLength += line.nLen;
	return true;
}
Exemple #18
0
// Returns 0 if succeeded, otherwise the error code
int NextLine(const wchar_t** asLines, CEStr &rsLine, NEXTLINEFLAGS Flags /*= NLF_TRIM_SPACES|NLF_SKIP_EMPTY_LINES*/)
{
	if (!asLines || !*asLines)
		return CERR_CMDLINEEMPTY;

	const wchar_t* psz = *asLines;
	//const wchar_t szSpaces[] = L" \t";
	//const wchar_t szLines[] = L"\r\n";
	//const wchar_t szSpacesLines[] = L" \t\r\n";

	if ((Flags & (NLF_TRIM_SPACES|NLF_SKIP_EMPTY_LINES)) == (NLF_TRIM_SPACES|NLF_SKIP_EMPTY_LINES))
		psz = SkipNonPrintable(psz);
	else if (Flags & NLF_TRIM_SPACES)
		while (*psz == L' ' || *psz == L'\t') psz++;
	else if (Flags & NLF_SKIP_EMPTY_LINES)
		while (*psz == L'\r' || *psz == L'\n') psz++;

	if (!*psz)
	{
		*asLines = psz;
		return CERR_CMDLINEEMPTY;
	}

	const wchar_t* pszEnd = wcspbrk(psz, L"\r\n");
	if (!pszEnd)
	{
		pszEnd = psz + lstrlen(psz);
	}

	const wchar_t* pszTrim = pszEnd;
	if (*pszEnd == L'\r') pszEnd++;
	if (*pszEnd == L'\n') pszEnd++;

	if (Flags & NLF_TRIM_SPACES)
	{
		while ((pszTrim > psz) && ((*(pszTrim-1) == L' ') || (*(pszTrim-1) == L'\t')))
			pszTrim--;
	}

	_ASSERTE(pszTrim >= psz);
	rsLine.Set(psz, pszTrim-psz);
	psz = pszEnd;

	*asLines = psz;
	return 0;
}
Exemple #19
0
bool CLngRc::GetResource(MArray<LngRcItem>& arr, int idx, CEStr& lsText)
{
	bool bFound = false;

	if ((idx >= 0) && (idx < arr.size()))
	{
		const LngRcItem& item = arr[idx];

		if (item.Processed && (item.Str && *item.Str))
		{
			lsText.Set(item.Str);
			bFound = true;
		}
	}

	return bFound;
}
Exemple #20
0
	bool GetLine(CEStr& szLine)
	{
		if (!ptrData || !cchUsed)
			return false;
		const char* ptrLineEnd = strpbrk(ptrData, "\r\n");
		if (!ptrLineEnd)
			return false; // There is no one completed line yet

		// Multi-line block?
		if ((ptrLineEnd[0] == L'\n') && (ptrLineEnd[1] == L' ' || ptrLineEnd[1] == L'\t'))
		{
			const char* ptrTestEnd = strpbrk(ptrLineEnd+1, "\r\n");
			if (ptrTestEnd)
				ptrLineEnd = ptrTestEnd;
		}

		// \r\n is not expected, but if it happens...
		const char* ptrNewLine = (ptrLineEnd[0] == '\r' && ptrLineEnd[1] == '\n') ? (ptrLineEnd+2) : (ptrLineEnd+1);
		// Alloc the buffer
		size_t cchLen = (ptrLineEnd - ptrData);
		wchar_t* ptrDst = szLine.GetBuffer(cchLen);
		if (!ptrDst)
		{
			return false; // memory allocation failed
		}

		// Return the string
		MultiByteToWideChar(CP_OEMCP, 0, ptrData, cchLen, ptrDst, cchLen);
		ptrDst[cchLen] = 0;
		// Shift the tail
		_ASSERTE((INT_PTR)cchUsed >= (ptrNewLine - ptrData));
		cchUsed -= (ptrNewLine - ptrData);
		_ASSERTE(cchUsed < cchMax);
		memmove(ptrData, ptrNewLine, cchUsed);
		ptrData[cchUsed] = 0;
		// Succeeded
		return true;
	};
Exemple #21
0
LPCWSTR GetDirectory(CEStr& szDir)
{
	DWORD nLen, nMax;

	nMax = GetCurrentDirectory(MAX_PATH, szDir.GetBuffer(MAX_PATH));
	if (!nMax)
	{
		szDir.Empty();
		goto wrap;
	}
	else if (nMax > MAX_PATH)
	{
		nLen = GetCurrentDirectory(nMax, szDir.GetBuffer(nMax));
		if (!nLen || (nLen > nMax))
		{
			szDir.Empty();
			goto wrap;
		}
	}

wrap:
	return szDir.IsEmpty() ? NULL : szDir.c_str();
}
Exemple #22
0
bool FileExistsSearch(LPCWSTR asFilePath, CEStr& rsFound, bool abSetPath/*= true*/, bool abRegSearch /*= true*/)
{
	if (!asFilePath || !*asFilePath)
	{
		_ASSERTEX(asFilePath && *asFilePath);
		return false;
	}

	if (FileExists(asFilePath))
	{
		return true;
	}

	// Развернуть переменные окружения
	if (wcschr(asFilePath, L'%'))
	{
		bool bFound = false;
		wchar_t* pszExpand = ExpandEnvStr(asFilePath);
		if (pszExpand && FileExists(pszExpand))
		{
			// asFilePath will be invalid after .Set
			rsFound.Set(pszExpand);
			bFound = true;
		}
		SafeFree(pszExpand);

		if (bFound)
		{
			return true;
		}
	}

	// Search "Path"
	if (FileSearchInDir(asFilePath, rsFound))
	{
		return true;
	}

	// Только если приложение не нашли "по путям" - пытаемся определить его расположение через [App Paths]
	// В противном случае, в частности, может быть запущен "far" не из папки с ConEmu, а зарегистрированный
	// в реестре, если на машине их несколько установлено.

	#if !defined(CONEMU_MINIMAL)
	_ASSERTE(gfnSearchAppPaths!=NULL);
	#endif

	// В ConEmuHk этот блок не активен, потому что может быть "только" перехват CreateProcess,
	// а о его параметрах должно заботиться вызывающее (текущее) приложение
	if (abRegSearch && gfnSearchAppPaths && !wcschr(asFilePath, L'\\'))
	{
		// Если в asFilePath НЕ указан путь - искать приложение в реестре,
		// и там могут быть указаны доп. параметры (пока только добавка в %PATH%)
		if (gfnSearchAppPaths(asFilePath, rsFound, abSetPath, NULL))
		{
			// Нашли по реестру, возможно обновили %PATH%
			return true;
		}
	}

	return false;
}
Exemple #23
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);
}
Exemple #24
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;
}
Exemple #25
0
// Вызывается для инициализации из Settings::LoadSettings()
HWND CConEmuInside::InsideFindParent()
{
	bool bFirstStep = true;
	DWORD nParentPID = 0;
	PROCESSENTRY32 pi = {sizeof(pi)};
	EnumFindParentArg find = {};

	if (!m_InsideIntegration)
	{
		return NULL;
	}

	if (mh_InsideParentWND)
	{
		if (IsWindow(mh_InsideParentWND))
		{
			if (m_InsideIntegration == ii_Simple)
			{
				// We cover all client area of mh_InsideParentWND in this mode
				_ASSERTE(mh_InsideParentRel==NULL);
				mh_InsideParentRel = NULL;
			}

			_ASSERTE(mh_InsideParentWND!=NULL);
			goto wrap;
		}
		else
		{
			if (m_InsideIntegration == ii_Simple)
			{
				DisplayLastError(L"Specified window not found");
				SetInsideParentWND(NULL);
				goto wrap;
			}
			_ASSERTE(IsWindow(mh_InsideParentWND));
			SetInsideParentWND(mh_InsideParentRel = NULL);
		}
	}

	_ASSERTE(m_InsideIntegration!=ii_Simple);

	if (mn_InsideParentPID)
	{
		if ((mn_InsideParentPID == GetCurrentProcessId())
			|| !GetProcessInfo(mn_InsideParentPID, &pi))
		{
			DisplayLastError(L"Invalid parent process specified");
			m_InsideIntegration = ii_None;
			SetInsideParentWND(NULL);
			goto wrap;
		}

		nParentPID = mn_InsideParentPID;
	}
	else
	{
		PROCESSENTRY32 pi = {sizeof(pi)};
		if (!GetProcessInfo(GetCurrentProcessId(), &pi) || !pi.th32ParentProcessID)
		{
			DisplayLastError(L"GetProcessInfo(GetCurrentProcessId()) failed");
			m_InsideIntegration = ii_None;
			SetInsideParentWND(NULL);
			goto wrap;
		}

		nParentPID = pi.th32ParentProcessID;
	}

	// Do window enumeration
	find.nPID = nParentPID;
	::EnumWindows(EnumInsideFindParent, (LPARAM)&find);


	if (!find.hParentRoot)
	{
		int nBtn = MsgBox(L"Can't find appropriate parent window!\n\nContinue in normal mode?", MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON2);
		if (nBtn != IDYES)
		{
			SetInsideParentWND(INSIDE_PARENT_NOT_FOUND);
			return mh_InsideParentWND; // Закрыться!
		}
		// Продолжить в обычном режиме
		m_InsideIntegration = ii_None;
		SetInsideParentWND(NULL);
		goto wrap;
	}

	mh_InitialRoot = find.hParentRoot;
	mn_InsideParentPID = nParentPID;

	HWND hExistConEmu;
	if ((hExistConEmu = InsideFindConEmu(find.hParentRoot)) != NULL)
	{
		_ASSERTE(FALSE && "Continue to create tab in existing instance");
		// Если в проводнике уже есть ConEmu - открыть в нем новую вкладку
		gpSetCls->SingleInstanceShowHide = sih_None;
		LPCWSTR pszCmdLine = GetCommandLine();
		CEStr lsArg;
		LPCWSTR pszCmd = pszCmdLine;
		while (0 == NextArg(&pszCmd, lsArg))
		{
			if (lsArg.OneOfSwitches(L"-runlist",L"-cmdlist"))
			{
				pszCmd = NULL; break;
			}
			else if (lsArg.OneOfSwitches(L"-run",L"-cmd"))
			{
				break;
			}
		}
		gpConEmu->RunSingleInstance(hExistConEmu, (pszCmd && *pszCmd) ? (pszCmd) : NULL);

		SetInsideParentWND(INSIDE_PARENT_NOT_FOUND);
		return mh_InsideParentWND; // Закрыться!
	}

	// Теперь нужно найти дочерние окна
	// 1. в которое будем внедряться
	// 2. по которому будем позиционироваться
	// 3. для синхронизации текущего пути
	InsideFindShellView(find.hParentRoot);

RepeatCheck:
	if (!isInsideWndSet() || (!mh_InsideParentRel && (m_InsideIntegration == ii_Explorer)))
	{
		wchar_t szAddMsg[128] = L"", szMsg[1024];
		if (bFirstStep)
		{
			bFirstStep = false;

			if (TurnExplorerTipPane(szAddMsg))
			{
				goto RepeatCheck;
			}
		}

		_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"%sCan't find appropriate shell window!\nUnrecognized layout of the Explorer.\n\nContinue in normal mode?", szAddMsg);
		int nBtn = MsgBox(szMsg, MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON2);

		if (nBtn != IDYES)
		{
			SetInsideParentWND(INSIDE_PARENT_NOT_FOUND);
			return mh_InsideParentWND; // Закрыться!
		}
		m_InsideIntegration = ii_None;
		SetInsideParentWND(NULL);
		goto wrap;
	}

wrap:
	if (!isInsideWndSet())
	{
		m_InsideIntegration = ii_None;
	}
	else
	{
		GetWindowThreadProcessId(mh_InsideParentWND, &mn_InsideParentPID);
		// Для мониторинга папки
		GetCurrentDirectory(countof(ms_InsideParentPath), ms_InsideParentPath);
		int nLen = lstrlen(ms_InsideParentPath);
		if ((nLen > 3) && (ms_InsideParentPath[nLen-1] == L'\\'))
		{
			ms_InsideParentPath[nLen-1] = 0;
		}
	}

	return mh_InsideParentWND;
}
Exemple #26
0
// Returns true on changes
// bDeQuote:  replace two "" with one "
// bDeEscape: process special symbols: ^e^[^r^n^t^b
bool DemangleArg(CEStr& rsDemangle, bool bDeQuote /*= true*/, bool bDeEscape /*= false*/)
{
	if (rsDemangle.IsEmpty() || !(bDeQuote || bDeEscape))
	{
		return false; // Nothing to do
	}

	LPCWSTR pszDemangles = (bDeQuote && bDeEscape) ? L"^\"" : bDeQuote ? L"\"" : L"^";
	LPCWSTR pchCap = wcspbrk(rsDemangle, pszDemangles);
	if (pchCap == NULL)
	{
		return false; // Nothing to replace
	}

	wchar_t* pszDst = rsDemangle.ms_Val;
	const wchar_t* pszSrc = rsDemangle.ms_Val;
	const wchar_t* pszEnd = rsDemangle.ms_Val + rsDemangle.GetLen();

	while (pszSrc < pszEnd)
	{
		if (bDeQuote && (*pszSrc == L'"'))
		{
			*(pszDst++) = *(pszSrc++);
			if (*pszSrc == L'"') // Expected, but may be missed by user?
				pszSrc++;
		}
		else if (bDeEscape && (*pszSrc == L'^'))
		{
			switch (*(++pszSrc))
			{
			case L'^': // Demangle cap
				*pszDst = L'^'; break;
			case 0:    // Leave single final cap
				*pszDst = L'^'; continue;
			case L'r': case L'R': // CR
				*pszDst = L'\r'; break;
			case L'n': case L'N': // LF
				*pszDst = L'\n'; break;
			case L't': case L'T': // TAB
				*pszDst = L'\t'; break;
			case L'a': case L'A': // BELL
				*pszDst = 7; break;
			case L'b': case L'B': // BACK
				*pszDst = L'\b'; break;
			case L'e': case L'E': case L'[': // ESC
				*pszDst = 27; break;
			default:
				// Unknown ctrl-sequence, bypass
				*(pszDst++) = *(pszSrc++);
				continue;
			}
			pszDst++; pszSrc++;
		}
		else
		{
			*(pszDst++) = *(pszSrc++);
		}
	}
	// Was processed? Zero terminate it.
	*pszDst = 0;

	return true;
}
Exemple #27
0
// Returns 0 if succeeded, otherwise the error code
int NextArg(const wchar_t** asCmdLine, CEStr &rsArg, const wchar_t** rsArgStart/*=NULL*/)
{
	if (!asCmdLine || !*asCmdLine)
		return CERR_CMDLINEEMPTY;

	#ifdef _DEBUG
	if ((rsArg.mn_TokenNo==0) // first token
		|| ((rsArg.mn_TokenNo>0) && (rsArg.ms_LastTokenEnd==*asCmdLine)
			&& (wcsncmp(*asCmdLine,rsArg.ms_LastTokenSave,countof(rsArg.ms_LastTokenSave)-1))==0))
	{
		// OK, параметры корректны
	}
	else
	{
		_ASSERTE(FALSE && "rsArgs was not resetted before new cycle!");
	}
	#endif

	LPCWSTR psCmdLine = SkipNonPrintable(*asCmdLine), pch = NULL;
	if (!*psCmdLine)
		return CERR_CMDLINEEMPTY;

	// Remote surrounding quotes, in certain cases
	// Example: ""7z.exe" /?"
	// Example: "C:\Windows\system32\cmd.exe" /C ""C:\Python27\python.EXE""
	if ((rsArg.mn_TokenNo == 0) || (rsArg.mn_CmdCall == CEStr::cc_CmdCK))
	{
		if (IsNeedDequote(psCmdLine, (rsArg.mn_CmdCall == CEStr::cc_CmdCK), &rsArg.mpsz_Dequoted))
			psCmdLine++;
		if (rsArg.mn_CmdCall == CEStr::cc_CmdCK)
			rsArg.mn_CmdCall = CEStr::cc_CmdCommand;
	}

	size_t nArgLen = 0;
	bool lbQMode = false;

	// аргумент начинается с "
	if (*psCmdLine == L'"')
	{
		lbQMode = true;
		psCmdLine++;
		// ... /d "\"C:\ConEmu\ConEmuPortable.exe\" /Dir ...
		bool bQuoteEscaped = (psCmdLine[0] == L'\\' && psCmdLine[1] == L'"');
		pch = wcschr(psCmdLine, L'"');
		if (pch && (pch > psCmdLine))
		{
			// To be correctly parsed something like this:
			// reg.exe add "HKCU\MyCo" /ve /t REG_EXPAND_SZ /d "\"C:\ConEmu\ConEmuPortable.exe\" /Dir \"%V\" /cmd \"cmd.exe\" \"-new_console:nC:cmd.exe\" \"-cur_console:d:%V\"" /f
			// But must not fails with ‘simple’ command like (no escapes in "C:\"):
			// /dir "C:\" /icon "cmd.exe" /single

			// Prev version fails while getting strings for -GuiMacro, example:
			// ConEmu.exe -detached -GuiMacro "print(\" echo abc \"); Context;"

			pch = wcspbrk(psCmdLine, L"\\\"");
			while (pch)
			{
				// Escaped quotation?
				if ((*pch == L'\\') && (*(pch+1) == L'"'))
				{
					// It's allowed when:
					// a) at the beginning of the line (handled above, bQuoteEscaped);
					// b) after space, left bracket or colon (-GuiMacro)
					// c) when already was forced by bQuoteEscaped
					if ((
						((((pch - 1) >= psCmdLine) && wcschr(L" (,", *(pch-1)))
							|| (*(pch+2) && !isSpace(*(pch+2)))
						)) || bQuoteEscaped)
					{
						bQuoteEscaped = true;
						pch++; // Point to "
					}
				}
				else if (*pch == L'"')
					break;
				// Next entry AFTER pch
				pch = wcspbrk(pch+1, L"\\\"");
			}
		}

		if (!pch) return CERR_CMDLINE;

		while (pch[1] == L'"' && (!rsArg.mpsz_Dequoted || ((pch+1) < rsArg.mpsz_Dequoted)))
		{
			pch += 2;
			pch = wcschr(pch, L'"');

			if (!pch) return CERR_CMDLINE;
		}

		// Теперь в pch ссылка на последнюю "
	}
	else
	{
		// До конца строки или до первого пробела
		//pch = wcschr(psCmdLine, L' ');
		// 09.06.2009 Maks - обломался на: cmd /c" echo Y "
		pch = psCmdLine;

		// General: Look for spacing of quote
		while (*pch && *pch!=L'"'
			&& *pch!=L' ' && *pch!=L'\t' && *pch!=L'\r' && *pch!=L'\n')
			pch++;

		//if (!pch) pch = psCmdLine + lstrlenW(psCmdLine); // до конца строки
	}

	_ASSERTE(pch >= psCmdLine);
	nArgLen = pch - psCmdLine;

	// Set result arugment
	// Warning: Don't demangle quotes/escapes here, or we'll fail to
	// concatenate environment or smth, losing quotes and others
	if (!rsArg.Set(psCmdLine, nArgLen))
		return CERR_CMDLINE;
	rsArg.mb_Quoted = lbQMode;
	rsArg.mn_TokenNo++;

	if (rsArgStart) *rsArgStart = psCmdLine;

	psCmdLine = pch;
	// Finalize
	if ((*psCmdLine == L'"') && (lbQMode || (rsArg.mpsz_Dequoted == psCmdLine)))
		psCmdLine++; // was pointed to closing quotation mark

	psCmdLine = SkipNonPrintable(psCmdLine);
	// When whole line was dequoted
	if ((*psCmdLine == L'"') && (rsArg.mpsz_Dequoted == psCmdLine))
		psCmdLine++;

	#ifdef _DEBUG
	rsArg.ms_LastTokenEnd = psCmdLine;
	lstrcpyn(rsArg.ms_LastTokenSave, psCmdLine, countof(rsArg.ms_LastTokenSave));
	#endif

	switch (rsArg.mn_CmdCall)
	{
	case CEStr::cc_Undefined:
		// Если это однозначно "ключ" - то на имя файла не проверяем
		if (*rsArg.ms_Val == L'/' || *rsArg.ms_Val == L'-')
		{
			// Это для парсинга (чтобы ассертов не было) параметров из ShellExecute (там cmd.exe указывается в другом аргументе)
			if ((rsArg.mn_TokenNo == 1) && (lstrcmpi(rsArg.ms_Val, L"/C") == 0 || lstrcmpi(rsArg.ms_Val, L"/K") == 0))
				rsArg.mn_CmdCall = CEStr::cc_CmdCK;
		}
		else
		{
			pch = PointToName(rsArg.ms_Val);
			if (pch)
			{
				if ((lstrcmpi(pch, L"cmd") == 0 || lstrcmpi(pch, L"cmd.exe") == 0)
					|| (lstrcmpi(pch, L"ConEmuC") == 0 || lstrcmpi(pch, L"ConEmuC.exe") == 0)
					|| (lstrcmpi(pch, L"ConEmuC64") == 0 || lstrcmpi(pch, L"ConEmuC64.exe") == 0))
				{
					rsArg.mn_CmdCall = CEStr::cc_CmdExeFound;
				}
			}
		}
		break;
	case CEStr::cc_CmdExeFound:
		if (lstrcmpi(rsArg.ms_Val, L"/C") == 0 || lstrcmpi(rsArg.ms_Val, L"/K") == 0)
			rsArg.mn_CmdCall = CEStr::cc_CmdCK;
		else if ((rsArg.ms_Val[0] != L'/') && (rsArg.ms_Val[0] != L'-'))
			rsArg.mn_CmdCall = CEStr::cc_Undefined;
		break;
	}

	*asCmdLine = psCmdLine;
	return 0;
}
Exemple #28
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;
}
Exemple #29
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;
}
Exemple #30
0
int CIconList::CreateTabIconInt(LPCWSTR asIconDescr, bool bAdmin, LPCWSTR asWorkDir)
{
	wchar_t* pszExpanded = ExpandEnvStr(asIconDescr);

	// Need to be created!
	int iIconIdx = -1;
	HICON hFileIcon = NULL;
	CEStr szLoadFile;
	LPCWSTR lpszExt = NULL;
	int nIndex = 0;
	bool bDirChanged = false;

	if (!szLoadFile.Set(pszExpanded ? pszExpanded : asIconDescr))
	{
		goto wrap;
	}

	lpszExt = ParseIconFileIndex(szLoadFile, nIndex);

	if (asWorkDir && *asWorkDir)
	{
		// Executable (or icon) file may be not availbale by %PATH%, let "cd" to it...
		bDirChanged = gpConEmu->ChangeWorkDir(asWorkDir);
	}

	if (!lpszExt)
	{
		if (apiSearchPath(NULL, szLoadFile, L".exe", szLoadFile))
		{
			lpszExt = PointToExt(szLoadFile);
		}

		if (!lpszExt)
			goto wrap;
	}

	if (lstrcmpi(lpszExt, L".ico") == 0)
	{
		hFileIcon = (HICON)LoadImage(0, szLoadFile, IMAGE_ICON, mn_CxIcon, mn_CyIcon, LR_DEFAULTCOLOR|LR_LOADFROMFILE);
	}
	else if ((lstrcmpi(lpszExt, L".exe") == 0) || (lstrcmpi(lpszExt, L".dll") == 0))
	{
		HICON hIconLarge = NULL, hIconSmall = NULL;
		ExtractIconEx(szLoadFile, nIndex, &hIconLarge, &hIconSmall, 1);
		bool bUseLargeIcon = ((mn_CxIcon > 16) && (hIconLarge != NULL)) || (hIconSmall == NULL);
		HICON hDestroyIcon = bUseLargeIcon ? hIconSmall : hIconLarge;
		if (hDestroyIcon) DestroyIcon(hDestroyIcon);
		hFileIcon = bUseLargeIcon ? hIconLarge : hIconSmall;
	}
	else
	{
		//TODO: Shell icons for registered files (cmd, bat, sh, pl, py, ...)
	}

	if (hFileIcon)
	{
		wchar_t szIconInfo[80] = L"", szMergedInfo[80] = L"";
		GetIconInfoStr(hFileIcon, szIconInfo);

		if (gpSetCls->isAdvLogging)
		{
			CEStr lsLog(lstrmerge(L"Icon `", asIconDescr, L"` was loaded: ", szIconInfo));
			gpConEmu->LogString(lsLog);
		}

		int iIconIdxAdm = -1;
		iIconIdx = ImageList_ReplaceIcon(mh_TabIcons, -1, hFileIcon);

		TabIconCache NewIcon = {lstrdup(asIconDescr), iIconIdx, false};
		m_Icons.push_back(NewIcon);

		if (mn_AdminIcon >= 0)
		{
			HIMAGELIST hAdmList = ImageList_Merge(mh_TabIcons, iIconIdx, mh_TabIcons, mn_AdminIcon+2, 0,0);
			if (hAdmList)
			{
				HICON hNewIcon = ImageList_GetIcon(hAdmList, 0, ILD_TRANSPARENT);
				if (hNewIcon)
				{
					CEStr lsLog(lstrmerge(L"Admin icon `", asIconDescr, L"` was created: ", GetIconInfoStr(hNewIcon, szMergedInfo)));
					gpConEmu->LogString(lsLog);

					iIconIdxAdm = ImageList_ReplaceIcon(mh_TabIcons, -1, hNewIcon);
					DestroyIcon(hNewIcon);

					TabIconCache AdmIcon = {lstrdup(asIconDescr), iIconIdxAdm, true};
					m_Icons.push_back(AdmIcon);

					if (bAdmin && (iIconIdxAdm > 0))
					{
						iIconIdx = iIconIdxAdm;
					}
				}
				else
				{
					gpConEmu->LogString(L"GetIcon for admin icon was failed");
				}
				ImageList_Destroy(hAdmList);
			}
			else
			{
				gpConEmu->LogString(L"Admin icon merging was failed");
			}
		}

		DestroyIcon(hFileIcon);
	}

wrap:
	if (bDirChanged)
	{
		gpConEmu->ChangeWorkDir(NULL);
	}
	SafeFree(pszExpanded);
	if (gpSetCls->isAdvLogging && (iIconIdx < 0))
	{
		CEStr lsLog(lstrmerge(L"Icon `", asIconDescr, L"` loading was failed"));
		gpConEmu->LogString(lsLog);
	}
	return iIconIdx;
}