Beispiel #1
0
int GuiMessageBox(HWND hConEmuWndRoot, LPCWSTR asText, LPCWSTR asTitle, int anBtns)
{
	int nResult = 0;
	
	if (hConEmuWndRoot)
	{
		HWND hConWnd = myGetConsoleWindow();
		CESERVER_REQ *pIn = (CESERVER_REQ*)malloc(sizeof(*pIn));
		ExecutePrepareCmd(pIn, CECMD_ASSERT, sizeof(CESERVER_REQ_HDR)+sizeof(MyAssertInfo));
		pIn->AssertInfo.nBtns = anBtns;
		_wcscpyn_c(pIn->AssertInfo.szTitle, countof(pIn->AssertInfo.szTitle), asTitle, countof(pIn->AssertInfo.szTitle)); //-V501
		_wcscpyn_c(pIn->AssertInfo.szDebugInfo, countof(pIn->AssertInfo.szDebugInfo), asText, countof(pIn->AssertInfo.szDebugInfo)); //-V501

		wchar_t szGuiPipeName[128];
		msprintf(szGuiPipeName, countof(szGuiPipeName), CEGUIPIPENAME, L".", (DWORD)hConEmuWndRoot); //-V205

		CESERVER_REQ* pOut = ExecuteCmd(szGuiPipeName, pIn, 1000, hConWnd);

		free(pIn);

		if (pOut)
		{
			if (pOut->hdr.cbSize > sizeof(CESERVER_REQ_HDR))
			{
				nResult = pOut->dwData[0];
			}
			ExecuteFreeResult(pOut);
		}
	}
	else
	{
		//_ASSERTE(hConEmuWndRoot!=NULL);
		// Избежать статической линковки к user32
		HMODULE hUser32 = GetModuleHandle(L"User32.dll");
		if (hUser32 == NULL)
			hUser32 = LoadLibrary(L"User32.dll");
		typedef int (WINAPI* MessageBoxW_T)(HWND, LPCWSTR, LPCWSTR, UINT);
		MessageBoxW_T _MessageBoxW = hUser32 ? (MessageBoxW_T)GetProcAddress(hUser32, "MessageBoxW") : NULL;
		if (_MessageBoxW)
		{
			nResult = _MessageBoxW(NULL, asText, asTitle, MB_SYSTEMMODAL|anBtns);
		}
		else
		{
			#ifdef _DEBUG
			_CrtDbgBreak();
			#endif
		}
	}

	return nResult;
}
Beispiel #2
0
LPCWSTR CmdArg::Set(LPCWSTR asNewValue, INT_PTR anChars /*= -1*/)
{
	if (asNewValue)
	{
		INT_PTR nNewLen = (anChars == -1) ? lstrlen(asNewValue) : anChars;
		if (nNewLen <= 0)
		{
			//_ASSERTE(FALSE && "Check, if caller really need to set empty string???");
			if (GetBuffer(1))
				ms_Arg[0] = 0;
		}
		else if (GetBuffer(nNewLen))
		{
			_ASSERTE(mn_MaxLen > nNewLen); // Must be set in GetBuffer
			_wcscpyn_c(ms_Arg, mn_MaxLen, asNewValue, nNewLen);
		}
	}
	else
	{
		Empty();
	}
	return ms_Arg;
}
Beispiel #3
0
wchar_t* GetShortFileNameEx(LPCWSTR asLong, BOOL abFavorLength/*=TRUE*/)
{
	if (!asLong)
		return NULL;

	int nSrcLen = lstrlenW(asLong); //-V303
	wchar_t* pszLong = lstrdup(asLong);

	int nMaxLen = nSrcLen + MAX_PATH; // "короткое" имя может более MAX_PATH
	wchar_t* pszShort = (wchar_t*)calloc(nMaxLen, sizeof(wchar_t)); //-V106

	wchar_t* pszResult = NULL;
	wchar_t* pszSrc = pszLong;
	//wchar_t* pszDst = pszShort;
	wchar_t* pszSlash;
	wchar_t* szName = (wchar_t*)malloc((MAX_PATH+1)*sizeof(wchar_t));
	bool     lbNetwork = false;
	int      nLen, nCurLen = 0;

	if (!pszLong || !pszShort || !szName)
		goto wrap;

	// Если путь сетевой (или UNC?) пропустить префиксы/серверы
	if (pszSrc[0] == L'\\' && pszSrc[1] == '\\')
	{
		// пропуск первых двух слешей
		pszSrc += 2;
		// формат "диска" не поддерживаем \\.\Drive\...
		if (pszSrc[0] == L'.' && pszSrc[1] == L'\\')
			goto wrap;
		// UNC
		if (pszSrc[0] == L'?' && pszSrc[1] == L'\\')
		{
			pszSrc += 2;
			if (pszSrc[0] == L'U' && pszSrc[1] == L'N' && pszSrc[2] == L'C' && pszSrc[3] == L'\\')
			{
				// UNC\Server\share\...
				pszSrc += 4; //-V112
				lbNetwork = true;
			}
			// иначе - ожидается диск
		}
		// Network (\\Server\\Share\...)
		else
		{
			lbNetwork = true;
		}
	}

	if (pszSrc[0] == 0)
		goto wrap;

	if (lbNetwork)
	{
		pszSlash = wcschr(pszSrc, L'\\');
		if (!pszSlash)
			goto wrap;
		pszSlash = wcschr(pszSlash+1, L'\\');
		if (!pszSlash)
			goto wrap;
		pszShort[0] = L'\\'; pszShort[1] = L'\\'; pszShort[2] = 0;
		_wcscatn_c(pszShort, nMaxLen, pszSrc, (pszSlash-pszSrc+1)); // память выделяется calloc! //-V303 //-V104
	}
	else
	{
		// <Drive>:\path...
		if (pszSrc[1] != L':')
			goto wrap;
		if (pszSrc[2] != L'\\' && pszSrc[2] != 0)
			goto wrap;
		pszSlash = pszSrc + 2;
		_wcscatn_c(pszShort, nMaxLen, pszSrc, (pszSlash-pszSrc+1)); // память выделяется calloc!
	}

	nCurLen = lstrlenW(pszShort);

	while (pszSlash && (*pszSlash == L'\\'))
	{
		pszSrc = pszSlash;
		pszSlash = wcschr(pszSrc+1, L'\\');
		if (pszSlash)
			*pszSlash = 0;

		if (!GetShortFileName(pszLong, MAX_PATH+1, szName, abFavorLength))
			goto wrap;
		nLen = lstrlenW(szName);
		if ((nLen + nCurLen) >= nMaxLen)
			goto wrap;
		//pszShort[nCurLen++] = L'\\'; pszShort[nCurLen] = 0;
		_wcscpyn_c(pszShort+nCurLen, nMaxLen-nCurLen, szName, nLen);
		nCurLen += nLen;

		if (pszSlash)
		{
			*pszSlash = L'\\';
			pszShort[nCurLen++] = L'\\'; // память выделяется calloc!
		}
	}

	nLen = lstrlenW(pszShort);

	if ((nLen > 0) && (pszShort[nLen-1] == L'\\'))
		pszShort[--nLen] = 0;

	if (nLen <= MAX_PATH)
	{
		pszResult = pszShort;
		pszShort = NULL;
		goto wrap;
	}

wrap:
	if (szName)
		free(szName);
	if (pszShort)
		free(pszShort);
	if (pszLong)
		free(pszLong);
	return pszResult;
}
Beispiel #4
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;
}
Beispiel #5
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 #6
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;
}