Beispiel #1
0
void RegisterConsoleFontHKLM(LPCWSTR pszFontFace)
{
	if (!pszFontFace || !*pszFontFace)
		return;

	HKEY hk;
	DWORD nRights = KEY_ALL_ACCESS|WIN3264TEST((IsWindows64() ? KEY_WOW64_64KEY : 0),0);

	if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Console\\TrueTypeFont",
	                  0, nRights, &hk))
	{
		wchar_t szId[32] = {0}, szFont[255]; DWORD dwLen, dwType;

		for (DWORD i = 0; i <20; i++)
		{
			szId[i] = L'0'; szId[i+1] = 0; wmemset(szFont, 0, 255);

			if (RegQueryValueExW(hk, szId, NULL, &dwType, (LPBYTE)szFont, &(dwLen = 255*2)))
			{
				RegSetValueExW(hk, szId, 0, REG_SZ, (LPBYTE)pszFontFace, (lstrlen(pszFontFace)+1)*2);
				break;
			}

			if (lstrcmpi(szFont, pszFontFace) == 0)
			{
				break; // он уже добавлен
			}
		}

		RegCloseKey(hk);
	}
}
Beispiel #2
0
// ConEmuC -OsVerInfo
int OsVerInfo()
{
	OSVERSIONINFOEX osv = {sizeof(osv)};
	GetOsVersionInformational((OSVERSIONINFO*)&osv);

	UINT DBCS = IsDbcs();
	UINT HWFS = IsHwFullScreenAvailable();
	UINT W5fam = IsWin5family();
	UINT WXPSP1 = IsWinXPSP1();
	UINT W6 = IsWin6();
	UINT W7 = IsWin7();
	UINT W10 = IsWin10();
	UINT Wx64 = IsWindows64();
	UINT WINE = IsWine();
	UINT WPE = IsWinPE();
	UINT TELNET = isTerminalMode();

	wchar_t szInfo[200];
	_wsprintf(szInfo, SKIPCOUNT(szInfo)
		L"OS version information\n"
		L"%u.%u build %u SP%u.%u suite=x%04X type=%u\n"
		L"W5fam=%u WXPSP1=%u W6=%u W7=%u W10=%u Wx64=%u\n"
		L"HWFS=%u DBCS=%u WINE=%u WPE=%u TELNET=%u\n",
		osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber, osv.wServicePackMajor, osv.wServicePackMinor, osv.wSuiteMask, osv.wProductType,
		W5fam, WXPSP1, W6, W7, W10, Wx64, HWFS,
		DBCS, WINE, WPE, TELNET);
	_wprintf(szInfo);

	return MAKEWORD(osv.dwMinorVersion, osv.dwMajorVersion);
}
Beispiel #3
0
CAttachDlg::CAttachDlg()
	: mh_Dlg(NULL)
	, mh_List(NULL)
	, mn_AttachType(0)
	, mn_AttachPID(0)
	, mh_AttachHWND(NULL)
	, mp_ProcessData(NULL)
{
	mb_IsWin64 = IsWindows64();
}
Beispiel #4
0
// Check running process bits - 32/64
int GetProcessBits(DWORD nPID, HANDLE hProcess /*= NULL*/)
{
	if (!IsWindows64())
		return 32;

	int ImageBits = WIN3264TEST(32,64); //-V112

	typedef BOOL (WINAPI* IsWow64Process_t)(HANDLE, PBOOL);
	static IsWow64Process_t IsWow64Process_f = NULL;

	if (!IsWow64Process_f)
	{
		HMODULE hKernel = GetModuleHandle(L"kernel32.dll");
		if (hKernel)
		{
			IsWow64Process_f = (IsWow64Process_t)GetProcAddress(hKernel, "IsWow64Process");
		}
	}

	if (IsWow64Process_f)
	{
		BOOL bWow64 = FALSE;
		HANDLE h = hProcess ? hProcess : OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, nPID);

		// IsWow64Process would be succeessfull for PROCESS_QUERY_LIMITED_INFORMATION (Vista+)
		if ((h == NULL) && IsWin6())
		{
			// PROCESS_QUERY_LIMITED_INFORMATION not defined in GCC
			h = OpenProcess(0x1000/*PROCESS_QUERY_LIMITED_INFORMATION*/, FALSE, nPID);
		}

		if (h == NULL)
		{
			// If it is blocked due to access rights - try to find alternative ways (by path or PERF COUNTER)
			ImageBits = 0;
		}
		else if (IsWow64Process_f(h, &bWow64) && !bWow64)
		{
			ImageBits = 64;
		}
		else
		{
			ImageBits = 32;
		}

		if (h && (h != hProcess))
			CloseHandle(h);
	}

	return ImageBits;
}
Beispiel #5
0
/// Check running process bitness - 32/64
int GetProcessBits(DWORD nPID, HANDLE hProcess /*= NULL*/)
{
	if (!IsWindows64())
		return 32;

	int ImageBits = WIN3264TEST(32,64); //-V112

	static BOOL (WINAPI* IsWow64Process_f)(HANDLE, PBOOL) = NULL;

	if (!IsWow64Process_f)
	{
		// Kernel32.dll is always loaded due to static link
		MModule kernel(GetModuleHandle(L"kernel32.dll"));
		kernel.GetProcAddress("IsWow64Process", IsWow64Process_f);
		// 64-bit OS must have this function
		_ASSERTE(IsWow64Process_f != NULL);
	}

	if (IsWow64Process_f)
	{
		BOOL bWow64 = FALSE;
		HANDLE h = hProcess ? hProcess : OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, nPID);

		// IsWow64Process would be succeessfull for PROCESS_QUERY_LIMITED_INFORMATION (Vista+)
		if ((h == NULL) && IsWin6())
		{
			// PROCESS_QUERY_LIMITED_INFORMATION not defined in GCC
			h = OpenProcess(0x1000/*PROCESS_QUERY_LIMITED_INFORMATION*/, FALSE, nPID);
		}

		if (h == NULL)
		{
			// If it is blocked due to access rights - try to find alternative ways (by path or PERF COUNTER)
			ImageBits = 0;
		}
		else if (IsWow64Process_f(h, &bWow64) && !bWow64)
		{
			ImageBits = 64;
		}
		else
		{
			ImageBits = 32;
		}

		if (h && (h != hProcess))
			CloseHandle(h);
	}

	return ImageBits;
}
Beispiel #6
0
bool IsHwFullScreenAvailable()
{
	if (IsWindows64())
		return false;

	// HW FullScreen was available in Win2k & WinXP (32bit)
	_ASSERTE(_WIN32_WINNT_VISTA==0x600);
	OSVERSIONINFOEXW osvi = {sizeof(osvi), HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA)};
	DWORDLONG const dwlConditionMask = VerSetConditionMask(VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_GREATER_EQUAL);
	if (VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask))
		return false; // Vista or higher - not available
	else
		return true;
}
Beispiel #7
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();
			}
		}
	}
Beispiel #8
0
// Найти "ComSpec" и вернуть lstrdup на него
wchar_t* GetComspec(const ConEmuComspec* pOpt)
{
	wchar_t* pszComSpec = NULL;

	if (pOpt)
	{
		if ((pOpt->csType == cst_Explicit) && *pOpt->ComspecExplicit)
		{
			pszComSpec = lstrdup(pOpt->ComspecExplicit);
		}

		if (!pszComSpec && (pOpt->csBits == csb_SameOS))
		{
			BOOL bWin64 = IsWindows64();
			if (bWin64 ? *pOpt->Comspec64 : *pOpt->Comspec32)
				pszComSpec = lstrdup(bWin64 ? pOpt->Comspec64 : pOpt->Comspec32);
		}

		if (!pszComSpec && (pOpt->csBits == csb_SameApp))
		{
			BOOL bWin64 = WIN3264TEST(FALSE,TRUE);
			if (bWin64 ? *pOpt->Comspec64 : *pOpt->Comspec32)
				pszComSpec = lstrdup(bWin64 ? pOpt->Comspec64 : pOpt->Comspec32);
		}

		if (!pszComSpec)
		{
			BOOL bWin64 = (pOpt->csBits != csb_x32);
			if (bWin64 ? *pOpt->Comspec64 : *pOpt->Comspec32)
				pszComSpec = lstrdup(bWin64 ? pOpt->Comspec64 : pOpt->Comspec32);
		}
	}
	else
	{
		_ASSERTE(pOpt && L"pOpt должен быть передан, по идее");
	}

	if (!pszComSpec)
	{
		wchar_t szComSpec[MAX_PATH];
		pszComSpec = lstrdup(GetComspecFromEnvVar(szComSpec, countof(szComSpec)));
	}

	// Уже должно быть хоть что-то
	_ASSERTE(pszComSpec && *pszComSpec);
	return pszComSpec;
}
Beispiel #9
0
int RegEnumKeys(HKEY hkRoot, LPCWSTR pszParentPath, RegEnumKeysCallback fn, LPARAM lParam)
{
	int iRc = -1;
	HKEY hk = NULL, hkChild = NULL;
	bool bContinue = true;
	LONG lrc;
	bool ib64 = IsWindows64();

	for (int s = 0; s < (ib64 ? 2 : 1); s++)
	{
		DWORD samDesired = KEY_READ;
		if (ib64)
		{
			if (s == 0)
				samDesired |= WIN3264TEST(KEY_WOW64_32KEY,KEY_WOW64_64KEY);
			else
				samDesired |= WIN3264TEST(KEY_WOW64_64KEY,KEY_WOW64_32KEY);
		}

		if (0 == (lrc = RegOpenKeyEx(hkRoot, pszParentPath, 0, samDesired, &hk)))
		{
			iRc = 0;
			UINT n = 0;
			wchar_t szSubKey[MAX_PATH] = L""; DWORD cchMax = countof(szSubKey) - 1;

			while (0 == (lrc = RegEnumKeyEx(hk, n++, szSubKey, &cchMax, NULL, NULL, NULL, NULL)))
			{
				if (0 == (lrc = RegOpenKeyEx(hk, szSubKey, 0, samDesired, &hkChild)))
				{
					if (fn != NULL)
					{
						if (!fn(hkChild, szSubKey, lParam))
							break;
					}
					iRc++;
					RegCloseKey(hkChild);
				}
				cchMax = countof(szSubKey) - 1;
			}

			RegCloseKey(hk);
		}
	}

	return iRc;
}
// Вернуть путь к папке, содержащей ConEmuC.exe
BOOL IsConEmuExeExist(LPCWSTR szExePath, wchar_t (&rsConEmuExe)[MAX_PATH+1])
{
	BOOL lbExeFound = FALSE;
	BOOL isWin64 = WIN3264TEST(IsWindows64(),TRUE);

	//if (szExePath[lstrlen(szExePath)-1] != L'\\')
	//	wcscat_c(szExePath, L"\\");
	_ASSERTE(szExePath && *szExePath && (szExePath[lstrlen(szExePath)-1] == L'\\'));

	wcscpy_c(rsConEmuExe, szExePath);
	wchar_t* pszName = rsConEmuExe+lstrlen(rsConEmuExe);
	LPCWSTR szGuiExe[2] = {L"ConEmu64.exe", L"ConEmu.exe"};
	for (size_t s = 0; !lbExeFound && (s < countof(szGuiExe)); s++)
	{
		if (!s && !isWin64) continue;
		wcscpy_add(pszName, rsConEmuExe, szGuiExe[s]);
		lbExeFound = FileExists(rsConEmuExe);
	}

	return lbExeFound;
}
Beispiel #11
0
	void Init()
	{
		mb_IsWindows64 = IsWindows64();
		memset(&m_Store, 0, sizeof(m_Store));
		mp_Last = &m_Store;
		mp_LastKey = NULL;
		memset(&m_HKCU, 0, sizeof(m_HKCU));
		memset(&m_HKLM, 0, sizeof(m_HKLM));
		memset(&m_HKLM32, 0, sizeof(m_HKLM32));
		memset(&m_HKLM64, 0, sizeof(m_HKLM64));
		// Common HKCU
		m_HKCU.hKey = HKEY_CURRENT_USER; m_HKCU.rkt = RKT_HKCU;
		// Native for process
		m_HKLM.hKey = HKEY_LOCAL_MACHINE; 
		#ifdef _WIN64
		m_HKLM.rkt = RKT_HKLM64;
		#else
		m_HKLM.rkt = RKT_HKLM32;
		#endif
		// When specified KEY_WOW64_64KEY/KEY_WOW64_32KEY
		m_HKLM32.hKey = HKEY_LOCAL_MACHINE; m_HKLM32.rkt = RKT_HKLM32;
		m_HKLM64.hKey = HKEY_LOCAL_MACHINE; m_HKLM64.rkt = mb_IsWindows64 ? RKT_HKLM64 : RKT_HKLM32;
	};
