Exemplo n.º 1
0
// anConEmuOnly
//	0 - если в ConEmu - вернуть окно отрисовки, иначе - вернуть окно консоли
//	1 - вернуть окно отрисовки
//	2 - вернуть главное окно ConEmu
//	3 - вернуть окно консоли
HWND WINAPI GetFarHWND2(int anConEmuOnly)
{
	// Если просили реальное окно консоли - вернем сразу
	if (anConEmuOnly == 3)
	{
		return FarHwnd;
	}

	if (ghConEmuWndDC)
	{
		if (IsWindow(ghConEmuWndDC))
		{
			if (anConEmuOnly == 2)
				return GetConEmuHWND(1);
			return ghConEmuWndDC;
		}

		//
		ghConEmuWndDC = NULL;
		//
		SetConEmuEnvVar(NULL);
		SetConEmuEnvVarChild(NULL,NULL);
	}

	if (anConEmuOnly)
		return NULL;

	return FarHwnd;
}
Exemplo n.º 2
0
// 0 -- All OK (ConEmu found, Version OK)
// 1 -- NO ConEmu (simple console mode)
// (obsolete) 2 -- ConEmu found, but old version
int ConEmuCheck(HWND* ahConEmuWnd)
{
	//int nChk = -1;
	HWND ConEmuWnd = NULL;
	ConEmuWnd = GetConEmuHWND(FALSE/*abRoot*/  /*, &nChk*/);

	// Если хотели узнать хэндл - возвращаем его
	if (ahConEmuWnd) *ahConEmuWnd = ConEmuWnd;

	if (ConEmuWnd == NULL)
	{
		return 1; // NO ConEmu (simple console mode)
	}
	else
	{
		//if (nChk>=3)
		//    return 2; // ConEmu found, but old version
		return 0;
	}
}
Exemplo n.º 3
0
int RunDebugger()
{
	if (!gpSrv->DbgInfo.pDebugTreeProcesses)
	{
		gpSrv->DbgInfo.pDebugTreeProcesses = (MMap<DWORD,CEDebugProcessInfo>*)calloc(1,sizeof(*gpSrv->DbgInfo.pDebugTreeProcesses));
		gpSrv->DbgInfo.pDebugTreeProcesses->Init(1024);
	}

	UpdateDebuggerTitle();

	// Если это новая консоль - увеличить ее размер, для удобства
	if (IsWindowVisible(ghConWnd))
	{
		HANDLE hCon = ghConOut;
		CONSOLE_SCREEN_BUFFER_INFO csbi = {};
		GetConsoleScreenBufferInfo(hCon, &csbi);
		if (csbi.dwSize.X < 260)
		{
			COORD crNewSize = {260, 9999};
			SetConsoleScreenBufferSize(ghConOut, crNewSize);
		}
		//if ((csbi.srWindow.Right - csbi.srWindow.Left + 1) < 120)
		//{
		//	COORD crMax = GetLargestConsoleWindowSize(hCon);
		//	if ((crMax.X - 10) > (csbi.srWindow.Right - csbi.srWindow.Left + 1))
		//	{
		//		COORD crSize = {((int)((crMax.X - 15)/10))*10, min(crMax.Y, (csbi.srWindow.Bottom - csbi.srWindow.Top + 1))};
		//		SMALL_RECT srWnd = {0, csbi.srWindow.Top, crSize.X - 1, csbi.srWindow.Bottom};
		//		MONITORINFO mi = {sizeof(mi)};
		//		GetMonitorInfo(MonitorFromWindow(ghConWnd, MONITOR_DEFAULTTONEAREST), &mi);
		//		RECT rcWnd = {}; GetWindowRect(ghConWnd, &rcWnd);
		//		SetWindowPos(ghConWnd, NULL, min(rcWnd.left,(mi.rcWork.left+50)), rcWnd.top, 0,0, SWP_NOSIZE|SWP_NOZORDER);
		//		SetConsoleSize(9999, crSize, srWnd, "StartDebugger");
		//	}
		//}
	}

	// Вывести в консоль информацию о версии.
	PrintVersion();
	#ifdef SHOW_DEBUG_STARTED_MSGBOX
	wchar_t szInfo[128];
	StringCchPrintf(szInfo, countof(szInfo), L"Attaching debugger...\nConEmuC PID = %u\nDebug PID = %u",
	                GetCurrentProcessId(), gpSrv->dwRootProcess);
	MessageBox(GetConEmuHWND(2), szInfo, L"ConEmuC.Debugger", 0);
	#endif

	//if (!DebugActiveProcess(gpSrv->dwRootProcess))
	//{
	//	DWORD dwErr = GetLastError();
	//	_printf("Can't start debugger! ErrCode=0x%08X\n", dwErr);
	//	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();

	if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL)
	{
		int iAttachRc = AttachRootProcessHandle();
		if (iAttachRc != 0)
			return iAttachRc;
	}
	else
	{
		_ASSERTE(!gpSrv->DbgInfo.bDebuggerActive);
	}

	_ASSERTE(((gpSrv->hRootProcess!=NULL) || (gpSrv->DbgInfo.pszDebuggingCmdLine!=NULL)) && "Process handle must be opened");

	gpSrv->DbgInfo.hDebugReady = CreateEvent(NULL, FALSE, FALSE, NULL);
	// Перенес обработку отладочных событий в отдельную нить, чтобы случайно не заблокироваться с главной
	gpSrv->DbgInfo.hDebugThread = CreateThread(NULL, 0, DebugThread, NULL, 0, &gpSrv->DbgInfo.dwDebugThreadId);
	HANDLE hEvents[2] = {gpSrv->DbgInfo.hDebugReady, gpSrv->DbgInfo.hDebugThread};
	DWORD nReady = WaitForMultipleObjects(countof(hEvents), hEvents, FALSE, INFINITE);

	if (nReady != WAIT_OBJECT_0)
	{
		DWORD nExit = 0;
		GetExitCodeThread(gpSrv->DbgInfo.hDebugThread, &nExit);
		return nExit;
	}

	gpszRunCmd = (wchar_t*)calloc(1,2);

	if (!gpszRunCmd)
	{
		_printf("Can't allocate 1 wchar!\n");
		return CERR_NOTENOUGHMEM1;
	}

	gpszRunCmd[0] = 0;
	gpSrv->DbgInfo.bDebuggerActive = TRUE;

	// And wait for debugger thread completion
	_ASSERTE(gnRunMode == RM_UNDEFINED);
	DWORD nDebugThread = WaitForSingleObject(gpSrv->DbgInfo.hDebugThread, INFINITE);
	_ASSERTE(nDebugThread == WAIT_OBJECT_0); UNREFERENCED_PARAMETER(nDebugThread);

	gbInShutdown = TRUE;
	return 0;
}
Exemplo n.º 4
0
int MyAssertProc(const wchar_t* pszFile, int nLine, const wchar_t* pszTest, bool abNoPipe)
{
#ifdef _DEBUG
	bool lbSkip = false;
	if (lbSkip)
		return 1;
#endif

	HANDLE hHeap = GetProcessHeap();
	MyAssertInfo* pa = (MyAssertInfo*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(MyAssertInfo));
	wchar_t *szExeName = (wchar_t*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, (MAX_PATH+1)*sizeof(wchar_t));
	if (!GetModuleFileNameW(NULL, szExeName, MAX_PATH+1)) szExeName[0] = 0;
	pa->bNoPipe = abNoPipe;
	msprintf(pa->szTitle, countof(pa->szTitle), L"CEAssert PID=%u TID=%u", GetCurrentProcessId(), GetCurrentThreadId());
	msprintf(pa->szDebugInfo, countof(pa->szDebugInfo), L"Assertion in %s\n%s\n\n%s: %i\n\nPress 'Retry' to trap.",
	                szExeName, pszTest ? pszTest : L"", pszFile, nLine);
	DWORD dwCode = 0;

	if (gAllowAssertThread == am_Thread)
	{
		DWORD dwTID;
		HANDLE hThread = CreateThread(NULL, 0, MyAssertThread, pa, 0, &dwTID);

		if (hThread == NULL)
		{
			dwCode = IDRETRY;
			goto wrap;
		}

		WaitForSingleObject(hThread, INFINITE);
		GetExitCodeThread(hThread, &dwCode);
		CloseHandle(hThread);
		goto wrap;
	}
	
#ifdef ASSERT_PIPE_ALLOWED
#ifdef _DEBUG
	if (!abNoPipe && (gAllowAssertThread == am_Pipe))
	{
		HWND hConWnd = GetConEmuHWND(2);
		HWND hGuiWnd = ghConEmuWnd;

		// -- искать - нельзя. Если мы НЕ в ConEmu - нельзя стучаться в другие копии!!!
		//#ifndef CONEMU_MINIMAL
		//if (hGuiWnd == NULL)
		//{
		//	hGuiWnd = FindWindowEx(NULL, NULL, VirtualConsoleClassMain, NULL);
		//}
		//#endif

		if (hGuiWnd && !gbInMyAssertTrap)
		{
			gbInMyAssertTrap = true;
			gbInMyAssertPipe = true;
			gnInMyAssertThread = GetCurrentThreadId();
			ResetEvent(ghInMyAssertTrap);
			
			dwCode = GuiMessageBox(abNoPipe ? NULL : hGuiWnd, pa->szDebugInfo, pa->szTitle, MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_RETRYCANCEL);
			gbInMyAssertTrap = false;
			gbInMyAssertPipe = false;
			SetEvent(ghInMyAssertTrap);
			gnInMyAssertThread = 0;
			goto wrap;
		}
	}

	while (gbInMyAssertPipe && (gnInMyAssertThread != GetCurrentThreadId()))
	{
		Sleep(250);
	}
#endif
#endif

	// В консольных приложениях попытка запустить CreateThread(MyAssertThread) может зависать
	dwCode = MyAssertThread(pa);

wrap:
	if (pa)
		HeapFree(hHeap, 0, pa);
	if (szExeName)
		HeapFree(hHeap, 0, szExeName);
	return (dwCode == IDRETRY) ? -1 : 1;
}
Exemplo n.º 5
0
int ComspecInit()
{
    TODO("Определить код родительского процесса, и если это FAR - запомнить его (для подключения к пайпу плагина)");
    TODO("Размер получить из GUI, если оно есть, иначе - по умолчанию");
    TODO("GUI может скорректировать размер с учетом полосы прокрутки");
    WARNING("CreateFile(CONOUT$) по идее возвращает текущий ScreenBuffer. Можно его самим возвращать в ComspecDone");

    // Правда нужно проверить, что там происходит с ghConOut.Close(),...
    // Размер должен менять сам GUI, через серверный ConEmuC!
#ifdef SHOW_STARTED_MSGBOX
    MessageBox(GetConEmuHWND(2), L"ConEmuC (comspec mode) is about to START", L"ConEmuC.ComSpec", 0);
#endif
    //int nNewBufferHeight = 0;
    //COORD crNewSize = {0,0};
    //SMALL_RECT rNewWindow = gpSrv->sbi.srWindow;
    BOOL lbSbiRc = FALSE;
    gbRootWasFoundInCon = 2; // не добавлять к "Press Enter to close console" - "or wait"
    gbComspecInitCalled = TRUE; // Нельзя вызывать ComspecDone, если не было вызова ComspecInit
    // в режиме ComSpec - запрещено!
    gbAlwaysConfirmExit = FALSE;
    gbAutoDisableConfirmExit = FALSE;
#ifdef _DEBUG
    xf_validate();
    xf_dump_chk();
#endif
    // Это наверное и не нужно, просто для информации...
    lbSbiRc = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &gpSrv->sbi);