Beispiel #12
0
// используется в GUI при загрузке настроек
void FindComspec(ConEmuComspec* pOpt, bool bCmdAlso /*= true*/)
{
	if (!pOpt)
		return;

	pOpt->Comspec32[0] = 0;
	pOpt->Comspec64[0] = 0;

	// Ищем tcc.exe
	if (pOpt->csType == cst_AutoTccCmd)
	{
		HKEY hk;
		BOOL bWin64 = IsWindows64();
		wchar_t szPath[MAX_PATH+1];

		// If tcc.exe can be found near to ConEmu location
		LPCWSTR ppszPredefined[] = {
			L"%ConEmuBaseDir%\\tcc.exe",
			L"%ConEmuDir%\\tcc.exe",
			// Sort of PortableApps locations
			L"%ConEmuDir%\\..\\tcc\\tcc.exe",
			L"%ConEmuDir%\\..\\..\\tcc\\tcc.exe",
			// End of predefined list
			NULL};
		for (INT_PTR i = 0; ppszPredefined[i]; i++)
		{
			DWORD nExpand = ExpandEnvironmentStrings(ppszPredefined[i], szPath, countof(szPath));
			if (nExpand && (nExpand < countof(szPath)))
			{
				if (FileExists(szPath))
				{
					wcscpy_c(pOpt->Comspec32, szPath);
					wcscpy_c(pOpt->Comspec64, szPath);
					break;
				}
			}
		}

		// On this step - check "Take Command"!
		if (!*pOpt->Comspec32 || !*pOpt->Comspec64)
		{
			// [HKEY_LOCAL_MACHINE\SOFTWARE\JP Software\Take Command 13.0]
			// @="\"C:\\Program Files\\JPSoft\\TCMD13\\tcmd.exe\""
			for (int b = 0; b <= 1; b++)
			{
				// b==0 - 32bit, b==1 - 64bit
				if (b && !bWin64)
					continue;
				bool bFound = false;
				DWORD nOpt = (b == 0) ? (bWin64 ? KEY_WOW64_32KEY : 0) : (bWin64 ? KEY_WOW64_64KEY : 0);
				if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\JP Software", 0, KEY_READ|nOpt, &hk))
				{
					wchar_t szName[MAX_PATH+1]; DWORD nLen;
					for (DWORD k = 0; !bFound && !RegEnumKeyEx(hk, k, szName, &(nLen = countof(szName)-1), 0,0,0,0); k++)
					{
						HKEY hk2;
						if (!RegOpenKeyEx(hk, szName, 0, KEY_READ|nOpt, &hk2))
						{
							// Just in case, check "Path" too
							LPCWSTR rsNames[] = {NULL, L"Path"};

							for (size_t n = 0; n < countof(rsNames); n++)
							{
								ZeroStruct(szPath); DWORD nSize = (countof(szPath)-1)*sizeof(szPath[0]);
								if (!RegQueryValueExW(hk2, rsNames[n], NULL, NULL, (LPBYTE)szPath, &nSize) && *szPath)
								{
									wchar_t* psz, *pszEnd;
									psz = (wchar_t*)Unquote(szPath, true);
									pszEnd = wcsrchr(psz, L'\\');
									if (!pszEnd || lstrcmpi(pszEnd, L"\\tcmd.exe") || !FileExists(psz))
										continue;
									lstrcpyn(pszEnd+1, L"tcc.exe", 8);
									if (FileExists(psz))
									{
										bFound = true;
										if (b == 0)
											wcscpy_c(pOpt->Comspec32, psz);
										else
											wcscpy_c(pOpt->Comspec64, psz);
									}
								}
							} // for (size_t n = 0; n < countof(rsNames); n++)
							RegCloseKey(hk2);
						}
					} //  for, подключи
					RegCloseKey(hk);
				} // L"SOFTWARE\\JP Software"
			} // for (int b = 0; b <= 1; b++)

			// Если установлен TCMD - предпочтительно использовать именно его, независимо от битности
			if (*pOpt->Comspec32 && !*pOpt->Comspec64)
				wcscpy_c(pOpt->Comspec64, pOpt->Comspec32);
			else if (*pOpt->Comspec64 && !*pOpt->Comspec32)
				wcscpy_c(pOpt->Comspec32, pOpt->Comspec64);
		}

		// If "Take Command" not installed - try "TCC/LE"
		if (!*pOpt->Comspec32 || !*pOpt->Comspec64)
		{
			// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{16A21882-4138-4ADA-A390-F62DC27E4504}]
			// "DisplayVersion"="13.04.60"
			// "Publisher"="JP Software"
			// "DisplayName"="Take Command 13.0"
			// или
			// "DisplayName"="TCC/LE 13.0"
			// и наконец
			// "InstallLocation"="C:\\Program Files\\JPSoft\\TCMD13\\"
			for (int b = 0; b <= 1; b++)
			{
				// b==0 - 32bit, b==1 - 64bit
				if (b && !bWin64)
					continue;
				if (((b == 0) ? *pOpt->Comspec32 : *pOpt->Comspec64))
					continue; // этот уже нашелся в TCMD

				bool bFound = false;
				DWORD nOpt = (b == 0) ? (bWin64 ? KEY_WOW64_32KEY : 0) : (bWin64 ? KEY_WOW64_64KEY : 0);
				if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, KEY_READ|nOpt, &hk))
				{
					wchar_t szName[MAX_PATH+1]; DWORD nLen;
					for (DWORD n = 0; !bFound && !RegEnumKeyEx(hk, n, szName, &(nLen = countof(szName)-1), 0,0,0,0); n++)
					{
						if (*szName != L'{')
							continue;
						HKEY hk2;
						if (!RegOpenKeyEx(hk, szName, 0, KEY_READ|nOpt, &hk2))
						{
							ZeroStruct(szPath); DWORD nSize = (countof(szPath) - 1)*sizeof(szPath[0]);
							if (!RegQueryValueExW(hk2, L"Publisher", NULL, NULL, (LPBYTE)szPath, &nSize)
								&& !lstrcmpi(szPath, L"JP Software"))
							{
								nSize = (countof(szPath)-12)*sizeof(szPath[0]);
								if (!RegQueryValueExW(hk2, L"InstallLocation", NULL, NULL, (LPBYTE)szPath, &nSize)
									&& *szPath)
								{
									wchar_t* psz, *pszEnd;
									if (szPath[0] == L'"')
									{
										psz = szPath + 1;
										pszEnd = wcschr(psz, L'"');
										if (pszEnd)
											*pszEnd = 0;
									}
									else
									{
										psz = szPath;
									}
									if (*psz)
									{
										pszEnd = psz+lstrlen(psz);
										if (*(pszEnd-1) != L'\\')
											*(pszEnd++) = L'\\';
										lstrcpyn(pszEnd, L"tcc.exe", 8);
										if (FileExists(psz))
										{
											bFound = true;
											if (b == 0)
												wcscpy_c(pOpt->Comspec32, psz);
											else
												wcscpy_c(pOpt->Comspec64, psz);
										}
									}
								}
							}
							RegCloseKey(hk2);
						}
					} // for, подключи
					RegCloseKey(hk);
				} // L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
			} // for (int b = 0; b <= 1; b++)
		}

		// Попытаться "в лоб" из "Program Files"
		if (!*pOpt->Comspec32 && !*pOpt->Comspec64)
		{

			const wchar_t* pszTcmd  = L"C:\\Program Files\\JPSoft\\TCMD13\\tcc.exe";
			const wchar_t* pszTccLe = L"C:\\Program Files\\JPSoft\\TCCLE13\\tcc.exe";
			if (FileExists(pszTcmd))
				wcscpy_c(pOpt->Comspec32, pszTcmd);
			else if (FileExists(pszTccLe))
				wcscpy_c(pOpt->Comspec32, pszTccLe);
		}

		if (*pOpt->Comspec32 && !*pOpt->Comspec64)
			wcscpy_c(pOpt->Comspec64, pOpt->Comspec32);
		else if (*pOpt->Comspec64 && !*pOpt->Comspec32)
			wcscpy_c(pOpt->Comspec32, pOpt->Comspec64);
	} // if (pOpt->csType == cst_AutoTccCmd)

	// С поиском tcc закончили. Теперь, если pOpt->Comspec32/pOpt->Comspec64 остались не заполнены
	// нужно сначала попытаться обработать переменную окружения ComSpec, а потом - просто "cmd.exe"
	if (!*pOpt->Comspec32)
		GetComspecFromEnvVar(pOpt->Comspec32, countof(pOpt->Comspec32), csb_x32);
	if (!*pOpt->Comspec64)
		GetComspecFromEnvVar(pOpt->Comspec64, countof(pOpt->Comspec64), csb_x64);
}
Beispiel #13
0
DWORD WINAPI DebugThread(LPVOID lpvParam)
{
	DWORD nWait = WAIT_TIMEOUT;
	//DWORD nExternalExitCode = -1;
	wchar_t szInfo[1024];

	if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
	{
		STARTUPINFO si = {sizeof(si)};
		PROCESS_INFORMATION pi = {};

		if (gpSrv->DbgInfo.bDebugProcessTree)
		{
			SetEnvironmentVariable(ENV_CONEMU_BLOCKCHILDDEBUGGERS_W, ENV_CONEMU_BLOCKCHILDDEBUGGERS_YES);
		}

		if (!CreateProcess(NULL, gpSrv->DbgInfo.pszDebuggingCmdLine, NULL, NULL, FALSE,
			NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|
			DEBUG_PROCESS | (gpSrv->DbgInfo.bDebugProcessTree ? 0 : DEBUG_ONLY_THIS_PROCESS),
			NULL, NULL, &si, &pi))
		{
			DWORD dwErr = GetLastError();

			wchar_t szProc[64]; szProc[0] = 0;
			PROCESSENTRY32 pi = {sizeof(pi)};
			if (GetProcessInfo(gpSrv->dwRootProcess, &pi))
				_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start debugging process. ErrCode=0x%08X\n", dwErr);
			lstrcpyn(szInfo+lstrlen(szInfo), gpSrv->DbgInfo.pszDebuggingCmdLine, 400);
			wcscat_c(szInfo, L"\n");
			_wprintf(szInfo);
			return CERR_CANTSTARTDEBUGGER;
		}

		gpSrv->hRootProcess = pi.hProcess;
		gpSrv->hRootThread = pi.hThread;
		gpSrv->dwRootProcess = pi.dwProcessId;
		gpSrv->dwRootThread = pi.dwThreadId;
		gpSrv->dwRootStartTime = GetTickCount();
	}


	/* ************************* */
	int iDbgIdx = 0, iAttachedCount = 0;
	while (true)
	{
		HANDLE hDbgProcess = NULL;
		DWORD  nDbgProcessID = 0;

		bool bFirstPID = ((iDbgIdx++) == 0);
		if (bFirstPID)
		{
			hDbgProcess = gpSrv->hRootProcess;
			nDbgProcessID = gpSrv->dwRootProcess;
		}
		else
		{
			// Взять из pDebugAttachProcesses
			if (!gpSrv->DbgInfo.pDebugAttachProcesses)
				break;
			if (!gpSrv->DbgInfo.pDebugAttachProcesses->pop_back(nDbgProcessID))
				break;
			hDbgProcess = GetProcessHandleForDebug(nDbgProcessID);
			if (!hDbgProcess)
			{
				_ASSERTE(hDbgProcess!=NULL && "Can't open debugging process handle");
				continue;
			}
		}
	

		_ASSERTE(hDbgProcess!=NULL && "Process handle must be opened");


		// Битность отладчика должна соответствовать битности приложения!
		if (IsWindows64())
		{
			int nBits = GetProcessBits(nDbgProcessID, hDbgProcess);
			if ((nBits == 32 || nBits == 64) && (nBits != WIN3264TEST(32,64)))
			{
				if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
				{
					_printf("Bitness of ConEmuC and debugging program does not match\n");
					if (bFirstPID)
						return CERR_CANTSTARTDEBUGGER;
					else
						continue;
				}

				wchar_t szExe[MAX_PATH+16];
				wchar_t szCmdLine[MAX_PATH*2];
				if (GetModuleFileName(NULL, szExe, countof(szExe)-16))
				{
					wchar_t* pszName = (wchar_t*)PointToName(szExe);
					_wcscpy_c(pszName, 16, (nBits == 32) ? L"ConEmuC.exe" : L"ConEmuC64.exe");
					_wsprintf(szCmdLine, SKIPLEN(countof(szCmdLine))
						L"\"%s\" /DEBUGPID=%u %s", szExe, nDbgProcessID,
						(gpSrv->DbgInfo.nDebugDumpProcess == 1) ? L"/DUMP" :
						(gpSrv->DbgInfo.nDebugDumpProcess == 2) ? L"/MINIDUMP" :
						(gpSrv->DbgInfo.nDebugDumpProcess == 3) ? L"/FULLDUMP" : L"");

					STARTUPINFO si = {sizeof(si)};
					PROCESS_INFORMATION pi = {};
					if (CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
					{
						// Ждать НЕ будем, сразу на выход

						//HANDLE hEvents[2] = {pi.hProcess, ghExitQueryEvent};
						//nWait = WaitForMultipleObjects(countof(hEvents), hEvents, FALSE, INFINITE);
						//if (nWait == WAIT_OBJECT_0)
						//{
						//	//GetExitCodeProcess(pi.hProcess, &nExternalExitCode);
						//	nExternalExitCode = 0;
						//}

						//CloseHandle(pi.hProcess);
						//CloseHandle(pi.hThread);

						//if (nExternalExitCode == 0)
						//{
						//	goto done;
						//}

						// Может там еще процессы в списке на дамп?
						continue;
					}
					else
					{
						DWORD dwErr = GetLastError();
						_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start external debugger '%s'. ErrCode=0x%08X\n",
							szCmdLine, dwErr);
						_wprintf(szInfo);
						if (bFirstPID)
							return CERR_CANTSTARTDEBUGGER;
						else
							continue;
					}
				}


				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Bits are incompatible. Can't debug '%s' PID=%i\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID);
				_wprintf(szInfo);
				if (bFirstPID)
					return CERR_CANTSTARTDEBUGGER;
				else
					continue;
			}
		}

		if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL)
		{
			if (!DebugActiveProcess(nDbgProcessID))
			{
				DWORD dwErr = GetLastError();

				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't attach debugger to '%s' PID=%i. ErrCode=0x%08X\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID, dwErr);
				_wprintf(szInfo);
				return CERR_CANTSTARTDEBUGGER;
			}
		}

		iAttachedCount++;
	}

	if (iAttachedCount == 0)
	{
		return CERR_CANTSTARTDEBUGGER;
	}
	/* **************** */

	// Дополнительная инициализация, чтобы закрытие дебагера (наш процесс) не привело
	// к закрытию "отлаживаемой" программы
	pfnDebugActiveProcessStop = (FDebugActiveProcessStop)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugActiveProcessStop");
	pfnDebugSetProcessKillOnExit = (FDebugSetProcessKillOnExit)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugSetProcessKillOnExit");

	if (pfnDebugSetProcessKillOnExit)
		pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/);

	gpSrv->DbgInfo.bDebuggerActive = TRUE;
	PrintDebugInfo();
	SetEvent(gpSrv->DbgInfo.hDebugReady);
	

	while (nWait == WAIT_TIMEOUT)
	{
		ProcessDebugEvent();

		if (ghExitQueryEvent)
			nWait = WaitForSingleObject(ghExitQueryEvent, 0);
	}

//done:
	gbRootAliveLess10sec = FALSE;
	gbInShutdown = TRUE;
	gbAlwaysConfirmExit = FALSE;

	_ASSERTE(gbTerminateOnCtrlBreak==FALSE);

	if (!nExitQueryPlace) nExitQueryPlace = 12+(nExitPlaceStep);

	SetTerminateEvent(ste_DebugThread);
	return 0;
}
BOOL FindConEmuBaseDir(wchar_t (&rsConEmuBaseDir)[MAX_PATH+1], wchar_t (&rsConEmuExe)[MAX_PATH+1], HMODULE hPluginDll /*= NULL*/)
{
	// Сначала пробуем Mapping консоли (вдруг есть?)
	{
		MFileMapping<CESERVER_CONSOLE_MAPPING_HDR> ConMap;
		ConMap.InitName(CECONMAPNAME, (DWORD)myGetConsoleWindow()); //-V205
		CESERVER_CONSOLE_MAPPING_HDR* p = ConMap.Open();
		if (p && p->ComSpec.ConEmuBaseDir[0])
		{
			// Успешно
			wcscpy_c(rsConEmuBaseDir, p->ComSpec.ConEmuBaseDir);
			wcscpy_c(rsConEmuExe, p->sConEmuExe);
			return TRUE;
		}
	}

	// Теперь - пробуем найти существующее окно ConEmu
	HWND hConEmu = FindWindow(VirtualConsoleClassMain, NULL);
	DWORD dwGuiPID = 0;
	if (hConEmu)
	{
		if (GetWindowThreadProcessId(hConEmu, &dwGuiPID) && dwGuiPID)
		{
			MFileMapping<ConEmuGuiMapping> GuiMap;
			GuiMap.InitName(CEGUIINFOMAPNAME, dwGuiPID);
			ConEmuGuiMapping* p = GuiMap.Open();
			if (p && p->ComSpec.ConEmuBaseDir[0])
			{
				wcscpy_c(rsConEmuBaseDir, p->ComSpec.ConEmuBaseDir);
				wcscpy_c(rsConEmuExe, p->sConEmuExe);
				return TRUE;
			}
		}
	}


	wchar_t szExePath[MAX_PATH+1];
	HKEY hkRoot[] = {NULL,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_LOCAL_MACHINE};
	DWORD samDesired = KEY_QUERY_VALUE;

	BOOL isWin64 = WIN3264TEST(IsWindows64(),TRUE);
	DWORD RedirectionFlag = WIN3264TEST((isWin64 ? KEY_WOW64_64KEY : 0),KEY_WOW64_32KEY);
	//#ifdef _WIN64
	//	isWin64 = TRUE;
	//	RedirectionFlag = KEY_WOW64_32KEY;
	//#else
	//	isWin64 = IsWindows64();
	//	RedirectionFlag = isWin64 ? KEY_WOW64_64KEY : 0;
	//#endif

	for (size_t i = 0; i < countof(hkRoot); i++)
	{
		szExePath[0] = 0;

		if (i == 0)
		{
			// Запущенного ConEmu.exe нет, можно поискать в каталоге текущего приложения

			if (!GetModuleFileName(NULL, szExePath, countof(szExePath)-20))
				continue;
			wchar_t* pszName = wcsrchr(szExePath, L'\\');
			if (!pszName)
				continue;
			*(pszName+1) = 0;

			// Проверяем наличие файлов
			// LPCWSTR szGuiExe[2] = {L"ConEmu64.exe", L"ConEmu.exe"};
			if (!IsConEmuExeExist(szExePath, rsConEmuExe) && hPluginDll)
			{
				// Попробовать найти наш exe-шник от пути плагина?
				if (!GetModuleFileName(hPluginDll, szExePath, countof(szExePath)-1))
					continue;
				wchar_t* pszName = wcsrchr(szExePath, L'\\');
				if (!pszName)
					continue;
				*(pszName+1) = 0;
				int nLen = lstrlen(szExePath);
				LPCWSTR pszCompare = L"\\Plugins\\ConEmu\\";
				if (nLen <= lstrlen(pszCompare))
					continue;
				nLen = lstrlen(pszCompare);
				int iCmp = lstrcmpi(pszName-nLen+1, pszCompare);
				if (iCmp != 0)
					continue;
				*(pszName-nLen+2) = 0;
			}

		}
		else
		{
			// Остался последний шанс - если ConEmu установлен через MSI, то путь указан в реестре
			// [HKEY_LOCAL_MACHINE\SOFTWARE\ConEmu]
			// "InstallDir"="C:\\Utils\\Far180\\"

			if (i == (countof(hkRoot)-1))
			{
				if (RedirectionFlag)
					samDesired |= RedirectionFlag;
				else
					break;
			}

			HKEY hKey;
			if (RegOpenKeyEx(hkRoot[i], L"Software\\ConEmu", 0, samDesired, &hKey) != ERROR_SUCCESS)
				continue;
			memset(szExePath, 0, countof(szExePath));
			DWORD nType = 0, nSize = sizeof(szExePath)-20*sizeof(wchar_t);
			int RegResult = RegQueryValueEx(hKey, L"", NULL, &nType, (LPBYTE)szExePath, &nSize);
			RegCloseKey(hKey);
			if (RegResult != ERROR_SUCCESS)
				continue;
		}

		if (szExePath[0])
		{
			// Хоть и задано в реестре - файлов может не быть. Проверяем
			if (szExePath[lstrlen(szExePath)-1] != L'\\')
				wcscat_c(szExePath, L"\\");
			// Проверяем наличие файлов
			// LPCWSTR szGuiExe[2] = {L"ConEmu64.exe", L"ConEmu.exe"};
			BOOL lbExeFound = IsConEmuExeExist(szExePath, rsConEmuExe);

			// Если GUI-exe найден - ищем "base"
			if (lbExeFound)
			{
				wchar_t* pszName = szExePath+lstrlen(szExePath);
				LPCWSTR szSrvExe[4] = {L"ConEmuC64.exe", L"ConEmu\\ConEmuC64.exe", L"ConEmuC.exe", L"ConEmu\\ConEmuC.exe"};
				for (size_t s = 0; s < countof(szSrvExe); s++)
				{
					if ((s <=1) && !isWin64) continue;
					wcscpy_add(pszName, szExePath, szSrvExe[s]);
					if (FileExists(szExePath))
					{
						pszName = wcsrchr(szExePath, L'\\');
						if (pszName)
						{
							*pszName = 0; // БЕЗ слеша на конце!
							wcscpy_c(rsConEmuBaseDir, szExePath);
							return TRUE;
						}
					}
				}
			}
		}
	}

	// Не удалось
	return FALSE;
}
Beispiel #15
0
LPCWSTR GetComspecFromEnvVar(wchar_t* pszComspec, DWORD cchMax, ComSpecBits Bits/* = csb_SameOS*/)
{
	if (!pszComspec || (cchMax < MAX_PATH))
	{
		_ASSERTE(pszComspec && (cchMax >= MAX_PATH));
		return NULL;
	}

	*pszComspec = 0;
	BOOL bWin64 = IsWindows64();

	if (!((Bits == csb_x32) || (Bits == csb_x64)))
	{
		if (GetEnvironmentVariable(L"ComSpec", pszComspec, cchMax))
		{
			// Не должен быть (даже случайно) ConEmuC.exe
			const wchar_t* pszName = PointToName(pszComspec);
			if (!pszName || !lstrcmpi(pszName, L"ConEmuC.exe") || !lstrcmpi(pszName, L"ConEmuC64.exe")
				|| !FileExists(pszComspec)) // ну и существовать должен
			{
				pszComspec[0] = 0;
			}
		}
	}

	// Если не удалось определить через переменную окружения - пробуем обычный "cmd.exe" из System32
	if (pszComspec[0] == 0)
	{
		int n = GetWindowsDirectory(pszComspec, cchMax - 20);
		if (n > 0 && (((DWORD)n) < (cchMax - 20)))
		{
			// Добавить \System32\cmd.exe

			// Warning! 'c:\Windows\SysNative\cmd.exe' не прокатит, т.к. доступен
			// только для 32битных приложений. А нам нужно в общем виде.
			// Если из 32битного нужно запустить 64битный cmd.exe - нужно выключать редиректор.

			if (!bWin64 || (Bits != csb_x32))
			{
				_wcscat_c(pszComspec, cchMax, (pszComspec[n-1] == L'\\') ? L"System32\\cmd.exe" : L"\\System32\\cmd.exe");
			}
			else
			{
				_wcscat_c(pszComspec, cchMax, (pszComspec[n-1] == L'\\') ? L"SysWOW64\\cmd.exe" : L"\\SysWOW64\\cmd.exe");
			}
		}
	}

	if (pszComspec[0] && !FileExists(pszComspec))
	{
		_ASSERTE("Comspec not found! File not exists!");
		pszComspec[0] = 0;
	}

	// Last chance
	if (pszComspec[0] == 0)
	{
		_ASSERTE(pszComspec[0] != 0); // Уже должен был быть определен
		//lstrcpyn(pszComspec, L"cmd.exe", cchMax);
		wchar_t *psFilePart;
		DWORD n = SearchPathW(NULL, L"cmd.exe", NULL, cchMax, pszComspec, &psFilePart);
		if (!n || (n >= cchMax))
			_wcscpy_c(pszComspec, cchMax, L"cmd.exe");
	}

	return pszComspec;
}
// CIR_OK=0 - OK, CIR_AlreadyInjected=1 - Already injected, иначе - ошибка
// Здесь вызывается CreateRemoteThread
CINFILTRATE_EXIT_CODES InjectRemote(DWORD nRemotePID, bool abDefTermOnly /*= false */)
{
	CINFILTRATE_EXIT_CODES iRc = CIR_GeneralError/*-1*/;
	bool lbWin64 = WIN3264TEST((IsWindows64()!=0),true);
	bool is32bit;
	int  nBits;
	DWORD nWrapperWait = (DWORD)-1, nWrapperResult = (DWORD)-1;
	HANDLE hProc = NULL;
	wchar_t szSelf[MAX_PATH+16], szHooks[MAX_PATH+16];
	wchar_t *pszNamePtr, szArgs[32];
	wchar_t szName[64];
	HANDLE hEvent = NULL;
	HANDLE hDefTermReady = NULL;
	bool bAlreadyHooked = false;
	HANDLE hSnap = NULL;
	MODULEENTRY32 mi = {sizeof(mi)};
	HMODULE ptrOuterKernel = NULL;

	if (!GetModuleFileName(NULL, szSelf, MAX_PATH))
	{
		iRc = CIR_GetModuleFileName/*-200*/;
		goto wrap;
	}
	wcscpy_c(szHooks, szSelf);
	pszNamePtr = (wchar_t*)PointToName(szHooks);
	if (!pszNamePtr)
	{
		iRc = CIR_GetModuleFileName/*-200*/;
		goto wrap;
	}


	// Hey, may be ConEmuHk.dll is already loaded?
	hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, nRemotePID);
	if (!hSnap || (hSnap == INVALID_HANDLE_VALUE))
	{
		iRc = CIR_SnapshotCantBeOpened/*-113*/;
		goto wrap;
	}
	else if (hSnap && Module32First(hSnap, &mi))
	{
		// 130829 - Let load newer(!) ConEmuHk.dll into target process.
		// 141201 - Also we need to be sure in kernel32.dll address

		LPCWSTR pszConEmuHk = WIN3264TEST(L"conemuhk.", L"conemuhk64.");
		size_t nDllNameLen = lstrlen(pszConEmuHk);
		// Out preferred module name
		wchar_t szOurName[40] = {};
		wchar_t szMinor[8] = L""; lstrcpyn(szMinor, _CRT_WIDE(MVV_4a), countof(szMinor));
		_wsprintf(szOurName, SKIPLEN(countof(szOurName))
			CEDEFTERMDLLFORMAT /*L"ConEmuHk%s.%02u%02u%02u%s.dll"*/,
			WIN3264TEST(L"",L"64"), MVV_1, MVV_2, MVV_3, szMinor);
		CharLowerBuff(szOurName, lstrlen(szOurName));

		// Go to enumeration
		wchar_t szName[64];
		do {
			LPCWSTR pszName = PointToName(mi.szModule);

			// Name of ConEmuHk*.*.dll module may be changed (copied to %APPDATA%)
			if (!pszName || !*pszName)
				continue;

			lstrcpyn(szName, pszName, countof(szName));
			CharLowerBuff(szName, lstrlen(szName));

			if (!ptrOuterKernel
				&& (lstrcmp(szName, L"kernel32.dll") == 0))
			{
				ptrOuterKernel = mi.hModule;
			}

			// ConEmuHk*.*.dll?
			if (!bAlreadyHooked
				&& (wmemcmp(szName, pszConEmuHk, nDllNameLen) == 0)
				&& (wmemcmp(szName+lstrlen(szName)-4, L".dll", 4) == 0))
			{
				// Yes! ConEmuHk.dll already loaded into nRemotePID!
				// But what is the version? Let don't downgrade loaded version!
				if (lstrcmp(szName, szOurName) >= 0)
				{
					// OK, szName is newer or equal to our build
					bAlreadyHooked = true;
				}
			}

			// Stop enumeration?
			if (bAlreadyHooked && ptrOuterKernel)
				break;
		} while (Module32Next(hSnap, &mi));

		// Check done
	}
	SafeCloseHandle(hSnap);


	// Already hooked?
	if (bAlreadyHooked)
	{
		iRc = CIR_AlreadyInjected/*1*/;
		goto wrap;
	}


	if (!ptrOuterKernel)
	{
		iRc = CIR_OuterKernelAddr/*-112*/;
		goto wrap;
	}


	// Check, if we can access that process
	hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, nRemotePID);
	if (hProc == NULL)
	{
		iRc = CIR_OpenProcess/*-201*/;
		goto wrap;
	}


	// Go to hook

	// Preparing Events
	_wsprintf(szName, SKIPLEN(countof(szName)) CEDEFAULTTERMHOOK, nRemotePID);
	if (!abDefTermOnly)
	{
		// When running in normal mode (NOT set up as default terminal)
		// we need full initialization procedure, not a light one when hooking explorer.exe
		hEvent = OpenEvent(EVENT_MODIFY_STATE|SYNCHRONIZE, FALSE, szName);
		if (hEvent)
		{
			ResetEvent(hEvent);
			CloseHandle(hEvent);
		}
	}
	else
	{
		hEvent = CreateEvent(LocalSecurity(), FALSE, FALSE, szName);
		SetEvent(hEvent);

		_wsprintf(szName, SKIPLEN(countof(szName)) CEDEFAULTTERMHOOKOK, nRemotePID);
		hDefTermReady = CreateEvent(LocalSecurity(), FALSE, FALSE, szName);
		ResetEvent(hDefTermReady);
	}

	// Creating as remote thread.
	// Resetting this event notify ConEmuHk about
	// 1) need to determine MainThreadId
	// 2) need to start pipe server
	_wsprintf(szName, SKIPLEN(countof(szName)) CECONEMUROOTTHREAD, nRemotePID);
	hEvent = OpenEvent(EVENT_MODIFY_STATE|SYNCHRONIZE, FALSE, szName);
	if (hEvent)
	{
		ResetEvent(hEvent);
		CloseHandle(hEvent);
	}


	// Определить битность процесса, Если он 32битный, а текущий - ConEmuC64.exe
	// Перезапустить 32битную версию ConEmuC.exe
	nBits = GetProcessBits(nRemotePID, hProc);
	if (nBits == 0)
	{
		// Do not even expected, ConEmu GUI must run ConEmuC elevated if required.
		iRc = CIR_GetProcessBits/*-204*/;
		goto wrap;
	}

	is32bit = (nBits == 32);

	if (is32bit != WIN3264TEST(true,false))
	{
		// По идее, такого быть не должно. ConEmu должен был запустить соответствующий conemuC*.exe
		_ASSERTE(is32bit == WIN3264TEST(true,false));
		PROCESS_INFORMATION pi = {};
		STARTUPINFO si = {sizeof(si)};

		_wcscpy_c(pszNamePtr, 16, is32bit ? L"ConEmuC.exe" : L"ConEmuC64.exe");
		_wsprintf(szArgs, SKIPLEN(countof(szArgs)) L" /INJECT=%u", nRemotePID);

		if (!CreateProcess(szHooks, szArgs, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
		{
			iRc = CIR_CreateProcess/*-202*/;
			goto wrap;
		}
		nWrapperWait = WaitForSingleObject(pi.hProcess, INFINITE);
		GetExitCodeProcess(pi.hProcess, &nWrapperResult);
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		if ((nWrapperResult != CERR_HOOKS_WAS_SET) && (nWrapperResult != CERR_HOOKS_WAS_ALREADY_SET))
		{
			iRc = CIR_WrapperResult/*-203*/;
			SetLastError(nWrapperResult);
			goto wrap;
		}
		// Значит всю работу сделал враппер
		iRc = CIR_OK/*0*/;
		goto wrap;
	}

	// Поехали
	_wcscpy_c(pszNamePtr, 16, is32bit ? L"ConEmuHk.dll" : L"ConEmuHk64.dll");
	if (!FileExists(szHooks))
	{
		iRc = CIR_ConEmuHkNotFound/*-250*/;
		goto wrap;
	}

	if (abDefTermOnly)
	{
		CINFILTRATE_EXIT_CODES iFRc = PrepareHookModule(szHooks);
		if (iFRc != 0)
		{
			iRc = iFRc;
			goto wrap;
		}
	}

	iRc = InfiltrateDll(hProc, ptrOuterKernel, szHooks);

	// Если создавали временную копию - запланировать ее удаление
	if (abDefTermOnly && (lstrcmpi(szHooks, szSelf) != 0))
	{
		MoveFileEx(szHooks, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
	}
wrap:
	if (hProc != NULL)
		CloseHandle(hProc);
	// But check the result of the operation

	//_ASSERTE(FALSE && "WaitForSingleObject(hDefTermReady)");

	if ((iRc == 0) && hDefTermReady)
	{
		_ASSERTE(abDefTermOnly);
		DWORD nWaitReady = WaitForSingleObject(hDefTermReady, CEDEFAULTTERMHOOKWAIT/*==0*/);
		if (nWaitReady == WAIT_TIMEOUT)
		{
			iRc = CIR_DefTermWaitingFailed/*-300*/; // Failed to start hooking thread in remote process
		}
	}
	return iRc;
}
Beispiel #17
0
void ConEmuUpdateSettings::ResetToDefaults()
{
	// Указатели должны быть освобождены перед вызовом
	_ASSERTE(szUpdateExeCmdLine==NULL);

	szUpdateVerLocation = NULL;
	isUpdateCheckOnStartup = false;
	isUpdateCheckHourly = false;
	isUpdateConfirmDownload = true; // true-Show MessageBox, false-notify via TSA only
	isUpdateUseBuilds = 0; // 0-спросить пользователя при первом запуске, 1-stable only, 2-latest
	isUpdateUseProxy = false;
	szUpdateProxy = szUpdateProxyUser = szUpdateProxyPassword = NULL; // "Server:port"
	// Проверяем, была ли программа установлена через ConEmuSetup.exe?
	isUpdateDownloadSetup = 0; // 0-Auto, 1-Installer (ConEmuSetup.exe), 2-7z archieve (ConEmu.7z), WinRar or 7z required
	isSetupDetected = 0; // 0-пока не проверялся, 1-установлено через Installer, пути совпали, 2-Installer не запускался

	szUpdateExeCmdLineDef = lstrdup(L"\"%1\" /p:%3 /qr");
	SafeFree(szUpdateExeCmdLine);

	bool bWinRar = false;
	wchar_t* pszArcPath = NULL; BOOL bWin64 = IsWindows64();
	for (int i = 0; !(pszArcPath && *pszArcPath) && (i <= 5); i++)
	{
		SettingsRegistry regArc;
		switch (i)
		{
		case 0:
			if (regArc.OpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\7-Zip", KEY_READ|(bWin64?KEY_WOW64_32KEY:0)))
			{
				regArc.Load(L"Path", &pszArcPath);
			}
			break;
		case 1:
			if (bWin64 && regArc.OpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\7-Zip", KEY_READ|KEY_WOW64_64KEY))
			{
				regArc.Load(L"Path", &pszArcPath);
			}
			break;
		case 2:
			if (regArc.OpenKey(HKEY_CURRENT_USER, L"SOFTWARE\\7-Zip", KEY_READ))
			{
				regArc.Load(L"Path", &pszArcPath);
			}
			break;
		case 3:
			if (regArc.OpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\WinRAR", KEY_READ|(bWin64?KEY_WOW64_32KEY:0)))
			{
				bWinRar = true;
				regArc.Load(L"exe32", &pszArcPath);
			}
			break;
		case 4:
			if (bWin64 && regArc.OpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\WinRAR", KEY_READ|KEY_WOW64_64KEY))
			{
				bWinRar = true;
				regArc.Load(L"exe64", &pszArcPath);
			}
			break;
		case 5:
			if (regArc.OpenKey(HKEY_CURRENT_USER, L"SOFTWARE\\WinRAR", KEY_READ))
			{
				bWinRar = true;
				if (!regArc.Load(L"exe32", &pszArcPath) && bWin64)
				{
					regArc.Load(L"exe64", &pszArcPath);
				}
			}
			break;
		}
	}
	if (!pszArcPath || !*pszArcPath)
	{
		szUpdateArcCmdLineDef = lstrdup(L"\"%ProgramFiles%\\7-Zip\\7zg.exe\" x -y \"%1\""); // "%1"-archive file, "%2"-ConEmu base dir
	}
	else
	{
		LPCWSTR pszExt = PointToExt(pszArcPath);
		int cchMax = lstrlen(pszArcPath)+64;
		szUpdateArcCmdLineDef = (wchar_t*)malloc(cchMax*sizeof(wchar_t));
		if (szUpdateArcCmdLineDef)
		{
			if (pszExt && lstrcmpi(pszExt, L".exe") == 0)
			{
				_ASSERTE(bWinRar==true);
				//Issue 537: old WinRAR beta's fails
				//_wsprintf(szUpdateArcCmdLineDef, SKIPLEN(cchMax) L"\"%s\" x -y \"%%1\"%s", pszArcPath, bWinRar ? L" \"%%2\\\"" : L"");
				_wsprintf(szUpdateArcCmdLineDef, SKIPLEN(cchMax) L"\"%s\" x -y \"%%1\"", pszArcPath);
			}
			else
			{
				_ASSERTE(bWinRar==false);
				int nLen = lstrlen(pszArcPath);
				bool bNeedSlash = (*pszArcPath && (pszArcPath[nLen-1] != L'\\')) ? true : false;
				_wsprintf(szUpdateArcCmdLineDef, SKIPLEN(cchMax) L"\"%s%s7zg.exe\" x -y \"%%1\"", pszArcPath, bNeedSlash ? L"\\" : L"");
			}
		}
	}
	SafeFree(pszArcPath);
	SafeFree(szUpdateArcCmdLine);

	szUpdateDownloadPath = lstrdup(L"%TEMP%\\ConEmu");
	isUpdateLeavePackages = false;
	szUpdatePostUpdateCmd = lstrdup(L"echo Last successful update>ConEmuUpdate.info && date /t>>ConEmuUpdate.info && time /t>>ConEmuUpdate.info"); // Юзер может чего-то свое делать с распакованными файлами
}
Beispiel #18
0
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
#endif
{
	hInst = hInstance;
	isWin64 = IsWindows64();
	
	GetVersionEx(&gOSVer);
	
	int nInstallVer = 0;
	
	wsprintf(gsTitle, L"ConEmu %s installer", CONEMUVERL);
	lstrcpyn(gsRunAsAdm, L"Run installer as administrator", countof(gsRunAsAdm));

	wchar_t szArg[MAX_PATH+1];
	LPCWSTR pszCmdToken = GetCommandLine();
	LPCWSTR pszCmdLineW = pszCmdToken;
	
	gsTempFolder[0] = 0;
	
	while (0 == NextArg(&pszCmdToken, szArg))
	{
		if (lstrcmp(szArg, L"/?") == 0 || lstrcmp(szArg, L"-?") == 0)
		{
			MessageBox(NULL, L"Usage:\nConEmuSetup [/e[:<extract path>]] [/p:x86 | /p:x64] [<msi args>]", gsTitle, MB_ICONINFORMATION);
			return 1;
		}
		
		if (*szArg == L'/')
		{
			if (szArg[1] == L'e' || szArg[1] == L'E')
			{
				gbExtractOnly = true;
				if (szArg[2] == L':' && szArg[3])
				{
					lstrcpyn(gsTempFolder, (szArg[3]==L'"') ? (szArg+4) : (szArg+3), countof(gsTempFolder));
				}
				continue;
			}
		
			if (lstrcmpi(szArg, L"/p:x86") == 0)
				nInstallVer = Ver86;
			else if (lstrcmpi(szArg, L"/p:x64") == 0)
				nInstallVer = Ver64;
			else
				pszCmdToken = pszCmdLineW;
			break;
		}
		else if (*szArg == L'-')
		{
			pszCmdToken = pszCmdLineW;
			break;
		}
			
		pszCmdLineW = pszCmdToken;
	}
	

	if (!gbExtractOnly)
	{
		wchar_t szInstallPath[MAX_PATH+32];
		bool bInstalled;
		HKEY hk;
	
		lstrcpyn(gsMessage, L"Choose version to install", countof(gsMessage));
		
			szInstallPath[0] = 0; bInstalled = false;
			struct {HKEY hk; LPCWSTR path; LPCWSTR name; bool our;}
				Keys[] = {
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\ConEmu",L"InstallDir",true},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far Manager",L"InstallDir"},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far2",L"InstallDir"},
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far",L"InstallDir"},
				};
			for (size_t s = 0; s < countof(Keys); s++)
			{
				if (!RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ, &hk)
					|| !RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ|KEY_WOW64_32KEY, &hk))
				{
					wchar_t szPath[MAX_PATH+1] = {}; DWORD cbSize = sizeof(szPath)-2;
					LONG lRc = RegQueryValueEx(hk, Keys[s].name, NULL, NULL, (LPBYTE)szPath, &cbSize);
					RegCloseKey(hk);
					if (!lRc && *szPath)
					{
						bInstalled = Keys[s].our;
						lstrcpy(szInstallPath, szPath);
						cbSize = lstrlen(szInstallPath);
						if (szInstallPath[cbSize-1] == L'\\') szInstallPath[cbSize-1] = 0;
						break;
					}
				}
			}
			if (szInstallPath[0] == 0)
			{
				GetEnvironmentVariable(L"ProgramFiles", szInstallPath, MAX_PATH);
				int nLen = lstrlen(szInstallPath);
				lstrcat(szInstallPath, (nLen > 0 && szInstallPath[nLen-1] != L'\\') ? L"\\ConEmu" : L"ConEmu");
			}
			wsprintf(gsVer86, L"%s x86\n%s installation folder is\n%s", CONEMUVERL, bInstalled ? L"Current" : L"Default", szInstallPath);

			
		if (isWin64)
		{
			
				szInstallPath[0] = 0; bInstalled = false;
				struct {HKEY hk; LPCWSTR path; LPCWSTR name; bool our;}
					Keys[] = {
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\ConEmu",L"InstallDir_x64",true},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far Manager",L"InstallDir_x64"},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far2",L"InstallDir_x64"},
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far",L"InstallDir_x64"},
					};
				for (size_t s = 0; s < countof(Keys); s++)
				{
					if (!RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ|KEY_WOW64_64KEY, &hk))
					{
						wchar_t szPath[MAX_PATH+1] = {}; DWORD cbSize = sizeof(szPath)-2;
						LONG lRc = RegQueryValueEx(hk, Keys[s].name, NULL, NULL, (LPBYTE)szPath, &cbSize);
						RegCloseKey(hk);
						if (!lRc && *szPath)
						{
							bInstalled = Keys[s].our;
							lstrcpy(szInstallPath, szPath);
							cbSize = lstrlen(szInstallPath);
							if (szInstallPath[cbSize-1] == L'\\') szInstallPath[cbSize-1] = 0;
							break;
						}
					}
				}
				if (szInstallPath[0] == 0)
				{
					GetEnvironmentVariable(L"ProgramW6432", szInstallPath, MAX_PATH);
					int nLen = lstrlen(szInstallPath);
					lstrcat(szInstallPath, (nLen > 0 && szInstallPath[nLen-1] != L'\\') ? L"\\ConEmu" : L"ConEmu");
				}
				wsprintf(gsVer64, L"%s x64\n%s installation folder is\n%s", CONEMUVERL, bInstalled ? L"Current" : L"Default", szInstallPath);

			wsprintf(gsFull, L"%s\n\nPress `Yes` to install x64 version\nPress `No` to install x86 version", gsMessage);
		}
		else
		{
			gsVer64[0] = 0;
		}
	}
	else
	{
		wchar_t szPath[MAX_PATH+1];
		if (*gsTempFolder)
		{
			lstrcpy(szPath, gsTempFolder);
		}
		else
		{
			GetTempPath(countof(szPath) - 14, szPath);
			wchar_t* pszSubDir = szPath+lstrlen(szPath);
			lstrcpy(pszSubDir, L"ConEmu");
			pszSubDir += 6;
			lstrcpy(pszSubDir, CONEMUVERL);
		}
		
		lstrcpyn(gsMessage, L"Choose version to extract", countof(gsMessage));
		wsprintf(gsVer86, L"%s x86\nExtract installation files to\n%s", CONEMUVERL, szPath);
		wsprintf(gsVer64, L"%s x64\nExtract installation files to\n%s", CONEMUVERL, szPath);
		wsprintf(gsFull, L"%s\n\nPress `Yes` to extract x64 version\nPress `No` to extract x86 version\n\n%s", gsMessage, szPath);
	}
	
	if (nInstallVer == 0)
		nInstallVer = ChooseVersion(); // IDCANCEL/Ver86/Ver64
		
	if (nInstallVer != Ver86 && nInstallVer != Ver64)
		return 1;
	
	if (gbExtractOnly && *gsTempFolder)
	{
		CreateDirectory(gsTempFolder, NULL);
	}
	else
	{
		GetTempPath(countof(gsTempFolder) - 14, gsTempFolder);
		
		wchar_t* pszSubDir = gsTempFolder+lstrlen(gsTempFolder);
		lstrcpy(pszSubDir, L"ConEmu");
		pszSubDir += 6;
		lstrcpy(pszSubDir, CONEMUVERL);
		pszSubDir += lstrlen(pszSubDir);
		if (!CreateDirectory(gsTempFolder, NULL))
		{
			bool lbCreated = false;
			SYSTEMTIME st = {}; GetLocalTime(&st);
			for (int i = 0; i < 100; i++)
			{
				wsprintf(pszSubDir, L"_%02i%02i%02i%i", st.wHour, st.wMinute, st.wSecond, i);
				if (CreateDirectory(gsTempFolder, NULL))
				{
					lbCreated = true;
					break;
				}
			}
			if (!lbCreated)
			{
				return ReportError(10, L"Can't create temp folder\n%s", gsTempFolder);
			}
		}
	}

	wsprintf(gsMsiFile, L"%s\\ConEmu.%s.%s.msi", gsTempFolder, CONEMUVERL, (nInstallVer == Ver86) ? L"x86" : L"x64");
	wsprintf(gsCabFile, L"%s\\ConEmu.cab", gsTempFolder);
	
	bool lbNeedExe = false;
	if (!gbExtractOnly && gOSVer.dwMajorVersion >= 6)
		lbNeedExe = true;

	if (!lbNeedExe)
		gsExeFile[0] = 0;
	else
		wsprintf(gsExeFile, L"%s\\ConEmuSetup.exe", gsTempFolder);
	
	int iExpMsi = ExportFile(nInstallVer, gsMsiFile);
	int iExpCab = (iExpMsi == 0) ? ExportFile(CABFILE, gsCabFile) : -1;
	int iExpExe = (!lbNeedExe) ? 0 : (iExpCab == 0) ? ExportFile(EXEFILE, gsExeFile) : -1;
	if (iExpMsi != 0 || iExpCab != 0 || iExpExe != 0)
	{
		DeleteFile(gsMsiFile);
		DeleteFile(gsCabFile);
		if (*gsExeFile)
			DeleteFile(gsExeFile);
		RemoveDirectory(gsTempFolder);
		return (iExpMsi != 0) ? iExpMsi : iExpCab;
	}
	
	if (gbExtractOnly)
	{
		wchar_t szMessage[MAX_PATH*2];
		wsprintf(szMessage, L"Installation files was extracted successfully\n%s", gsTempFolder);
		MessageBox(NULL, szMessage, gsTitle, MB_ICONINFORMATION);
		return 0;
	}

	int iInstRc = 0;
	SHELLEXECUTEINFO sei = {sizeof(sei)};
	wchar_t* pszParms = NULL;
	sei.fMask = SEE_MASK_NOCLOSEPROCESS|/*SEE_MASK_NOASYNC*/0x00000100; //|/*SEE_MASK_NOZONECHECKS*/0x00800000;
	sei.lpVerb = L"open";
	if (gOSVer.dwMajorVersion<=5 || !gbUseElevation)
	{
		sei.lpFile = gsMsiFile;
		sei.lpParameters = pszCmdToken;
	}
	else
	{
		sei.lpFile = gsExeFile;
		int nMaxLen = lstrlen(gsMsiFile) + (pszCmdToken ? lstrlen(pszCmdToken) : 0) + 64;
		pszParms = (wchar_t*)malloc(nMaxLen*sizeof(wchar_t));
		wsprintf(pszParms, L"/i \"%s\" %s", gsMsiFile, pszCmdToken ? pszCmdToken : L"");
		sei.lpParameters = pszParms;
	}
	sei.lpDirectory = gsTempFolder;
	sei.nShow = SW_SHOWNORMAL;
	
	BOOL lbExecute = ShellExecuteEx(&sei);
	
	#if 0
	if (!lbExecute && lbNeedExe)
	{
		DWORD nErr = GetLastError();
		if (nErr == 1223)
		{
			// Отмена пользователем UAC, или правов не хватило?
			sei.fMask = SEE_MASK_NOCLOSEPROCESS|/*SEE_MASK_NOASYNC*/0x00000100; //|/*SEE_MASK_NOZONECHECKS*/0x00800000;
			sei.lpVerb = L"open";
			sei.lpFile = gsMsiFile;
			sei.lpParameters = pszCmdToken;
			sei.lpDirectory = gsTempFolder;
			sei.nShow = SW_SHOWNORMAL;
			
			lbExecute = ShellExecuteEx(&sei);
		}
	}
	#endif
	
	if (!lbExecute)
	{
		iInstRc = ReportError(20, L"Installer failed\n%s", gsMsiFile);
	}
	else
	{
		if (!sei.hProcess)
		{
			iInstRc = ReportError(21, L"Installer failed\n%s", gsMsiFile);
		}
		else
		{
			WaitForSingleObject(sei.hProcess, INFINITE);
			DWORD nCode = 0;
			SetLastError(0);
			//1602 - это похоже "Отмена" пользователем
			if (!GetExitCodeProcess(sei.hProcess, &nCode) || (nCode != 0 && nCode != 1602))
			{
				wchar_t szFormat[128]; wsprintf(szFormat, L"Installer failed\n%%s\nExitCode=%u", nCode);
				iInstRc = ReportError(100+nCode, szFormat, gsMsiFile);
			}
		}
	}
	
	DeleteFile(gsMsiFile);
	DeleteFile(gsCabFile);
	if (*gsExeFile)
		DeleteFile(gsExeFile);
	RemoveDirectory(gsTempFolder);
	
	return iInstRc;
}
Beispiel #19
0
// Returns true, if application was found in registry:
// [HKCU|HKLM]\Software\Microsoft\Windows\CurrentVersion\App Paths
// Also, function may change local process %PATH% variable
bool SearchAppPaths(LPCWSTR asFilePath, CmdArg& rsFound, bool abSetPath, CmdArg* rpsPathRestore /*= NULL*/)
{
	if (rpsPathRestore)
		rpsPathRestore->Empty();

	if (!asFilePath || !*asFilePath)
		return false;

	LPCWSTR pszSearchFile = PointToName(asFilePath);
	LPCWSTR pszExt = PointToExt(pszSearchFile);

	// Lets try find it in "App Paths"
	// "HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\"
	// "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\"
	LPCWSTR pszRoot = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";
	HKEY hk; LONG lRc;
	CmdArg lsName; lsName.Attach(lstrmerge(pszRoot, pszSearchFile, pszExt ? NULL : L".exe"));
	// Seems like 32-bit and 64-bit registry branches are the same now, but just in case - will check both
	DWORD nWOW[2] = {WIN3264TEST(KEY_WOW64_32KEY,KEY_WOW64_64KEY), WIN3264TEST(KEY_WOW64_64KEY,KEY_WOW64_32KEY)};
	for (int i = 0; i < 3; i++)
	{
		bool bFound = false;
		DWORD nFlags = ((i && IsWindows64()) ? nWOW[i-1] : 0);
		if ((i == 2) && !nFlags)
			break; // This is 32-bit OS
		lRc = RegOpenKeyEx(i ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, lsName, 0, KEY_READ|nFlags, &hk);
		if (lRc != 0) continue;
		wchar_t szVal[MAX_PATH+1] = L"";
		DWORD nType, nSize = sizeof(szVal)-sizeof(szVal[0]);
		lRc = RegQueryValueEx(hk, NULL, NULL, &nType, (LPBYTE)szVal, &nSize);
		if (lRc == 0)
		{
			wchar_t *pszCheck = NULL;
			if (nType == REG_SZ)
			{
				pszCheck = szVal;
			}
			else if (nType == REG_EXPAND_SZ)
			{
				pszCheck = ExpandEnvStr(szVal);
			}
			// May be quoted
			if (pszCheck)
			{
				LPCWSTR pszPath = Unquote(pszCheck, true);
				if (FileExists(pszPath))
				{
					// asFilePath will be invalid after .Set
					rsFound.Set(pszPath);
					bFound = true;

					if (pszCheck != szVal)
						free(pszCheck);

					// The program may require additional "%PATH%". So, if allowed...
					if (abSetPath)
					{
						nSize = 0;
						lRc = RegQueryValueEx(hk, L"PATH", NULL, &nType, NULL, &nSize);
						if (lRc == 0 && nSize)
						{
							wchar_t* pszCurPath = GetEnvVar(L"PATH");
							wchar_t* pszAddPath = (wchar_t*)calloc(nSize+4,1);
							wchar_t* pszNewPath = NULL;
							if (pszAddPath)
							{
								lRc = RegQueryValueEx(hk, L"PATH", NULL, &nType, (LPBYTE)pszAddPath, &nSize);
								if (lRc == 0 && *pszAddPath)
								{
									// Если в "%PATH%" этого нет (в начале) - принудительно добавить
									int iCurLen = pszCurPath ? lstrlen(pszCurPath) : 0;
									int iAddLen = lstrlen(pszAddPath);
									bool bNeedAdd = true;
									if ((iCurLen >= iAddLen) && (pszCurPath[iAddLen] == L';' || pszCurPath[iAddLen] == 0))
									{
										wchar_t ch = pszCurPath[iAddLen]; pszCurPath[iAddLen] = 0;
										if (lstrcmpi(pszCurPath, pszAddPath) == 0)
											bNeedAdd = false;
										pszCurPath[iAddLen] = ch;
									}
									// Если пути еще нет
									if (bNeedAdd)
									{
										if (rpsPathRestore)
										{
											rpsPathRestore->SavePathVar(pszCurPath);
										}
										pszNewPath = lstrmerge(pszAddPath, L";", pszCurPath);
										if (pszNewPath)
										{
											SetEnvironmentVariable(L"PATH", pszNewPath);
										}
										else
										{
											_ASSERTE(pszNewPath!=NULL && "Allocation failed?");
										}
									}
								}
							}
							SafeFree(pszAddPath);
							SafeFree(pszCurPath);
							SafeFree(pszNewPath);
						}
					}
				}
			}
		}
		RegCloseKey(hk);

		if (bFound)
			return true;
	}

	return false;
}
Beispiel #20
0
void UpdateComspec(ConEmuComspec* pOpt, bool DontModifyPath /*= false*/)
{
	if (!pOpt)
	{
		_ASSERTE(pOpt!=NULL);
		return;
	}

	if (pOpt->isUpdateEnv && (pOpt->csType != cst_EnvVar))
	{
		//if (pOpt->csType == cst_AutoTccCmd) -- always, if isUpdateEnv
		{
			LPCWSTR pszNew = NULL;
			switch (pOpt->csBits)
			{
			case csb_SameOS:
				pszNew = IsWindows64() ? pOpt->Comspec64 : pOpt->Comspec32;
				break;
			case csb_SameApp:
				pszNew = WIN3264TEST(pOpt->Comspec32,pOpt->Comspec64);
				break;
			case csb_x32:
				pszNew = pOpt->Comspec32;
				break;
			default:
				_ASSERTE(pOpt->csBits==csb_SameOS || pOpt->csBits==csb_SameApp || pOpt->csBits==csb_x32);
				pszNew = NULL;
			}
			if (pszNew && *pszNew)
			{
				#ifdef SHOW_COMSPEC_CHANGE
				wchar_t szCurrent[MAX_PATH]; GetEnvironmentVariable(L"ComSpec", szCurrent, countof(szCurrent));
				if (lstrcmpi(szCurrent, pszNew))
				{
					wchar_t szMsg[MAX_PATH*4], szProc[MAX_PATH] = {}, szPid[MAX_PATH];
					GetModuleFileName(NULL, szProc, countof(szProc));
					_wsprintf(szPid, SKIPLEN(countof(szPid))
						L"PID=%u, '%s'", GetCurrentProcessId(), PointToName(szProc));
					_wsprintf(szMsg, SKIPLEN(countof(szMsg))
						L"Changing %%ComSpec%% in %s\nCur=%s\nNew=%s",
						szPid , szCurrent, pszNew);
					MessageBox(NULL, szMsg, szPid, MB_SYSTEMMODAL);
				}
				#endif

				_ASSERTE(wcschr(pszNew, L'%')==NULL);
				SetEnvVarExpanded(L"ComSpec", pszNew);
			}
		}
	}

	if (pOpt->AddConEmu2Path && !DontModifyPath)
	{
		if ((pOpt->ConEmuBaseDir[0] == 0) || (pOpt->ConEmuExeDir[0] == 0))
		{
			_ASSERTE(pOpt->ConEmuBaseDir[0] != 0);
			_ASSERTE(pOpt->ConEmuExeDir[0] != 0);
		}
		else
		{
			wchar_t* pszCur = GetEnvVar(L"PATH");

			if (!pszCur)
				pszCur = lstrdup(L"");

			DWORD n = lstrlen(pszCur);
			wchar_t* pszUpr = lstrdup(pszCur);
			wchar_t* pszDirUpr = (wchar_t*)malloc(MAX_PATH*sizeof(*pszCur));

			MCHKHEAP;

			if (!pszUpr || !pszDirUpr)
			{
				_ASSERTE(pszUpr && pszDirUpr);
			}
			else
			{
				bool bChanged = false;
				wchar_t* pszAdd = NULL;

				CharUpperBuff(pszUpr, n);

				for (int i = 0; i <= 1; i++)
				{
					// Put '%ConEmuExeDir' on first place
					switch (i)
					{
					case 1:
						if (!(pOpt->AddConEmu2Path & CEAP_AddConEmuExeDir))
							continue;
						pszAdd = pOpt->ConEmuExeDir;
						break;
					case 0:
						if (!(pOpt->AddConEmu2Path & CEAP_AddConEmuBaseDir))
							continue;
						if (lstrcmp(pOpt->ConEmuExeDir, pOpt->ConEmuBaseDir) == 0)
							continue; // второй раз ту же директорию не добавляем
						pszAdd = pOpt->ConEmuBaseDir;
						break;
					}

					int nDirLen = lstrlen(pszAdd);
					lstrcpyn(pszDirUpr, pszAdd, MAX_PATH);
					CharUpperBuff(pszDirUpr, nDirLen);

					MCHKHEAP;

					// Need to find exact match!
					bool bFound = false;

					LPCWSTR pszFind = wcsstr(pszUpr, pszDirUpr);
					while (pszFind)
					{
						if (pszFind[nDirLen] == L';' || pszFind[nDirLen] == 0)
						{
							// OK, found
							bFound = true;
							break;
						}
						// Next try (may be partial match of subdirs...)
						pszFind = wcsstr(pszFind+nDirLen, pszDirUpr);
					}

					if (!bFound)
					{
						wchar_t* pszNew = lstrmerge(pszAdd, L";", pszCur);
						if (!pszNew)
						{
							_ASSERTE(pszNew && "Failed to reallocate PATH variable");
							break;
						}
						MCHKHEAP;
						SafeFree(pszCur);
						pszCur = pszNew;
						bChanged = true; // Set flag, check next dir
					}
				}

				MCHKHEAP;

				if (bChanged)
				{
					SetEnvironmentVariable(L"PATH", pszCur);
				}
			}

			MCHKHEAP;

			SafeFree(pszUpr);
			SafeFree(pszDirUpr);

			MCHKHEAP;
			SafeFree(pszCur);
		}
	}
}
Beispiel #21
0
int InjectRemote(DWORD nRemotePID, bool abDefTermOnly /*= false */)
{
	int iRc = -1;
	bool lbWin64 = WIN3264TEST((IsWindows64()!=0),true);
	bool is32bit;
	DWORD nWrapperWait = (DWORD)-1, nWrapperResult = (DWORD)-1;
	HANDLE hProc = NULL;
	wchar_t szSelf[MAX_PATH+16], szHooks[MAX_PATH+16];
	wchar_t *pszNamePtr, szArgs[32];

	if (!GetModuleFileName(NULL, szSelf, MAX_PATH))
	{
		iRc = -200;
		goto wrap;
	}
	wcscpy_c(szHooks, szSelf);
	pszNamePtr = (wchar_t*)PointToName(szHooks);
	if (!pszNamePtr)
	{
		iRc = -200;
		goto wrap;
	}

	hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, nRemotePID);
	if (hProc == NULL)
	{
		iRc = -201;
		goto wrap;
	}

	// Определить битность процесса, Если он 32битный, а текущий - ConEmuC64.exe
	// Перезапустить 32битную версию ConEmuC.exe
	if (!lbWin64)
	{
		is32bit = true; // x86 OS!
	}
	else
	{
		is32bit = false; // x64 OS!

		// Проверяем, кто такой nRemotePID
		HMODULE hKernel = GetModuleHandleW(L"kernel32.dll");

		if (hKernel)
		{
			typedef BOOL (WINAPI* IsWow64Process_t)(HANDLE hProcess, PBOOL Wow64Process);
			IsWow64Process_t IsWow64Process_f = (IsWow64Process_t)GetProcAddress(hKernel, "IsWow64Process");

			if (IsWow64Process_f)
			{
				BOOL bWow64 = FALSE;

				if (IsWow64Process_f(hProc, &bWow64) && bWow64)
				{
					// По идее, такого быть не должно. ConEmu должен был запустить 32битный conemuC.exe
					#ifdef _WIN64
					_ASSERTE(bWow64==FALSE);
					#endif
					is32bit = true;
				}
			}
		}
	}

	if (is32bit != WIN3264TEST(true,false))
	{
		// По идее, такого быть не должно. ConEmu должен был запустить соответствующий conemuC*.exe
		_ASSERTE(is32bit == WIN3264TEST(true,false));
		PROCESS_INFORMATION pi = {};
		STARTUPINFO si = {sizeof(si)};

		_wcscpy_c(pszNamePtr, 16, is32bit ? L"ConEmuC.exe" : L"ConEmuC64.exe");
		_wsprintf(szArgs, SKIPLEN(countof(szArgs)) L" /INJECT=%u", nRemotePID);

		if (!CreateProcess(szHooks, szArgs, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
		{
			iRc = -202;
			goto wrap;
		}
		nWrapperWait = WaitForSingleObject(pi.hProcess, INFINITE);
		GetExitCodeProcess(pi.hProcess, &nWrapperResult);
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		if ((nWrapperResult != CERR_HOOKS_WAS_SET) && (nWrapperResult != CERR_HOOKS_WAS_ALREADY_SET))
		{
			iRc = -203;
			SetLastError(nWrapperResult);
			goto wrap;
		}
		// Значит всю работу сделал враппер
		iRc = 0;
		goto wrap;
	}

	// Поехали
	_wcscpy_c(pszNamePtr, 16, is32bit ? L"ConEmuHk.dll" : L"ConEmuHk64.dll");
	if (!FileExists(szHooks))
	{
		iRc = -250;
		goto wrap;
	}

	if (abDefTermOnly)
	{
		int iFRc = PrepareHookModule(szHooks);
		if (iFRc != 0)
		{
			iRc = iFRc;
			goto wrap;
		}
	}

	iRc = InfiltrateDll(hProc, szHooks);

	// Если создавали временную копию - запланировать ее удаление
	if (abDefTermOnly && (lstrcmpi(szHooks, szSelf) != 0))
	{
		MoveFileEx(szHooks, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
	}
wrap:
	if (hProc != NULL)
		CloseHandle(hProc);
	return iRc;
}
Beispiel #22
0
bool CAttachDlg::CanAttachWindow(HWND hFind, DWORD nSkipPID, CProcessData* apProcessData, CAttachDlg::AttachWndInfo& Info)
{
	static bool bIsWin64 = IsWindows64();

	ZeroStruct(Info);

	DWORD_PTR nStyle = GetWindowLongPtr(hFind, GWL_STYLE);
	DWORD_PTR nStyleEx = GetWindowLongPtr(hFind, GWL_EXSTYLE);
	if (!GetWindowThreadProcessId(hFind, &Info.nPID))
		Info.nPID = 0;

	if (!Info.nPID)
		return false;

	bool lbCan = ((nStyle & (WS_VISIBLE/*|WS_CAPTION|WS_MAXIMIZEBOX*/)) == (WS_VISIBLE/*|WS_CAPTION|WS_MAXIMIZEBOX*/));
	if (lbCan)
	{
		// Более тщательно стили проверить
		lbCan = ((nStyle & WS_MAXIMIZEBOX) == WS_MAXIMIZEBOX) || ((nStyle & WS_THICKFRAME) == WS_THICKFRAME);
	}
	if (lbCan && Info.nPID == GetCurrentProcessId())
		lbCan = false;
	if (lbCan && Info.nPID == nSkipPID)
		lbCan = false;
	if (lbCan && (nStyle & WS_CHILD))
		lbCan = false;
	if (lbCan && (nStyleEx & WS_EX_TOOLWINDOW))
		lbCan = false;
	if (lbCan && gpConEmu->isOurConsoleWindow(hFind))
		lbCan = false;
	if (lbCan && gpConEmu->mp_Inside && (hFind == gpConEmu->mp_Inside->mh_InsideParentRoot))
		lbCan = false;

	GetClassName(hFind, Info.szClass, countof(Info.szClass));
	GetWindowText(hFind, Info.szTitle, countof(Info.szTitle));

	if (gpSetCls->isAdvLogging)
	{
		wchar_t szLogInfo[MAX_PATH*3];
		_wsprintf(szLogInfo, SKIPLEN(countof(szLogInfo)) L"Attach:%s x%08X/x%08X/x%08X {%s} \"%s\"", Info.szExeName, LODWORD(hFind), nStyle, nStyleEx, Info.szClass, Info.szTitle);
		CVConGroup::LogString(szLogInfo);
	}

	if (!lbCan)
		return false;

	_wsprintf(Info.szPid, SKIPLEN(countof(Info.szPid)) L"%u", Info.nPID);
	const wchar_t sz32bit[] = L" [32]";
	const wchar_t sz64bit[] = L" [64]";

	HANDLE h;
	DEBUGTEST(DWORD nErr);
	bool lbExeFound = false;

	if (apProcessData)
	{
		lbExeFound = apProcessData->GetProcessName(Info.nPID, Info.szExeName, countof(Info.szExeName), Info.szExePathName, countof(Info.szExePathName), &Info.nImageBits);
		if (lbExeFound)
		{
			//ListView_SetItemText(hList, nItem, alc_File, szExeName);
			//ListView_SetItemText(hList, nItem, alc_Path, szExePathName);
			if (bIsWin64 && Info.nImageBits)
			{
				wcscat_c(Info.szPid, (Info.nImageBits == 64) ? sz64bit : sz32bit);
			}
		}
	}

	if (!lbExeFound)
	{
		Info.nImageBits = GetProcessBits(Info.nPID);
		if (bIsWin64 && Info.nImageBits)
		{
			wcscat_c(Info.szPid, (Info.nImageBits == 64) ? sz64bit : sz32bit);
		}

		h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Info.nPID);
		if (h && h != INVALID_HANDLE_VALUE)
		{
			MODULEENTRY32 mi = {sizeof(mi)};
			if (Module32First(h, &mi))
			{
				lstrcpyn(Info.szExeName, *mi.szModule ? mi.szModule : (wchar_t*)PointToName(mi.szExePath), countof(Info.szExeName));
				lstrcpyn(Info.szExePathName, mi.szExePath, countof(Info.szExePathName));
				lbExeFound = true;
			}
			else
			{
				if (bIsWin64)
				{
					wcscat_c(Info.szPid, sz64bit);
				}
			}
			CloseHandle(h);
		}
		else
		{
			#ifdef _DEBUG
			nErr = GetLastError();
			_ASSERTE(nErr == 5 || (nErr == 299 && Info.nImageBits == 64));
			#endif
			wcscpy_c(Info.szExeName, L"???");
		}

		#if 0 //#ifdef _WIN64 -- no need to call TH32CS_SNAPMODULE32, simple TH32CS_SNAPMODULE will handle both if it can
		if (!lbExeFound)
		{
			h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32, Info.nPID);
			if (h && h != INVALID_HANDLE_VALUE)
			{
				MODULEENTRY32 mi = {sizeof(mi)};
				if (Module32First(h, &mi))
				{
					//ListView_SetItemText(hList, nItem, alc_File, *mi.szModule ? mi.szModule : (wchar_t*)PointToName(mi.szExePath));
					lstrcpyn(Info.szExeName, *mi.szModule ? mi.szModule : (wchar_t*)PointToName(mi.szExePath), countof(Info.szExeName));
					//ListView_SetItemText(hList, nItem, alc_Path, mi.szExePath);
					lstrcpyn(Info.szExePathName, mi.szExePath, countof(Info.szExePathName));
				}
				CloseHandle(h);
			}
		}
		#endif
	}

	if (!lbExeFound)
	{
		// Так можно получить только имя файла процесса
		PROCESSENTRY32 pi = {sizeof(pi)};
		h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		if (h && h != INVALID_HANDLE_VALUE)
		{
			if (Process32First(h, &pi))
			{
				do
				{
					if (pi.th32ProcessID == Info.nPID)
					{
						lstrcpyn(Info.szExeName, pi.szExeFile, countof(Info.szExeName));
						break;
					}
				} while (Process32Next(h, &pi));
			}
		}
	}

	wcscpy_c(Info.szType, isConsoleClass(Info.szClass) ? szTypeCon : szTypeGui);
	return true;
}
Beispiel #23
0
// 0 - SUCCEEDED, otherwise - error code
int WINAPI MountVirtualHive(LPCWSTR asHive, PHKEY phKey, LPCWSTR asXPMountName, wchar_t* pszErrInfo, int cchErrInfoMax, BOOL* pbKeyMounted)
{
	int lRc = -1;
	
	if (pszErrInfo && cchErrInfoMax)
		*pszErrInfo = 0; // если передали буфер для ошибки - сразу его почистить

	*pbKeyMounted = FALSE;

	OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)};
	GetVersionEx(&osv);
	HMODULE hAdvapi32 = LoadLibrary(L"advapi32.dll");
	//LPCWSTR pszKeyName = NULL;
	LPCWSTR ppszKeys[] =
	{
		L"HKCU",
		L"HKCU\\Software",
		L"HKLM",
		L"HKLM\\Software",
		L"HKLM64",
		L"HKLM64\\Software"
	};
	size_t nRootKeys = IsWindows64() ? countof(ppszKeys) : (countof(ppszKeys) - 2);

	if (!hAdvapi32)
	{
		if (pszErrInfo && cchErrInfoMax)
			msprintf(pszErrInfo, cchErrInfoMax,
				L"LoadLibrary(advapi32.dll) failed, code=0x%08X!\n", GetLastError());
		lRc = -2;
		goto wrap;
	}
	
	if (osv.dwMajorVersion >= 6)
	{
		// Vista+
		typedef LONG (WINAPI* RegLoadAppKey_t)(LPCWSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions, DWORD Reserved);
		RegLoadAppKey_t RegLoadAppKey_f = (RegLoadAppKey_t)GetProcAddress(hAdvapi32, "RegLoadAppKeyW");
		if (!RegLoadAppKey_f)
		{
			if (pszErrInfo && cchErrInfoMax)
				msprintf(pszErrInfo, cchErrInfoMax,
					L"RegLoadAppKeyW not found, code=0x%08X!\n", GetLastError());
			lRc = -3;
			goto wrap;
		}
		else
		{
			if ((lRc = RegLoadAppKey_f(asHive, phKey, KEY_ALL_ACCESS, 0, 0)) != 0)
			{
				if ((lRc = RegLoadAppKey_f(asHive, phKey, KEY_READ, 0, 0)) != 0)
				{
					if (pszErrInfo && cchErrInfoMax)
						msprintf(pszErrInfo, cchErrInfoMax,
							L"RegLoadAppKey failed, code=0x%08X!", (DWORD)lRc);
					lRc = -4; //-V112
					goto wrap;
				}
			}
			*pbKeyMounted = TRUE;
		}
	}
	else if (!asXPMountName || !*asXPMountName)
	{
		lRc = -7;
		if (pszErrInfo && cchErrInfoMax)
			lstrcpyn(pszErrInfo, L"XPMountName is empty!", cchErrInfoMax);
		goto wrap;
	}
	else
	{
		CBackupPrivileges se;
		if (!se.BackupPrivilegesAcuire(TRUE))
		{
			if (pszErrInfo && cchErrInfoMax)
				msprintf(pszErrInfo, cchErrInfoMax,
					L"Aquiring SE_BACKUP_NAME/SE_RESTORE_NAME failed, code=0x%08X!\nYou must be Administrator or Backup operator", GetLastError());
			lRc = -5;
			goto wrap;
		}
		
		//_wcscpy_c(rsXPMountName, cchXPMountMax, VIRTUAL_REGISTRY_GUID);
		//WARNING("###: Докинуть в конец что-нть уникальное, например CRC пути к hive");
		
		// Hive уже мог быть подключен другой копией ConEmu.
		TODO("При выходе - может возникнуть конфликт? Кто первый сделает RegUnloadKey...");
		
		if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_ALL_ACCESS, phKey)) == 0)
		{
			goto wrap; // успешно - hive уже подключен
		}
		else if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_READ, phKey)) == 0)
		{
			goto wrap; // успешно - hive уже подключен (ReadOnly)
		}
		
		// Hive еще не был подключен
		if ((lRc = RegLoadKey(HKEY_USERS, asXPMountName, asHive)) != 0)
		{
			if (pszErrInfo && cchErrInfoMax)
				msprintf(pszErrInfo, cchErrInfoMax,
					L"RegLoadKey failed, code=0x%08X!", (DWORD)lRc);
			lRc = -6;
			goto wrap;
		}
		// Ключ смонтирован, нужно его будет демонтировать при выходе
		*pbKeyMounted = TRUE;

		if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_ALL_ACCESS, phKey)) == 0)
		{
			goto wrap; // успешно - hive уже подключен
		}
		else if ((lRc = RegOpenKeyEx(HKEY_USERS, asXPMountName, 0, KEY_READ, phKey)) == 0)
		{
			goto wrap; // успешно - hive уже подключен (ReadOnly)
		}
	}
	
	// Нужно проверить, можно ли создать/открыть необходимые ключи
	for (UINT i = 0; i < nRootKeys; i++)
	{
		HKEY hTest = NULL;
		LPCWSTR pszKeyName = ppszKeys[i];
		lRc = RegCreateKeyEx(*phKey, pszKeyName, 0,0,0, KEY_ALL_ACCESS, 0, &hTest, 0);
		if (lRc != 0)
			lRc = RegCreateKeyEx(*phKey, pszKeyName, 0,0,0, KEY_READ, 0, &hTest, 0);
		if (lRc != 0)
		{
			if (pszErrInfo && cchErrInfoMax)
				msprintf(pszErrInfo, cchErrInfoMax,
					L"RegCreateKeyEx(%s) failed, code=0x%08X!", pszKeyName, (DWORD)lRc);
			RegCloseKey(*phKey);
			*phKey = NULL;
			if (asXPMountName && *asXPMountName)
				UnMountVirtualHive(asXPMountName, NULL, 0);
			lRc = -8;
			goto wrap;
		}
	}