#ifdef _DEBUG
    DWORD nErrCode = lbSbiRc ? 0 : GetLastError();
    // Процесс запущен с редиректом вывода?
    _ASSERTE(lbSbiRc || (nErrCode == ERROR_INVALID_HANDLE));
#endif

#if 0
    // 111211 - "-new_console" теперь передается в GUI и исполняется в нем
    // Сюда мы попадаем если был ключик -new_console
    // А этом случае нужно завершить ЭТОТ экземпляр и запустить в ConEmu новую вкладку
    if (gpSrv->bNewConsole)
    {
#ifdef _DEBUG
        xf_validate();
        xf_dump_chk();
#endif
        PROCESS_INFORMATION pi;
        memset(&pi, 0, sizeof(pi));
        STARTUPINFOW si;
        memset(&si, 0, sizeof(si));
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USECOUNTCHARS;
        si.dwXCountChars = gpSrv->sbi.dwSize.X;
        si.dwYCountChars = gpSrv->sbi.dwSize.Y;
        si.wShowWindow = SW_HIDE;
        PRINT_COMSPEC(L"Creating new console for:\n%s\n", gpszRunCmd);
#ifdef _DEBUG
        xf_validate();
        xf_dump_chk();
#endif
        // CREATE_NEW_PROCESS_GROUP - низя, перестает работать Ctrl-C
        // Запускается новый сервер (новая консоль), сюда хуки ставить не надо.
        BOOL lbRc = createProcess(TRUE, NULL, gpszRunCmd, NULL,NULL, TRUE,
                                  NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE,
                                  NULL, NULL, &si, &pi);
        DWORD dwErr = GetLastError();

        if (!lbRc)
        {
            PrintExecuteError(gpszRunCmd, dwErr);
            return CERR_CREATEPROCESS;
        }

#ifdef _DEBUG
        xf_validate();
        xf_dump_chk();
#endif
        //delete psNewCmd; psNewCmd = NULL;
        AllowSetForegroundWindow(pi.dwProcessId);
        PRINT_COMSPEC(L"New console created. PID=%i. Exiting...\n", pi.dwProcessId);
        SafeCloseHandle(pi.hProcess);
        SafeCloseHandle(pi.hThread);
        DisableAutoConfirmExit();
        //gpSrv->nProcessStartTick = GetTickCount() - 2*CHECK_ROOTSTART_TIMEOUT; // менять nProcessStartTick не нужно. проверка только по флажкам
#ifdef _DEBUG
        xf_validate();
        xf_dump_chk();
#endif
        return CERR_RUNNEWCONSOLE;
    }