wrap:
	if (hAdvapi32)
		FreeLibrary(hAdvapi32); // Decrease counter
	return lRc;
}
Beispiel #24
0
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
#endif
{
	hInst = hInstance;
	isWin64 = IsWindows64();

	GetVersionEx(&gOSVer);

	int nInstallVer = 0;

	wsprintf(gsTitle, msgConEmuInstaller, CONEMUVERL);
	lstrcpyn(gsRunAsAdm, msgRunSetupAsAdmin, countof(gsRunAsAdm));

	wchar_t szArg[MAX_PATH+1];
	LPCWSTR pszCmdToken = GetCommandLine();
	LPCWSTR pszCmdLineW = pszCmdToken;

	CTempDir temp_dir; // gsTempFolder[0] = 0;

	while (0 == NextArg(&pszCmdToken, szArg))
	{
		if (lstrcmp(szArg, L"/?") == 0 || lstrcmp(szArg, L"-?") == 0 || lstrcmp(szArg, L"-h") == 0
			|| lstrcmp(szArg, L"-help") == 0 || lstrcmp(szArg, L"--help") == 0)
		{
			MessageBox(NULL, msgUsageExample, gsTitle, MB_ICONINFORMATION);
			return exit_Cancelled;
		}

		if (*szArg == L'/')
		{
			if (szArg[1] == L'e' || szArg[1] == L'E')
			{
				gbExtractOnly = true;
				if (szArg[2] == L':' && szArg[3])
				{
					lstrcpyn(gsTempFolder, (szArg[3]==L'"') ? (szArg+4) : (szArg+3), countof(gsTempFolder));
				}
				continue;
			}

		    if (memcmp(szArg, L"/p:x", 4*sizeof(*szArg)) == 0)
		    {
		    	gbAlreadyAdmin = IsUserAdmin();
				if (lstrcmpi(szArg+4, L"86") == 0)
				{
					nInstallVer = Ver86;
				}
				else if (lstrcmpi(szArg+4, L"86,adm") == 0)
				{
					nInstallVer = Ver86;
					gbUseElevation = !gbAlreadyAdmin;
				}
				else if (lstrcmpi(szArg+4, L"64") == 0)
				{
					nInstallVer = Ver64;
				}
				else if (lstrcmpi(szArg+4, L"64,adm") == 0)
				{
					nInstallVer = Ver64;
					gbUseElevation = !gbAlreadyAdmin;
				}
			}
			else
				pszCmdToken = pszCmdLineW;
			break;
		}
		else if (*szArg == L'-')
		{
			pszCmdToken = pszCmdLineW;
			break;
		}

		pszCmdLineW = pszCmdToken;
	}

	if (!temp_dir.Acquire())
	{
		return exit_CreateDirectory;
	}

	if (!gbExtractOnly)
	{
		// If pszCmdToken is not empty - set global var
		gbAutoMode = (pszCmdToken && *pszCmdToken);

		wchar_t szInstallPath[MAX_PATH+32];
		bool bInstalled;
		HKEY hk;

		lstrcpyn(gsMessage, msgChooseInstallVer, countof(gsMessage));

			szInstallPath[0] = 0; bInstalled = false;
			struct {HKEY hk; LPCWSTR path; LPCWSTR name; bool our;}
				Keys[] = {
					{HKEY_LOCAL_MACHINE,L"SOFTWARE\\ConEmu",L"InstallDir",true},
					//Current installer does not use FarManager installation dir anymore
					//{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far Manager",L"InstallDir"},
					//{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far2",L"InstallDir"},
					//{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far",L"InstallDir"},
				};
			for (size_t s = 0; s < countof(Keys); s++)
			{
				if (!RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ, &hk)
					|| !RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ|KEY_WOW64_32KEY, &hk))
				{
					wchar_t szPath[MAX_PATH+1] = {}; DWORD cbSize = sizeof(szPath)-2;
					LONG lRc = RegQueryValueEx(hk, Keys[s].name, NULL, NULL, (LPBYTE)szPath, &cbSize);
					RegCloseKey(hk);
					if (!lRc && *szPath)
					{
						bInstalled = Keys[s].our;
						lstrcpy(szInstallPath, szPath);
						cbSize = lstrlen(szInstallPath);
						if (szInstallPath[cbSize-1] == L'\\') szInstallPath[cbSize-1] = 0;
						break;
					}
				}
			}
			if (szInstallPath[0] == 0)
			{
				GetEnvironmentVariable(L"ProgramFiles", szInstallPath, MAX_PATH);
				int nLen = lstrlen(szInstallPath);
				lstrcat(szInstallPath, (nLen > 0 && szInstallPath[nLen-1] != L'\\') ? L"\\ConEmu" : L"ConEmu");
			}
			wsprintf(gsVer86, msgInstallFolderIs, CONEMUVERL, L"x86", bInstalled ? msgPathCurrent : msgPathDefault, szInstallPath);


		if (isWin64)
		{

				szInstallPath[0] = 0; bInstalled = false;
				struct {HKEY hk; LPCWSTR path; LPCWSTR name; bool our;}
					Keys[] = {
						{HKEY_LOCAL_MACHINE,L"SOFTWARE\\ConEmu",L"InstallDir_x64",true},
						//Current installer does not use FarManager installation dir anymore
						//{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far Manager",L"InstallDir_x64"},
						//{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far2",L"InstallDir_x64"},
						//{HKEY_LOCAL_MACHINE,L"SOFTWARE\\Far",L"InstallDir_x64"},
					};
				for (size_t s = 0; s < countof(Keys); s++)
				{
					if (!RegOpenKeyEx(Keys[s].hk, Keys[s].path, 0, KEY_READ|KEY_WOW64_64KEY, &hk))
					{
						wchar_t szPath[MAX_PATH+1] = {}; DWORD cbSize = sizeof(szPath)-2;
						LONG lRc = RegQueryValueEx(hk, Keys[s].name, NULL, NULL, (LPBYTE)szPath, &cbSize);
						RegCloseKey(hk);
						if (!lRc && *szPath)
						{
							bInstalled = Keys[s].our;
							lstrcpy(szInstallPath, szPath);
							cbSize = lstrlen(szInstallPath);
							if (szInstallPath[cbSize-1] == L'\\') szInstallPath[cbSize-1] = 0;
							break;
						}
					}
				}
				if (szInstallPath[0] == 0)
				{
					GetEnvironmentVariable(L"ProgramW6432", szInstallPath, MAX_PATH);
					int nLen = lstrlen(szInstallPath);
					lstrcat(szInstallPath, (nLen > 0 && szInstallPath[nLen-1] != L'\\') ? L"\\ConEmu" : L"ConEmu");
				}
				wsprintf(gsVer64, msgInstallFolderIs, CONEMUVERL, L"x64", bInstalled ? msgPathCurrent : msgPathDefault, szInstallPath);

			wsprintf(gsFull, msgInstallConfirm, gsMessage);
		}
		else
		{
			gsVer64[0] = 0;
		}
	}
	else
	{
		LPCWSTR szPath = gsTempFolder;
		lstrcpyn(gsMessage, msgChooseExtractVer, countof(gsMessage));
		wsprintf(gsVer86, msgExtractX86X64, CONEMUVERL, L"x86", szPath);
		wsprintf(gsVer64, msgExtractX86X64, CONEMUVERL, L"x64", szPath);
		wsprintf(gsFull, msgExtractConfirm, gsMessage, szPath);
	}

	if (nInstallVer == 0)
	{
		nInstallVer = ChooseVersion(); // IDCANCEL/Ver86/Ver64
	}

	if (nInstallVer != Ver86 && nInstallVer != Ver64)
	{
		return exit_Cancelled;
	}

	// Preparing full paths
	wsprintf(gsMsiFile, L"%s\\ConEmu.%s.%s.msi", gsTempFolder, CONEMUVERL, (nInstallVer == Ver86) ? L"x86" : L"x64");
	wsprintf(gsCabFile, L"%s\\ConEmu.cab", gsTempFolder);

	bool lbNeedExe = false;
	if (!gbExtractOnly && gOSVer.dwMajorVersion >= 6)
		lbNeedExe = true;

	if (!lbNeedExe)
		gsExeFile[0] = 0;
	else
		wsprintf(gsExeFile, L"%s\\ConEmuSetup.exe", gsTempFolder);

	int iExpMsi = ExportFile(nInstallVer, gsMsiFile);
	int iExpCab = (iExpMsi == 0) ? ExportFile(CABFILE, gsCabFile) : -1;
	int iExpExe = (!lbNeedExe) ? 0 : (iExpCab == 0) ? ExportFile(EXEFILE, gsExeFile) : -1;
	if (iExpMsi != 0 || iExpCab != 0 || iExpExe != 0)
	{
		DeleteFile(gsMsiFile);
		DeleteFile(gsCabFile);
		if (*gsExeFile)
			DeleteFile(gsExeFile);
		return (iExpMsi != 0) ? iExpMsi : iExpCab;
	}

	if (gbExtractOnly)
	{
		temp_dir.DontRemove();
		wchar_t szMessage[MAX_PATH*2];
		wsprintf(szMessage, msgExtractedSuccessfully, gsTempFolder);
		MessageBox(NULL, szMessage, gsTitle, MB_ICONINFORMATION);
		return exit_Succeeded;
	}

	int iInstRc = exit_Succeeded;
	SHELLEXECUTEINFO sei = {sizeof(sei)};
	wchar_t* pszParms = NULL;
	sei.fMask = SEE_MASK_NOCLOSEPROCESS|/*SEE_MASK_NOASYNC*/0x00000100; //|/*SEE_MASK_NOZONECHECKS*/0x00800000;
	sei.lpVerb = L"open";
	if (gOSVer.dwMajorVersion<=5 || !gbUseElevation)
	{
		sei.lpFile = gsMsiFile;
		sei.lpParameters = pszCmdToken;
	}
	else
	{
		// Executor has `<requestedExecutionLevel level="requireAdministrator" ...>` in manifest
		sei.lpFile = gsExeFile;
		int nMaxLen = lstrlen(gsMsiFile) + (pszCmdToken ? lstrlen(pszCmdToken) : 0) + 64;
		pszParms = (wchar_t*)malloc(nMaxLen*sizeof(wchar_t));
		wsprintf(pszParms, L"/i \"%s\" %s", gsMsiFile, pszCmdToken ? pszCmdToken : L"");
		sei.lpParameters = pszParms;
	}
	sei.lpDirectory = gsTempFolder;
	sei.nShow = SW_SHOWNORMAL;

	BOOL lbExecute = ShellExecuteEx(&sei);

	#if 0
	if (!lbExecute && lbNeedExe)
	{
		DWORD nErr = GetLastError();
		if (nErr == 1223)
		{
			// Отмена пользователем UAC, или правов не хватило?
			sei.fMask = SEE_MASK_NOCLOSEPROCESS|/*SEE_MASK_NOASYNC*/0x00000100; //|/*SEE_MASK_NOZONECHECKS*/0x00800000;
			sei.lpVerb = L"open";
			sei.lpFile = gsMsiFile;
			sei.lpParameters = pszCmdToken;
			sei.lpDirectory = gsTempFolder;
			sei.nShow = SW_SHOWNORMAL;

			lbExecute = ShellExecuteEx(&sei);
		}
	}
	#endif

	if (!lbExecute)
	{
		iInstRc = ReportError(exit_ShellExecuteEx, msgInstallerFailed, gsMsiFile);
	}
	else
	{
		if (!sei.hProcess)
		{
			iInstRc = ReportError(exit_NullProcess, msgInstallerFailed, gsMsiFile);
		}
		else
		{
			WaitForSingleObject(sei.hProcess, INFINITE);
			DWORD nCode = 0;
			SetLastError(0);
			wchar_t szFormat[256];
			if (GetExitCodeProcess(sei.hProcess, &nCode))
			{
				switch (nCode)
				{
				case 0:
					iInstRc = exit_Succeeded;
					break;
				case 1602: // cancelled by user
					iInstRc = exit_Cancelled; // don't show any errors
					break;
				case 3010: // reboot is required
					wsprintf(szFormat, msgRebootRequired, nCode);
					iInstRc = ReportError(exit_AddWin32Code+nCode, szFormat, gsMsiFile);
					break;
				default:
					wsprintf(szFormat, msgInstallerFailedEx, nCode);
					iInstRc = ReportError(exit_AddWin32Code+nCode, szFormat, gsMsiFile);
				}
			}
			else
			{
				lstrcpyn(szFormat, msgExitCodeFailed, countof(szFormat));
				iInstRc = ReportError(exit_ExitCodeProcess, szFormat, gsMsiFile);
			}
		}
	}

	DeleteFile(gsMsiFile);
	DeleteFile(gsCabFile);
	if (*gsExeFile)
		DeleteFile(gsExeFile);

	return iInstRc;
}
Beispiel #25
0
bool GetImageSubsystem(const wchar_t *FileName,DWORD& ImageSubsystem,DWORD& ImageBits/*16/32/64*/,DWORD& FileAttrs)
{
	bool Result = false;
	ImageSubsystem = IMAGE_SUBSYSTEM_UNKNOWN;
	ImageBits = 0;
	FileAttrs = (DWORD)-1;
	wchar_t* pszExpand = NULL;
	// Пытаться в UNC? Хотя сам CreateProcess UNC не поддерживает, так что смысла пока нет
	HANDLE hModuleFile = CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);

	// Переменные окружения
	if ((hModuleFile == INVALID_HANDLE_VALUE) && FileName && wcschr(FileName, L'%'))
	{
		pszExpand = ExpandEnvStr(FileName);
		if (pszExpand)
		{
			hModuleFile = CreateFile(pszExpand,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
			if (hModuleFile != INVALID_HANDLE_VALUE)
			{
				FileName = pszExpand;
			}
		}
	}

#if 0
	// Если не указан путь к файлу - попробовать найти его в %PATH%
	if (hModuleFile != INVALID_HANDLE_VALUE && FileName && wcschr(FileName, L'\\') == NULL && wcschr(FileName, L'.') != NULL)
	{
		DWORD nErrCode = GetLastError();
		if (nErrCode)
		{
			wchar_t szFind[MAX_PATH], *psz;
			DWORD nLen = SearchPath(NULL, FileName, NULL, countof(szFind), szFind, &psz);
			if (nLen && nLen < countof(szFind))
				hModuleFile = CreateFile(szFind,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
		}
	}
#endif

	if (hModuleFile != INVALID_HANDLE_VALUE)
	{
		BY_HANDLE_FILE_INFORMATION bfi = {0};
		IMAGE_DOS_HEADER DOSHeader;
		DWORD ReadSize;

		if (GetFileInformationByHandle(hModuleFile, &bfi))
			FileAttrs = bfi.dwFileAttributes;

		// Это это батник - сразу вернуть IMAGE_SUBSYSTEM_BATCH_FILE
		LPCWSTR pszExt = PointToExt(FileName);
		if (pszExt 
			&& (!lstrcmpi(pszExt, L".cmd")
				|| !lstrcmpiW(pszExt, L".bat")
				|| !lstrcmpiW(pszExt, L".btm") // take command
			))
		{
			CloseHandle(hModuleFile);
			ImageSubsystem = IMAGE_SUBSYSTEM_BATCH_FILE;
			ImageBits = IsWindows64() ? 64 : 32; //-V112
			Result = true;
			goto wrap;
		}

		if (ReadFile(hModuleFile,&DOSHeader,sizeof(DOSHeader),&ReadSize,NULL))
		{
			_ASSERTE(IMAGE_DOS_SIGNATURE==0x5A4D);
			if (DOSHeader.e_magic != IMAGE_DOS_SIGNATURE)
			{
				//const wchar_t *pszExt = wcsrchr(FileName, L'.');

				if (pszExt && lstrcmpiW(pszExt, L".com") == 0)
				{
					ImageSubsystem = IMAGE_SUBSYSTEM_DOS_EXECUTABLE;
					ImageBits = 16;
					Result = true;
				}
			}
			else
			{
				ImageSubsystem = IMAGE_SUBSYSTEM_DOS_EXECUTABLE;
				ImageBits = 16;
				Result = true;

				if (SetFilePointer(hModuleFile,DOSHeader.e_lfanew,NULL,FILE_BEGIN))
				{
					IMAGE_HEADERS PEHeader;

					if (ReadFile(hModuleFile,&PEHeader,sizeof(PEHeader),&ReadSize,NULL))
					{
						_ASSERTE(IMAGE_NT_SIGNATURE==0x00004550);
						if (PEHeader.Signature == IMAGE_NT_SIGNATURE)
						{
							switch(PEHeader.OptionalHeader32.Magic)
							{
								case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
								{
									ImageSubsystem = PEHeader.OptionalHeader32.Subsystem;
									_ASSERTE((ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) || (ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI));
									ImageBits = 32; //-V112
								}
								break;
								case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
								{
									ImageSubsystem = PEHeader.OptionalHeader64.Subsystem;
									_ASSERTE((ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) || (ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI));
									ImageBits = 64;
								}
								break;
								/*default:
									{
										// unknown magic
									}*/
							}
						}
						else if ((WORD)PEHeader.Signature == IMAGE_OS2_SIGNATURE)
						{
							ImageBits = 32; //-V112
							/*
							NE,  хмм...  а как определить что оно ГУЕВОЕ?

							Andrzej Novosiolov <*****@*****.**>
							AN> ориентироваться по флагу "Target operating system" NE-заголовка
							AN> (1 байт по смещению 0x36). Если там Windows (значения 2, 4) - подразумеваем
							AN> GUI, если OS/2 и прочая экзотика (остальные значения) - подразумеваем консоль.
							*/
							BYTE ne_exetyp = reinterpret_cast<PIMAGE_OS2_HEADER>(&PEHeader)->ne_exetyp;

							if (ne_exetyp==2||ne_exetyp==4) //-V112
							{
								ImageSubsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
							}
							else
							{
								ImageSubsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
							}
						}

						/*else
						{
							// unknown signature
						}*/
					}

					/*else
					{
						// обломс вышел с чтением следующего заголовка ;-(
					}*/
				}

				/*else
				{
					// видимо улетели куда нить в трубу, т.к. dos_head.e_lfanew указал
					// слишком в неправдоподное место (например это чистой воды DOS-файл)
				}*/
			}

			/*else
			{
				// это не исполняемый файл - у него нету заголовка MZ, например, NLM-модуль
				// TODO: здесь можно разбирать POSIX нотацию, например "/usr/bin/sh"
			}*/
		}

		/*else
		{
			// ошибка чтения
		}*/
		CloseHandle(hModuleFile);
	}

	/*else
	{
		// ошибка открытия
	}*/
wrap:
	SafeFree(pszExpand);
	return Result;
}
Beispiel #26
0
bool InitRegistryRoot(CESERVER_CONSOLE_MAPPING_HDR* pInfo)
{
	wchar_t szTitle[64];
	msprintf(szTitle, countof(szTitle), L"ConEmuHk, PID=%u", GetCurrentProcessId());

	if (!ghAdvapi32)
	{
		GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but ghAdvapi32 is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
		return false;
	}

	if (!RegOpenKeyEx_f)
	{
		_ASSERTE(RegOpenKeyEx_f!=NULL);
		RegOpenKeyEx_f = (RegOpenKeyEx_t)GetProcAddress(ghAdvapi32, "RegOpenKeyExW");
		if (!RegOpenKeyEx_f)
		{
			GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegOpenKeyExW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
			return false;
		}
	}
	if (!RegCreateKeyEx_f)
	{
		_ASSERTE(RegCreateKeyEx_f!=NULL);
		RegCreateKeyEx_f = (RegCreateKeyEx_t)GetProcAddress(ghAdvapi32, "RegCreateKeyExW");
		if (!RegCreateKeyEx_f)
		{
			GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegCreateKeyExW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
			return false;
		}
	}
	if (!RegCloseKey_f)
	{
		_ASSERTE(RegCloseKey_f!=NULL);
		RegCloseKey_f = (RegCloseKey_t)GetProcAddress(ghAdvapi32, "RegCloseKey");
		if (!RegCloseKey_f)
		{
			GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegCloseKey) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
			return false;
		}
	}

	if (ghNewKeyRoot == NULL)
	{
		//OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)};
		//GetVersionEx(&osv);
		//if (osv.dwMajorVersion >= 6)
		if (!*pInfo->sMountKey)
		{
			// Vista+	
			typedef LONG (WINAPI* RegLoadAppKey_t)(LPCWSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions, DWORD Reserved);
			RegLoadAppKey_t RegLoadAppKey_f = (RegLoadAppKey_t)GetProcAddress(ghAdvapi32, "RegLoadAppKeyW");
			if (RegLoadAppKey_f)
			{
				LONG lRc = 0;
				if ((lRc = RegLoadAppKey_f(pInfo->sHiveFileName, &ghNewKeyRoot, KEY_ALL_ACCESS, 0, 0)) != 0)
				{
					if ((lRc = RegLoadAppKey_f(pInfo->sHiveFileName, &ghNewKeyRoot, KEY_READ, 0, 0)) != 0)
					{
						wchar_t szDbgMsg[128];
						msprintf(szDbgMsg, countof(szDbgMsg), L"ConEmuHk: RegLoadAppKey failed, code=0x%08X!\n", (DWORD)lRc);
						GuiMessageBox(ghConEmuWnd, szDbgMsg, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
						ghNewKeyRoot = NULL;
					}
				}
			}
			else
			{
				GuiMessageBox(ghConEmuWnd, L"ConEmuHk: InitRegistryRoot was called, but GetProcAddress(RegLoadAppKeyW) is null!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
				ghNewKeyRoot = NULL;
			}				
		}
		else
		{
			// XP Only. т.к. для монтирования хайва требуются права админа
			HKEY hkRoot = pInfo->hMountRoot;
			if (hkRoot == HKEY_CURRENT_USER)
			{
				// Значит это "HKCU\Software\ConEmu Virtual Registry"
				if (RegOpenKeyEx_f(HKEY_CURRENT_USER, VIRTUAL_REGISTRY_ROOT, 0, KEY_ALL_ACCESS, &hkRoot))
				{
					GuiMessageBox(ghConEmuWnd, L"ConEmuHk: RegOpenKeyEx(" VIRTUAL_REGISTRY_ROOT L") failed!\n", szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
					ghNewKeyRoot = NULL;
					hkRoot = NULL;
				}
			}
			if (hkRoot && RegOpenKeyEx_f(hkRoot, pInfo->sMountKey, 0, KEY_ALL_ACCESS, &ghNewKeyRoot))
			{
				if (RegOpenKeyEx_f(hkRoot, pInfo->sMountKey, 0, KEY_READ, &ghNewKeyRoot))
				{
					wchar_t szErrMsg[512];
					msprintf(szErrMsg, countof(szErrMsg), 
						L"ConEmuHk: RegOpenKeyEx(0x%X,'%s') failed!\n",
						(DWORD)(LONG)(LONG_PTR)hkRoot, pInfo->sMountKey);
					GuiMessageBox(ghConEmuWnd, szErrMsg, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
					ghNewKeyRoot = NULL;
				}
			}
		}

		if (!ghNewKeyRoot)
		{
			ghNewKeyRoot = (HKEY)-1;
		}
		else
		{
			LONG lRc = 0;
			LPCWSTR pszKeyName = NULL;
			if (!lRc)
				lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKCU", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKCU, 0);
			if (!lRc)
				lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKCU\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKCUSoftware, 0);
			if (!lRc)
				lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM32, 0);
			if (!lRc)
				lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM32Software, 0);
			if (!lRc && IsWindows64())
			{
				// эта ветка не должна выполняться в 32битных ОС
				if (!lRc)
					lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM64", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM64, 0);
				if (!lRc)
					lRc = RegCreateKeyEx_f(ghNewKeyRoot, pszKeyName=L"HKLM64\\Software", 0,0,0, KEY_ALL_ACCESS, 0, &ghNewHKLM64Software, 0);
			}
			if (lRc != 0)
			{
				CloseRootKeys();
				ghNewKeyRoot = (HKEY)-1; // чтобы не пытаться открыть повторно
				wchar_t szErrInfo[MAX_PATH];
				msprintf(szErrInfo, countof(szErrInfo), L"ConEmuHk: Virtual subkey (%s) creation failed! ErrCode=0x%08X\n",
					pszKeyName ? pszKeyName : L"<NULL>", (DWORD)lRc);
				GuiMessageBox(ghConEmuWnd, szErrInfo, szTitle, MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
			}
			// Для консистентности
			if (!ghNewHKLM64)
				ghNewHKLM64 = ghNewHKLM32;
			if (!ghNewHKLM64Software)
				ghNewHKLM64Software = ghNewHKLM32Software;
		}
	}

	if ((ghNewKeyRoot == NULL) || (ghNewKeyRoot == (HKEY)-1))
	{
		DEBUGSTR(L"ConEmuHk: Registry virtualization failed!\n");
		return false;
	}
	else
	{
		DEBUGSTR(L"ConEmuHk: Registry virtualization succeeded\n");
	}

	return true;
}
Beispiel #27
0
bool FindImageSubsystem(const wchar_t *Module, /*wchar_t* pstrDest,*/ DWORD& ImageSubsystem, DWORD& ImageBits, DWORD& FileAttrs)
{
	if (!Module || !*Module)
		return false;

	bool Result = false;
	//ImageSubsystem = IMAGE_SUBSYSTEM_UNKNOWN;

	// Исключения нас не интересуют - команда уже сформирована и отдана в CreateProcess!
	//// нулевой проход - смотрим исключения
	//// Берем "исключения" из реестра, которые должны исполняться директом,
	//// например, некоторые внутренние команды ком. процессора.
	//string strExcludeCmds;
	//GetRegKey(strSystemExecutor,L"ExcludeCmds",strExcludeCmds,L"");
	//UserDefinedList ExcludeCmdsList;
	//ExcludeCmdsList.Set(strExcludeCmds);
	//while (!ExcludeCmdsList.IsEmpty())
	//{
	//	if (!StrCmpI(Module,ExcludeCmdsList.GetNext()))
	//	{
	//		ImageSubsystem=IMAGE_SUBSYSTEM_WINDOWS_CUI;
	//		Result=true;
	//		break;
	//	}
	//}

	//string strFullName=Module;
	LPCWSTR ModuleExt = PointToExt(Module);
	wchar_t *strPathExt/*[32767]*/ = NULL; //(L".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WSH");
	wchar_t *strPathEnv/*[32767]*/ = NULL;
	wchar_t *strExpand/*[32767]*/ = NULL;
	wchar_t *strTmpName/*[32767]*/ = NULL;
	wchar_t *pszFilePart = NULL;
	DWORD nPathExtLen = 0;
	LPCWSTR pszPathExtEnd = NULL;
	LPWSTR Ext = NULL;

	typedef LONG (WINAPI *RegOpenKeyExW_t)(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);
	RegOpenKeyExW_t _RegOpenKeyEx = NULL;
	typedef LONG (WINAPI *RegQueryValueExW_t)(HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);
	RegQueryValueExW_t _RegQueryValueEx = NULL;
	typedef LONG (WINAPI *RegCloseKey_t)(HKEY hKey);
	RegCloseKey_t _RegCloseKey = NULL;
	HMODULE hAdvApi = NULL;
	
	

	int cchstrPathExt = 32767;
	strPathExt = (wchar_t*)malloc(cchstrPathExt*sizeof(wchar_t)); *strPathExt = 0;
	int cchstrPathEnv = 32767;
	strPathEnv = (wchar_t*)malloc(cchstrPathEnv*sizeof(wchar_t)); *strPathEnv = 0;
	int cchstrExpand = 32767;
	strExpand = (wchar_t*)malloc(cchstrExpand*sizeof(wchar_t)); *strExpand = 0;
	int cchstrTmpName = 32767;
	strTmpName = (wchar_t*)malloc(cchstrTmpName*sizeof(wchar_t)); *strTmpName = 0;
		
	nPathExtLen = GetEnvironmentVariable(L"PATHEXT", strPathExt, cchstrPathExt-2);
	if (!nPathExtLen)
	{
		_wcscpy_c(strPathExt, cchstrPathExt, L".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WSH");
		nPathExtLen = lstrlen(strPathExt);
	}
	pszPathExtEnd = strPathExt+nPathExtLen;
	// Разбить на токены
	strPathExt[nPathExtLen] = strPathExt[nPathExtLen+1] = 0;
	Ext = wcschr(strPathExt, L';');
	while (Ext)
	{
		*Ext = 0;
		Ext = wcschr(Ext+1, L';');
	}

	TODO("Проверить на превышение длин строк");

	// первый проход - в текущем каталоге
	LPWSTR pszExtCur = strPathExt;
	while (pszExtCur < pszPathExtEnd)
	{
		Ext = pszExtCur;
		pszExtCur = pszExtCur + lstrlen(pszExtCur)+1;

		_wcscpyn_c(strTmpName, cchstrTmpName, Module, cchstrTmpName); //-V501

		if (!ModuleExt)
		{
			if (!*Ext)
				continue;
			_wcscatn_c(strTmpName, cchstrTmpName, Ext, cchstrTmpName);
		}

		if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits/*16/32/64*/, FileAttrs))
		{
			Result = true;
			goto wrap;
		}

		if (ModuleExt)
		{
			break;
		}
	}

	// второй проход - по правилам SearchPath

	// поиск по переменной PATH
	if (GetEnvironmentVariable(L"PATH", strPathEnv, cchstrPathEnv))
	{
		LPWSTR pszPathEnvEnd = strPathEnv + lstrlen(strPathEnv);

		LPWSTR pszPathCur = strPathEnv;
		while (pszPathCur && (pszPathCur < pszPathEnvEnd))
		{
			LPWSTR Path = pszPathCur;
			LPWSTR pszPathNext = wcschr(pszPathCur, L';');
			if (pszPathNext)
			{
				*pszPathNext = 0;
				pszPathCur = pszPathNext+1;
			}
			else
			{
				pszPathCur = pszPathEnvEnd;
			}
			if (!*Path)
				continue;

			pszExtCur = strPathExt;
			while (pszExtCur < pszPathExtEnd)
			{
				Ext = pszExtCur;
				pszExtCur = pszExtCur + lstrlen(pszExtCur)+1;
				if (!*Ext)
					continue;

				if (SearchPath(Path, Module, Ext, cchstrTmpName, strTmpName, &pszFilePart))
				{
					if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits, FileAttrs))
					{
						Result = true;
						goto wrap;
					}
				}
			}
		}
	}

	pszExtCur = strPathExt;
	while (pszExtCur < pszPathExtEnd)
	{
		Ext = pszExtCur;
		pszExtCur = pszExtCur + lstrlen(pszExtCur)+1;
		if (!*Ext)
			continue;

		if (SearchPath(NULL, Module, Ext, cchstrTmpName, strTmpName, &pszFilePart))
		{
			if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits, FileAttrs))
			{
				Result = true;
				goto wrap;
			}
		}
	}

	// третий проход - лезем в реестр в "App Paths"
	if (!wcschr(Module, L'\\'))
	{
		hAdvApi = LoadLibrary(L"AdvApi32.dll");
		if (!hAdvApi)
			goto wrap;
		_RegOpenKeyEx = (RegOpenKeyExW_t)GetProcAddress(hAdvApi, "RegOpenKeyExW");
		_RegQueryValueEx = (RegQueryValueExW_t)GetProcAddress(hAdvApi, "RegQueryValueExW");
		_RegCloseKey = (RegCloseKey_t)GetProcAddress(hAdvApi, "RegCloseKey");
		if (!_RegOpenKeyEx || !_RegQueryValueEx || !_RegCloseKey)
			goto wrap;

		LPCWSTR RegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";
		// В строке Module заменить исполняемый модуль на полный путь, который
		// берется из SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
		// Сначала смотрим в HKCU, затем - в HKLM
		HKEY RootFindKey[] = {HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_LOCAL_MACHINE};

		BOOL lbAddExt = FALSE;
		pszExtCur = strPathExt;
		while (pszExtCur < pszPathExtEnd)
		{
			if (!lbAddExt)
			{
				Ext = NULL;
				lbAddExt = TRUE;
			}
			else
			{
				Ext = pszExtCur;
				pszExtCur = pszExtCur + lstrlen(pszExtCur)+1;
				if (!*Ext)
					continue;
			}

			_wcscpy_c(strTmpName, cchstrTmpName, RegPath);
			_wcscatn_c(strTmpName, cchstrTmpName, Module, cchstrTmpName);
			if (Ext)
				_wcscatn_c(strTmpName, cchstrTmpName, Ext, cchstrTmpName);

			DWORD samDesired = KEY_QUERY_VALUE;
			DWORD RedirectionFlag = 0;
			// App Paths key is shared in Windows 7 and above
			OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)};
			GetVersionEx(&osv);
			if (osv.dwMajorVersion < 6 || (osv.dwMajorVersion == 6 && osv.dwMinorVersion < 1))
			{
				#ifdef _WIN64
				RedirectionFlag = KEY_WOW64_32KEY;
				#else
				RedirectionFlag = IsWindows64() ? KEY_WOW64_64KEY : 0;
				#endif
			}
			for (size_t i = 0; i < countof(RootFindKey); i++)
			{
				if (i == (countof(RootFindKey)-1))
				{
					if (RedirectionFlag)
						samDesired |= RedirectionFlag;
					else
						break;
				}
				HKEY hKey;
				if (_RegOpenKeyEx(RootFindKey[i], strTmpName, 0, samDesired, &hKey) == ERROR_SUCCESS)
				{
					DWORD nType = 0, nSize = sizeof(strTmpName)-2;
					int RegResult = _RegQueryValueEx(hKey, L"", NULL, &nType, (LPBYTE)strTmpName, &nSize);
					_RegCloseKey(hKey);

					if ((RegResult == ERROR_SUCCESS) && (nType == REG_SZ || nType == REG_EXPAND_SZ || nType == REG_MULTI_SZ))
					{
						strTmpName[(nSize >> 1)+1] = 0;
						if (!ExpandEnvironmentStrings(strTmpName, strExpand, cchstrExpand))
							_wcscpy_c(strExpand, cchstrExpand, strTmpName);
						if (GetImageSubsystem(Unquote(strExpand), ImageSubsystem, ImageBits, FileAttrs))
						{
							Result = true;
							goto wrap;
						}
					}
				}
			}
Beispiel #28
0
DWORD WINAPI DebugThread(LPVOID lpvParam)
{
	DWORD nWait = WAIT_TIMEOUT;
	wchar_t szInfo[1024];
	wchar_t szPID[20];
	int iAttachedCount = 0;
	CEStr szOtherBitPids, szOtherDebugCmd;

	// Дополнительная инициализация, чтобы закрытие дебагера (наш процесс) не привело
	// к закрытию "отлаживаемой" программы
	pfnDebugActiveProcessStop = (FDebugActiveProcessStop)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugActiveProcessStop");
	pfnDebugSetProcessKillOnExit = (FDebugSetProcessKillOnExit)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugSetProcessKillOnExit");

	// Affect GetProcessHandleForDebug
	gpSrv->DbgInfo.bDebuggerActive = TRUE;

	// If dump was requested
	if (gpSrv->DbgInfo.nDebugDumpProcess)
	{
		gpSrv->DbgInfo.bUserRequestDump = TRUE;
	}

	// "/DEBUGEXE" or "/DEBUGTREE"
	if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
	{
		STARTUPINFO si = {sizeof(si)};
		PROCESS_INFORMATION pi = {};

		if (gpSrv->DbgInfo.bDebugProcessTree)
		{
			SetEnvironmentVariable(ENV_CONEMU_BLOCKCHILDDEBUGGERS_W, ENV_CONEMU_BLOCKCHILDDEBUGGERS_YES);
		}

		if (!CreateProcess(NULL, gpSrv->DbgInfo.pszDebuggingCmdLine, NULL, NULL, FALSE,
			NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|
			DEBUG_PROCESS | (gpSrv->DbgInfo.bDebugProcessTree ? 0 : DEBUG_ONLY_THIS_PROCESS),
			NULL, NULL, &si, &pi))
		{
			DWORD dwErr = GetLastError();

			wchar_t szProc[64]; szProc[0] = 0;
			PROCESSENTRY32 pi = {sizeof(pi)};
			if (GetProcessInfo(gpSrv->dwRootProcess, &pi))
				_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start debugging process. ErrCode=0x%08X\n", dwErr);
			CEStr lsInfo(lstrmerge(szInfo, gpSrv->DbgInfo.pszDebuggingCmdLine, L"\n"));
			_wprintf(lsInfo);
			return CERR_CANTSTARTDEBUGGER;
		}

		gpSrv->hRootProcess = pi.hProcess;
		gpSrv->hRootThread = pi.hThread;
		gpSrv->dwRootProcess = pi.dwProcessId;
		gpSrv->dwRootThread = pi.dwThreadId;
		gpSrv->dwRootStartTime = GetTickCount();

		// Let's know that at least one process is debugging
		iAttachedCount++;
	}


	/* ************************* */
	int iDbgIdx = 0;
	bool bSetKillOnExit = true;

	while (true)
	{
		HANDLE hDbgProcess = NULL;
		DWORD  nDbgProcessID = 0;

		if ((iDbgIdx++) == 0)
		{
			hDbgProcess = gpSrv->hRootProcess;
			nDbgProcessID = gpSrv->dwRootProcess;
		}
		else
		{
			// Взять из pDebugAttachProcesses
			if (!gpSrv->DbgInfo.pDebugAttachProcesses)
				break;
			if (!gpSrv->DbgInfo.pDebugAttachProcesses->pop_back(nDbgProcessID))
				break;
			hDbgProcess = GetProcessHandleForDebug(nDbgProcessID);
			if (!hDbgProcess)
			{
				_ASSERTE(hDbgProcess!=NULL && "Can't open debugging process handle");
				continue;
			}
		}


		_ASSERTE(hDbgProcess!=NULL && "Process handle must be opened");


		// Битность отладчика должна соответствовать битности приложения!
		if (IsWindows64())
		{
			int nBits = GetProcessBits(nDbgProcessID, hDbgProcess);
			if ((nBits == 32 || nBits == 64) && (nBits != WIN3264TEST(32,64)))
			{
				// If /DEBUGEXE or /DEBUGTREE was used
				if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL)
				{
					_printf("Bitness of ConEmuC and debugging program does not match\n");
					continue;
				}

				// Добавить процесс в список для запуска альтернативного дебаггера соотвествующей битности
				// Force trailing "," even if only one PID specified ( --> bDebugMultiProcess = TRUE)
				lstrmerge(&szOtherBitPids.ms_Arg, _itow(nDbgProcessID, szPID, 10), L",");

				// Может там еще процессы в списке на дамп?
				continue;
			}
		}

		if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL)
		{
			if (DebugActiveProcess(nDbgProcessID))
			{
				iAttachedCount++;
			}
			else
			{
				DWORD dwErr = GetLastError();

				wchar_t szProc[64]; szProc[0] = 0;
				PROCESSENTRY32 pi = {sizeof(pi)};
				if (GetProcessInfo(nDbgProcessID, &pi))
					_wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc));

				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't attach debugger to '%s' PID=%i. ErrCode=0x%08X\n",
					szProc[0] ? szProc : L"not found", nDbgProcessID, dwErr);
				_wprintf(szInfo);

				// Может другие подцепить получится?
				continue;
			}
		}

		// To avoid debugged processes killing
		if (bSetKillOnExit && pfnDebugSetProcessKillOnExit)
		{
			// affects all current and future debuggees connected to the calling thread
			if (pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/))
			{
				bSetKillOnExit = false;
			}
		}
	}

	// Different bitness, need to start appropriate debugger
	if (szOtherBitPids.ms_Arg && *szOtherBitPids.ms_Arg)
	{
		wchar_t szExe[MAX_PATH+5], *pszName;
		if (!GetModuleFileName(NULL, szExe, MAX_PATH))
		{
			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"GetModuleFileName(NULL) failed. ErrCode=0x%08X\n", GetLastError());
			_wprintf(szInfo);
		}
		else if (!(pszName = (wchar_t*)PointToName(szExe)))
		{
			_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"GetModuleFileName(NULL) returns invalid path\n%s\n", szExe);
			_wprintf(szInfo);
		}
		else
		{
			*pszName = 0;
			// Reverted to current bitness
			wcscat_c(szExe, WIN3264TEST(L"ConEmuC64.exe", L"ConEmuC.exe"));

			szOtherDebugCmd.Attach(lstrmerge(L"\"", szExe, L"\" "
				L"/DEBUGPID=", szOtherBitPids.ms_Arg,
				(gpSrv->DbgInfo.nDebugDumpProcess == 1) ? L" /DUMP" :
				(gpSrv->DbgInfo.nDebugDumpProcess == 2) ? L" /MINIDUMP" :
				(gpSrv->DbgInfo.nDebugDumpProcess == 3) ? L" /FULLDUMP" : L""));

			STARTUPINFO si = {sizeof(si)};
			PROCESS_INFORMATION pi = {};
			if (CreateProcess(NULL, szOtherDebugCmd.ms_Arg, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
			{
				// Ждать не будем
			}
			else
			{
				DWORD dwErr = GetLastError();
				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start external debugger, ErrCode=0x%08X\n", dwErr);
				CEStr lsInfo(lstrmerge(szInfo, szOtherDebugCmd, L"\n"));
				_wprintf(lsInfo);
			}
		}
	}

	//_ASSERTE(FALSE && "Continue to dump");

	// If neither /DEBUG[EXE|TREE] nor /DEBUGPID was not succeeded
	if (iAttachedCount == 0)
	{
		gpSrv->DbgInfo.bDebuggerActive = FALSE;
		return CERR_CANTSTARTDEBUGGER;
	}
	else if (iAttachedCount > 1)
	{
		_ASSERTE(gpSrv->DbgInfo.bDebugMultiProcess && "Already must be set from arguments parser");
		gpSrv->DbgInfo.bDebugMultiProcess = TRUE;
	}

	if (gpSrv->DbgInfo.bUserRequestDump)
	{
		gpSrv->DbgInfo.nWaitTreeBreaks = iAttachedCount;
	}

	/* **************** */

	// To avoid debugged processes killing (JIC, must be called already)
	if (bSetKillOnExit && pfnDebugSetProcessKillOnExit)
	{
		// affects all current and future debuggees connected to the calling thread
		if (pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/))
		{
			bSetKillOnExit = false;
		}
	}

	PrintDebugInfo();
	SetEvent(gpSrv->DbgInfo.hDebugReady);


	while (nWait == WAIT_TIMEOUT)
	{
		ProcessDebugEvent();

		if (ghExitQueryEvent)
			nWait = WaitForSingleObject(ghExitQueryEvent, 0);
	}

//done:
	gbRootAliveLess10sec = FALSE;
	gbInShutdown = TRUE;
	gbAlwaysConfirmExit = FALSE;

	_ASSERTE(gbTerminateOnCtrlBreak==FALSE);

	if (!nExitQueryPlace) nExitQueryPlace = 12+(nExitPlaceStep);

	SetTerminateEvent(ste_DebugThread);
	return 0;
}