#endif

    // Если определена ComSpecC - значит ConEmuC переопределил стандартный ComSpec
    // Вернем его
    wchar_t szComSpec[MAX_PATH+1];
    const wchar_t* pszComSpecName;

    //110202 - comspec более не переопределяется
    //if (GetEnvironmentVariable(L"ComSpecC", szComSpec, MAX_PATH) && szComSpec[0] != 0)
    WARNING("TCC/ComSpec");
    if (GetEnvironmentVariable(L"ComSpec", szComSpec, MAX_PATH) && szComSpec[0] != 0)
    {
        //// Только если это (случайно) не conemuc.exe
        //wchar_t* pwszCopy = (wchar_t*)PointToName(szComSpec); //wcsrchr(szComSpec, L'\\');
        ////if (!pwszCopy) pwszCopy = szComSpec;

        //#pragma warning( push )
        //#pragma warning(disable : 6400)
        //if (lstrcmpiW(pwszCopy, L"ConEmuC")==0 || lstrcmpiW(pwszCopy, L"ConEmuC.exe")==0
        //        /*|| lstrcmpiW(pwszCopy, L"ConEmuC64")==0 || lstrcmpiW(pwszCopy, L"ConEmuC64.exe")==0*/)
        //	szComSpec[0] = 0;
        //#pragma warning( pop )

        //if (szComSpec[0])
        //{
        //	SetEnvironmentVariable(L"ComSpec", szComSpec);
        //	SetEnvironmentVariable(L"ComSpecC", NULL);
        //}

        pszComSpecName = (wchar_t*)PointToName(szComSpec);
    }
    else
    {
        WARNING("TCC/ComSpec");
        pszComSpecName = L"cmd.exe";
    }

    lstrcpyn(gpSrv->szComSpecName, pszComSpecName, countof(gpSrv->szComSpecName));

    if (pszComSpecName)
    {
        wchar_t szSelf[MAX_PATH+1];

        if (GetModuleFileName(NULL, szSelf, MAX_PATH))
        {
            lstrcpyn(gpSrv->szSelfName, (wchar_t*)PointToName(szSelf), countof(gpSrv->szSelfName));

            if (!GetAliases(gpSrv->szSelfName, &gpSrv->pszPreAliases, &gpSrv->nPreAliasSize))
            {
                if (gpSrv->pszPreAliases)
                {
                    _wprintf(gpSrv->pszPreAliases);
                    free(gpSrv->pszPreAliases);
                    gpSrv->pszPreAliases = NULL;
                }
            }
        }
    }

    SendStarted();
    //ConOutCloseHandle()
    return 0;
}
Exemplo n.º 6
0
void ComspecDone(int aiRc)
{
#ifdef _DEBUG
    xf_dump_chk();
    xf_validate(NULL);
#endif
    //WARNING("Послать в GUI CONEMUCMDSTOPPED");
    LogSize(NULL, 0, "ComspecDone");

    // Это необходимо делать, т.к. при смене буфера (SetConsoleActiveScreenBuffer) приложением,
    // дескриптор нужно закрыть, иначе conhost может не вернуть предыдущий буфер
    //ConOutCloseHandle()

    // Поддержка алиасов
    if (gpSrv->szComSpecName[0] && gpSrv->szSelfName[0])
    {
        // Скопировать алиасы из cmd.exe в conemuc.exe
        wchar_t *pszPostAliases = NULL;
        DWORD nPostAliasSize;
        BOOL lbChanged = (gpSrv->pszPreAliases == NULL);

        if (!GetAliases(gpSrv->szComSpecName, &pszPostAliases, &nPostAliasSize))
        {
            if (pszPostAliases)
                _wprintf(pszPostAliases);
        }
        else
        {
            if (!lbChanged)
            {
                lbChanged = (gpSrv->nPreAliasSize!=nPostAliasSize);
            }

            if (!lbChanged && gpSrv->nPreAliasSize && gpSrv->pszPreAliases && pszPostAliases)
            {
                lbChanged = memcmp(gpSrv->pszPreAliases,pszPostAliases,gpSrv->nPreAliasSize)!=0;
            }

            if (lbChanged)
            {
                xf_dump_chk();

                if (gnMainServerPID)
                {
                    MCHKHEAP;
                    CESERVER_REQ* pIn = ExecuteNewCmd(CECMD_SAVEALIASES,sizeof(CESERVER_REQ_HDR)+nPostAliasSize);

                    if (pIn)
                    {
                        MCHKHEAP;
                        memmove(pIn->Data, pszPostAliases, nPostAliasSize);
                        MCHKHEAP;
                        CESERVER_REQ* pOut = ExecuteSrvCmd(gnMainServerPID, pIn, GetConEmuHWND(2), FALSE, 0, TRUE);
                        MCHKHEAP;

                        if (pOut) ExecuteFreeResult(pOut);

                        ExecuteFreeResult(pIn);
                        MCHKHEAP;
                    }
                }

                xf_dump_chk();
                wchar_t *pszNewName = pszPostAliases, *pszNewTarget, *pszNewLine;

                while (pszNewName && *pszNewName)
                {
                    pszNewLine = pszNewName + lstrlen(pszNewName);
                    pszNewTarget = wcschr(pszNewName, L'=');

                    if (pszNewTarget)
                    {
                        *pszNewTarget = 0;
                        pszNewTarget++;
                    }

                    if (*pszNewTarget == 0) pszNewTarget = NULL;

                    AddConsoleAlias(pszNewName, pszNewTarget, gpSrv->szSelfName);
                    pszNewName = pszNewLine+1;
                }

                xf_dump_chk();
            }
        }

        if (pszPostAliases)
        {
            free(pszPostAliases);
            pszPostAliases = NULL;
        }
    }

    xf_dump_chk();
    //TODO("Уведомить плагин через пайп (если родитель - FAR) что процесс завершен. Плагин должен считать и запомнить содержимое консоли и только потом вернуть управление в ConEmuC!");
    DWORD dwErr1 = 0; //, dwErr2 = 0;
    HANDLE hOut1 = NULL, hOut2 = NULL;
    BOOL lbRc1 = FALSE, lbRc2 = FALSE;
    CONSOLE_SCREEN_BUFFER_INFO sbi1 = {{0,0}}, sbi2 = {{0,0}};

#ifdef _DEBUG
    HWND hWndCon = GetConEmuHWND(2);
#endif

    // Тут нужна реальная, а не скорректированная информация!
    if (!gbNonGuiMode)
    {
        // Если GUI не сможет через сервер вернуть высоту буфера - это нужно сделать нам!
        lbRc1 = GetConsoleScreenBufferInfo(hOut1 = GetStdHandle(STD_OUTPUT_HANDLE), &sbi1);

        if (!lbRc1)
            dwErr1 = GetLastError();

        xf_dump_chk();
    }

    //PRAGMA_ERROR("Размер должен возвращать сам GUI, через серверный ConEmuC!");
#ifdef SHOW_STARTED_MSGBOX
    MessageBox(GetConEmuHWND(2), L"ConEmuC (comspec mode) is about to TERMINATE", L"ConEmuC.ComSpec", 0);
#endif

#ifdef _DEBUG
    xf_dump_chk();
    xf_validate(NULL);
#endif

    if (!gbNonGuiMode && (gpSrv->dwParentFarPID != 0))
    {
        //// Вернуть размер буфера (высота И ширина)
        //if (gpSrv->sbi.dwSize.X && gpSrv->sbi.dwSize.Y) {
        //	SMALL_RECT rc = {0};
        //	SetConsoleSize(0, gpSrv->sbi.dwSize, rc, "ComspecDone");
        //}
        //ConOutCloseHandle()
        CONSOLE_SCREEN_BUFFER_INFO l_csbi = {{0}};
        lbRc2 = GetConsoleScreenBufferInfo(hOut2 = GetStdHandle(STD_OUTPUT_HANDLE), &l_csbi);

        CESERVER_REQ *pOut = SendStopped(&l_csbi);

        if (pOut)
        {
            if (!pOut->StartStopRet.bWasBufferHeight)
            {
                //gpSrv->sbi.dwSize = pIn->StartStop.sbi.dwSize;
                lbRc1 = FALSE; // Консольное приложение самостоятельно сбросило буферный режим. Не дергаться...
            }
            else
            {
                lbRc1 = TRUE;
            }

            ExecuteFreeResult(pOut);
            pOut = NULL;
        }

        if (!gbWasBufferHeight)
        {
            lbRc2 = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &sbi2);

#ifdef _DEBUG
            if (sbi2.dwSize.Y > 200)
            {
                wchar_t szTitle[128];
                _wsprintf(szTitle, SKIPLEN(countof(szTitle)) L"ConEmuC (PID=%i)", GetCurrentProcessId());
                MessageBox(NULL, L"BufferHeight was not turned OFF", szTitle, MB_SETFOREGROUND|MB_SYSTEMMODAL);
            }
#endif

            if (lbRc1 && lbRc2 && sbi2.dwSize.Y == sbi1.dwSize.Y)
            {
                // GUI не смог вернуть высоту буфера...
                // Это плохо, т.к. фар высоту буфера не меняет и будет сильно глючить на N сотнях строк...
                int nNeedHeight = gpSrv->sbi.dwSize.Y;

                if (nNeedHeight < 10)
                {
                    nNeedHeight = (sbi2.srWindow.Bottom-sbi2.srWindow.Top+1);
                }

                if (sbi2.dwSize.Y != nNeedHeight)
                {
                    _ASSERTE(sbi2.dwSize.Y == nNeedHeight);
                    PRINT_COMSPEC(L"Error: BufferHeight was not changed from %i\n", sbi2.dwSize.Y);
                    SMALL_RECT rc = {0};
                    sbi2.dwSize.Y = nNeedHeight;

                    if (gpLogSize) LogSize(&sbi2.dwSize, 0, ":ComspecDone.RetSize.before");

                    SetConsoleSize(0, sbi2.dwSize, rc, "ComspecDone.Force");

                    if (gpLogSize) LogSize(NULL, 0, ":ComspecDone.RetSize.after");
                }
            }
        }
    }

    if (gpSrv->pszPreAliases) {
        free(gpSrv->pszPreAliases);
        gpSrv->pszPreAliases = NULL;
    }

    //SafeCloseHandle(ghCtrlCEvent);
    //SafeCloseHandle(ghCtrlBreakEvent);
}
Exemplo n.º 7
0
int RunDebugger()
{
	if (!gpSrv->DbgInfo.pDebugTreeProcesses)
	{
		gpSrv->DbgInfo.pDebugTreeProcesses = (MMap<DWORD,CEDebugProcessInfo>*)calloc(1,sizeof(*gpSrv->DbgInfo.pDebugTreeProcesses));
		gpSrv->DbgInfo.pDebugTreeProcesses->Init(1024);
	}

	UpdateDebuggerTitle();

	// Если это новая консоль - увеличить ее размер, для удобства
	if (IsWindowVisible(ghConWnd))
	{
		HANDLE hCon = ghConOut;
		CONSOLE_SCREEN_BUFFER_INFO csbi = {};
		GetConsoleScreenBufferInfo(hCon, &csbi);
		if (csbi.dwSize.X < 260)
		{
			COORD crNewSize = {260, 9999};
			SetConsoleScreenBufferSize(ghConOut, crNewSize);
		}
		//if ((csbi.srWindow.Right - csbi.srWindow.Left + 1) < 120)
		//{
		//	COORD crMax = GetLargestConsoleWindowSize(hCon);
		//	if ((crMax.X - 10) > (csbi.srWindow.Right - csbi.srWindow.Left + 1))
		//	{
		//		COORD crSize = {((int)((crMax.X - 15)/10))*10, min(crMax.Y, (csbi.srWindow.Bottom - csbi.srWindow.Top + 1))};
		//		SMALL_RECT srWnd = {0, csbi.srWindow.Top, crSize.X - 1, csbi.srWindow.Bottom};
		//		MONITORINFO mi = {sizeof(mi)};
		//		GetMonitorInfo(MonitorFromWindow(ghConWnd, MONITOR_DEFAULTTONEAREST), &mi);
		//		RECT rcWnd = {}; GetWindowRect(ghConWnd, &rcWnd);
		//		SetWindowPos(ghConWnd, NULL, min(rcWnd.left,(mi.rcWork.left+50)), rcWnd.top, 0,0, SWP_NOSIZE|SWP_NOZORDER);
		//		SetConsoleSize(9999, crSize, srWnd, "StartDebugger");
		//	}
		//}
	}

	// Вывести в консоль информацию о версии.
	PrintVersion();
	#ifdef SHOW_DEBUG_STARTED_MSGBOX
	wchar_t szInfo[128];
	StringCchPrintf(szInfo, countof(szInfo), L"Attaching debugger...\n" CE_CONEMUC_NAME_W " PID = %u\nDebug PID = %u",
	                GetCurrentProcessId(), gpSrv->dwRootProcess);
	MessageBox(GetConEmuHWND(2), szInfo, CE_CONEMUC_NAME_W L".Debugger", 0);
	#endif

	if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL)
	{
		int iAttachRc = AttachRootProcessHandle();
		if (iAttachRc != 0)
			return iAttachRc;
	}
	else
	{
		_ASSERTE(!gpSrv->DbgInfo.bDebuggerActive);
	}

	gpszRunCmd = (wchar_t*)calloc(1,sizeof(*gpszRunCmd));
	if (!gpszRunCmd)
	{
		_printf("Can't allocate 1 wchar!\n");
		return CERR_NOTENOUGHMEM1;
	}

	_ASSERTE(((gpSrv->hRootProcess!=NULL) || (gpSrv->DbgInfo.pszDebuggingCmdLine!=NULL)) && "Process handle must be opened");

	// Если просили сделать дамп нескольких процессов - нужно сразу уточнить его тип
	if (gpSrv->DbgInfo.bDebugMultiProcess && (gpSrv->DbgInfo.nDebugDumpProcess == 1))
	{
		// 2 - minidump, 3 - fulldump
		int nConfirmDumpType = ConfirmDumpType(gpSrv->dwRootProcess, NULL);
		if (nConfirmDumpType < 2)
		{
			// Отмена
			return CERR_CANTSTARTDEBUGGER;
		}
		gpSrv->DbgInfo.nDebugDumpProcess = nConfirmDumpType;
	}

	// gpSrv->DbgInfo.bDebuggerActive must be set in DebugThread

	// Run DebugThread
	gpSrv->DbgInfo.hDebugReady = CreateEvent(NULL, FALSE, FALSE, NULL);
	// Перенес обработку отладочных событий в отдельную нить, чтобы случайно не заблокироваться с главной
	gpSrv->DbgInfo.hDebugThread = CreateThread(NULL, 0, DebugThread, NULL, 0, &gpSrv->DbgInfo.dwDebugThreadId);
	HANDLE hEvents[2] = {gpSrv->DbgInfo.hDebugReady, gpSrv->DbgInfo.hDebugThread};
	DWORD nReady = WaitForMultipleObjects(countof(hEvents), hEvents, FALSE, INFINITE);

	if (nReady != WAIT_OBJECT_0)
	{
		DWORD nExit = 0;
		GetExitCodeThread(gpSrv->DbgInfo.hDebugThread, &nExit);
		return nExit;
	}

	// gpSrv->DbgInfo.bDebuggerActive was set in DebugThread

	// And wait for debugger thread completion
	_ASSERTE(gnRunMode == RM_UNDEFINED);
	DWORD nDebugThread = WaitForSingleObject(gpSrv->DbgInfo.hDebugThread, INFINITE);
	_ASSERTE(nDebugThread == WAIT_OBJECT_0); UNREFERENCED_PARAMETER(nDebugThread);

	gbInShutdown = TRUE;
	return 0;
}