Example #1
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"); // Юзер может чего-то свое делать с распакованными файлами
}
Example #2
0
// IDYES    - Close All consoles
// IDNO     - Close active console only
// IDCANCEL - As is
int ConfirmCloseConsoles(const ConfirmCloseParam& Parm)
{
    DontEnable de;

    wchar_t szText[512], *pszText;
    int nBtn = IDCANCEL;

    static LONG lCounter = 0;
    LONG l = InterlockedIncrement(&lCounter);
    if (l > 1)
    {
        if (l == 2)
        {
            _ASSERTE(FALSE && "Confirm stack overflow!");
        }
        goto wrap;
    }

    if (Parm.rpLeaveConEmuOpened) *Parm.rpLeaveConEmuOpened = false;

    // Use TaskDialog?
    if (gOSVer.dwMajorVersion >= 6)
    {
        // must be already initialized: CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

        wchar_t szMessage[128];
        lstrcpyn(szMessage,
                 Parm.asSingleConsole ? Parm.asSingleConsole : Parm.bForceKill ? L"Confirm killing?" : L"Confirm closing?",
                 countof(szMessage));

        wchar_t szWWW[MAX_PATH];
        _wsprintf(szWWW, SKIPLEN(countof(szWWW)) L"<a href=\"%s\">%s</a>", gsHomePage, gsHomePage);

        wchar_t szCloseAll[MAX_PATH*2];
        wchar_t *pszText;
        if (Parm.asSingleConsole)
        {
            wcscpy_c(szCloseAll, L"Yes\n");
            pszText = szCloseAll + _tcslen(szCloseAll);
            lstrcpyn(pszText, Parm.asSingleTitle, min(MAX_PATH,(countof(szCloseAll)-(pszText-szCloseAll))));
            pszText += _tcslen(pszText);
        }
        else
        {
            _wsprintf(szCloseAll, SKIPLEN(countof(szCloseAll))
                      (Parm.bGroup && (Parm.nConsoles>1))
                      ? ((Parm.bGroup == ConfirmCloseParam::eGroup)
                         ? L"Close group (%u console%s)"
                         : L"Close (%u console%s)")
                      : L"Close all %u console%s.",
                      Parm.nConsoles, (Parm.nConsoles>1)?L"s":L"");
            pszText = szCloseAll + _tcslen(szCloseAll);
        }
        if ((Parm.asSingleConsole == NULL) || (Parm.nOperations || Parm.nUnsavedEditors))
        {
            //if (nOperations)
            {
                _wsprintf(pszText, SKIPLEN(countof(szCloseAll)-(pszText-szCloseAll)) L"\nIncomplete operations: %i", Parm.nOperations);
                pszText += _tcslen(pszText);
            }
            //if (nUnsavedEditors)
            {
                _wsprintf(pszText, SKIPLEN(countof(szCloseAll)-(pszText-szCloseAll)) L"\nUnsaved editor windows: %i", Parm.nUnsavedEditors);
                pszText += _tcslen(pszText);
            }
        }

        wchar_t szCloseOne[MAX_PATH];
        wcscpy_c(szCloseOne, L"Close active console only");
        if (Parm.nConsoles > 1)
        {
            CVConGuard VCon;
            int iCon = gpConEmu->GetActiveVCon(&VCon);
            if (iCon >= 0)
            {
                pszText = szCloseOne + _tcslen(szCloseOne);
                _wsprintf(pszText, SKIPLEN(countof(szCloseOne)-(pszText-szCloseOne)) L"\n#%u: ", (iCon+1));
                pszText += _tcslen(pszText);
                lstrcpyn(pszText, VCon->RCon()->GetTitle(true), countof(szCloseOne)-(pszText-szCloseOne));
            }
        }

        const wchar_t* szCancel = L"Cancel\nDon't close anything";


        int nButtonPressed                  = 0;
        TASKDIALOGCONFIG config             = {sizeof(config)};
        TASKDIALOG_BUTTON buttons[]   = {
            { IDYES,    szCloseAll },
            { IDNO,     szCloseOne },
            { IDCANCEL, szCancel },
        };
        config.cButtons                     = countof(buttons);
        if (Parm.nConsoles <= 1)
        {
            buttons[1] = buttons[2];
            config.cButtons--;
        }

        config.hwndParent                   = ghWnd;
        config.hInstance                    = NULL /*g_hInstance*/;
        config.dwFlags                      = TDF_USE_HICON_MAIN|TDF_USE_COMMAND_LINKS|TDF_ALLOW_DIALOG_CANCELLATION
                                              |TDF_ENABLE_HYPERLINKS; //|TDIF_SIZE_TO_CONTENT|TDF_CAN_BE_MINIMIZED;
        //config.pszMainIcon                  = MAKEINTRESOURCE(IDI_ICON1);
        config.hMainIcon                    = hClassIcon;
        config.pszWindowTitle               = gpConEmu->GetDefaultTitle();
        config.pszMainInstruction           = szMessage;
        //config.pszContent                 = L"...";
        config.pButtons                     = buttons;
        config.nDefaultButton               = IDYES;
        config.pszFooter                    = szWWW;

        //{
        //	config.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED;
        //	config.pszVerificationText = L"Text on checkbox";
        //}

        HRESULT hr = TaskDialog(&config, &nButtonPressed, NULL, NULL);

        if (hr == S_OK)
        {
            switch (nButtonPressed)
            {
            case IDCANCEL: // user cancelled the dialog
            case IDYES:
            case IDNO:
                nBtn = nButtonPressed;
                goto wrap;

            default:
                _ASSERTE(nButtonPressed==IDCANCEL||nButtonPressed==IDYES||nButtonPressed==IDNO);
                break; // should never happen
            }
        }
    }

    // Иначе - через стандартный MessageBox

    if (Parm.asSingleConsole)
    {
        lstrcpyn(szText,
                 Parm.asSingleConsole ? Parm.asSingleConsole : Parm.bForceKill ? L"Confirm killing?" : L"Confirm closing?",
                 min(128,countof(szText)));
        wcscat_c(szText, L"\r\n\r\n");
        int nLen = lstrlen(szText);
        lstrcpyn(szText+nLen, Parm.asSingleTitle, countof(szText)-nLen);
    }
    else
    {
        _wsprintf(szText, SKIPLEN(countof(szText)) L"About to close %u console%s.\r\n", Parm.nConsoles, (Parm.nConsoles>1)?L"s":L"");
    }
    pszText = szText+_tcslen(szText);

    if (Parm.nOperations || Parm.nUnsavedEditors)
    {
        *(pszText++) = L'\r';
        *(pszText++) = L'\n';
        *(pszText) = 0;

        if (Parm.nOperations)
        {
            _wsprintf(pszText, SKIPLEN(countof(szText)-(pszText-szText)) L"Incomplete operations: %i\r\n", Parm.nOperations);
            pszText += _tcslen(pszText);
        }
        if (Parm.nUnsavedEditors)
        {
            _wsprintf(pszText, SKIPLEN(countof(szText)-(pszText-szText)) L"Unsaved editor windows: %i\r\n", Parm.nUnsavedEditors);
            pszText += _tcslen(pszText);
        }
    }

    if (Parm.nConsoles > 1)
    {
        wcscat_c(szText,
                 L"\r\nPress button <No> to close active console only\r\n"
                 L"\r\nProceed with close ConEmu?");
    }

    nBtn = MsgBox(szText, (/*rpPanes ? MB_OKCANCEL :*/ (Parm.nConsoles>1) ? MB_YESNOCANCEL : MB_OKCANCEL)|MB_ICONEXCLAMATION,
                  gpConEmu->GetDefaultTitle(), ghWnd);

    if (nBtn == IDOK)
    {
        nBtn = IDYES; // для однозначности
    }

wrap:
    InterlockedDecrement(&lCounter);
    return nBtn;
}
Example #3
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);
}
Example #4
0
int main(int argc, char** argv)
{
	gn_argc = argc; gp_argv = argv;

	int iRc = 0;
	HMODULE hConEmu = NULL;
	wchar_t szErrInfo[200];
	DWORD dwErr;
	typedef int (__stdcall* ConsoleMain2_t)(BOOL abAlternative);
	ConsoleMain2_t lfConsoleMain2;

	#ifdef _DEBUG
	HMODULE hConEmuHk = GetModuleHandle(WIN3264TEST(L"ConEmuHk.dll",L"ConEmuHk64.dll"));
	_ASSERTE(hConEmuHk==NULL && "Hooks must not be loaded into ConEmuC[64].exe!");
	#endif

	#if defined(SHOW_STARTED_MSGBOX)
	if (!IsDebuggerPresent())
	{
		wchar_t szTitle[100]; _wsprintf(szTitle, SKIPLEN(countof(szTitle)) WIN3264TEST(L"ConEmuC",L"ConEmuC64") L" Loaded (PID=%i)", GetCurrentProcessId());
		const wchar_t* pszCmdLine = GetCommandLineW();
		MessageBox(NULL,pszCmdLine,szTitle,0);
	}
	#endif

	// Обязательно, иначе по CtrlC мы свалимся
	SetConsoleCtrlHandler((PHANDLER_ROUTINE)HandlerRoutine, true);

	#ifdef _DEBUG
	UnitTests();
	#endif

	// Some command we can process internally
	if (ProcessCommandLine(iRc, hConEmu))
	{
		// Done, exiting
		goto wrap;
	}

	// Otherwise - do the full cycle
	if (!hConEmu)
		hConEmu = LoadLibrary(WIN3264TEST(L"ConEmuCD.dll",L"ConEmuCD64.dll"));
	dwErr = GetLastError();

	if (!hConEmu)
	{
		_wsprintf(szErrInfo, SKIPLEN(countof(szErrInfo))
		           L"Can't load library \"%s\", ErrorCode=0x%08X\n",
		           WIN3264TEST(L"ConEmuCD.dll",L"ConEmuCD64.dll"),
		           dwErr);
		_wprintf(szErrInfo);
		_ASSERTE(FALSE && "LoadLibrary failed");
		iRc = CERR_CONEMUHK_NOTFOUND;
		goto wrap;
	}

	// Загрузить функи из ConEmuHk
	lfConsoleMain2 = (ConsoleMain2_t)GetProcAddress(hConEmu, "ConsoleMain2");
	gfHandlerRoutine = (PHANDLER_ROUTINE)GetProcAddress(hConEmu, "HandlerRoutine");

	if (!lfConsoleMain2 || !gfHandlerRoutine)
	{
		dwErr = GetLastError();
		_wsprintf(szErrInfo, SKIPLEN(countof(szErrInfo))
		           L"Procedure \"%s\"  not found in library \"%s\"",
		           lfConsoleMain2 ? L"HandlerRoutine" : L"ConsoleMain2",
		           WIN3264TEST(L"ConEmuCD.dll",L"ConEmuCD64.dll"));
		_wprintf(szErrInfo);
		_ASSERTE(FALSE && "GetProcAddress failed");
		FreeLibrary(hConEmu);
		iRc = CERR_CONSOLEMAIN_NOTFOUND;
		goto wrap;
	}

	// Main dll entry point for Server & ComSpec
	iRc = lfConsoleMain2(0/*WorkMode*/);
	// Exiting
	gfHandlerRoutine = NULL;
	//FreeLibrary(hConEmu); -- Shutdown Server/Comspec уже выполнен
wrap:
	//-- bottle neck: relatively long deinitialization
	ExitProcess(iRc);
	return iRc;
}
Example #5
0
//
//	IDataObject::SetData
//
HRESULT __stdcall CDataObject::SetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium,  BOOL fRelease)
{
	_ASSERTE(pMedium && pMedium->pUnkForRelease==NULL);

	#ifdef _DEBUG
	LPCWSTR pszName = GetFormatName(pFormatEtc->cfFormat, true);
	DWORD nData = (DWORD)-1;
	if (lstrcmp(pszName, L"IsShowingLayered")==0
		|| lstrcmp(pszName, L"IsShowingText")==0
		|| lstrcmp(pszName, L"DragContext")==0
		|| lstrcmp(pszName, L"UsingDefaultDragImage")==0
		|| lstrcmp(pszName, L"DragSourceHelperFlags")==0
		|| lstrcmp(pszName, L"DragWindow")==0
		|| lstrcmp(pszName, L"DisableDragText")==0
		)
	{
		LPDWORD pdw = (LPDWORD)GlobalLock(pMedium->hGlobal);
		if (pdw)
		{
			nData = *pdw;
		}
		GlobalUnlock(pMedium->hGlobal);
	}

	wchar_t szDbg[255];
	_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"CDataObject::SetData {cfFormat=%s, lindex=%i, tymed=x%02X(%u)}, {tymed=x%02X}",
		GetFormatName(pFormatEtc->cfFormat), pFormatEtc->lindex, pFormatEtc->tymed, pFormatEtc->tymed, pMedium->tymed);
	if (nData != (DWORD)-1)
	{
		int nLen = lstrlen(szDbg);
		_wsprintf(szDbg+nLen, SKIPLEN(countof(szDbg)-nLen) L", Data=x%02X(%u)", nData, nData);
	}
	wcscat_c(szDbg, L"\n");
	DEBUGSTRDATA(szDbg);
	#endif

	DEBUGTEST(bool bNew = false);
	LONG nIndex = LookupFormatEtc(pFormatEtc);

	if (nIndex >= 0)
	{
		if ((pMedium != &(m_Data[nIndex].StgMedium)) && (pMedium->hGlobal != &(m_Data[nIndex].StgMedium)))
		{
			if (m_Data[nIndex].fRelease)
			{
				ReleaseStgMedium(&m_Data[nIndex].StgMedium);
			}
			else
			{
				ZeroStruct(m_Data[nIndex].StgMedium);
			}
		}
		else
		{
			Assert((pMedium != &(m_Data[nIndex].StgMedium)) && (pMedium->hGlobal != &(m_Data[nIndex].StgMedium)));
		}
	}
	else //	if (nIndex < 0)
	{
		DEBUGTEST(bNew = true);
		_ASSERTE(nIndex < 0);

		DragData newItem = {};
		newItem.FormatEtc = *pFormatEtc;
		nIndex = m_Data.push_back(newItem);
	}

	m_Data[nIndex].fUsed = TRUE;
	m_Data[nIndex].fRelease = fRelease;
	m_Data[nIndex].StgMedium = *pMedium;

	return S_OK;
}
Example #6
0
LRESULT CConEmuChild::ChildWndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)
{
	LRESULT result = 0;

	// Logger
	MSG msgStr = {hWnd, messg, wParam, lParam};
	ConEmuMsgLogger::Log(msgStr, ConEmuMsgLogger::msgCanvas);

	if (gpSetCls->isAdvLogging >= 4)
	{
		gpConEmu->LogMessage(hWnd, messg, wParam, lParam);
	}

	CVConGuard guard;
	CVirtualConsole* pVCon = NULL;
	if (messg == WM_CREATE || messg == WM_NCCREATE)
	{
		LPCREATESTRUCT lp = (LPCREATESTRUCT)lParam;
		guard = (CVirtualConsole*)lp->lpCreateParams;
		pVCon = guard.VCon();
		if (pVCon)
		{
			gVConDcMap.Set(hWnd, pVCon);

			pVCon->m_TAutoCopy.Init(hWnd, TIMER_AUTOCOPY, TIMER_AUTOCOPY_DELAY);

			pVCon->m_TScrollShow.Init(hWnd, TIMER_SCROLL_SHOW, TIMER_SCROLL_SHOW_DELAY);
			pVCon->m_TScrollHide.Init(hWnd, TIMER_SCROLL_HIDE, TIMER_SCROLL_HIDE_DELAY);
			#ifndef SKIP_HIDE_TIMER
			pVCon->m_TScrollCheck.Init(hWnd, TIMER_SCROLL_CHECK, TIMER_SCROLL_CHECK_DELAY);
			#endif
		}
	}
	else if (hWnd != ghDcInDestroing)
	{
		if (!gVConDcMap.Get(hWnd, &pVCon) || !guard.Attach(pVCon))
			pVCon = NULL;
	}


	if (messg == WM_SYSCHAR)
	{
		_ASSERTE(FALSE); // по идее, фокуса тут быть не должно
		// Чтобы не пищало
		result = TRUE;
		goto wrap;
	}

	if (!pVCon)
	{
		_ASSERTE(pVCon!=NULL || hWnd==ghDcInDestroing);
		result = DefWindowProc(hWnd, messg, wParam, lParam);
		goto wrap;
	}

	switch (messg)
	{
		case WM_SHOWWINDOW:
			{
				#ifdef _DEBUG
				HWND hGui = pVCon->GuiWnd();
				if (hGui)
				{
					_ASSERTE(((wParam==0) || pVCon->RCon()->isGuiForceConView()) && "Show DC while GuiWnd exists");
				}
				#endif
				result = DefWindowProc(hWnd, messg, wParam, lParam);
				break;
			}
		case WM_SETFOCUS:
			// Если в консоли работает "GUI" окно (GUI режим), то фокус нужно отдать туда.
			{
				// Фокус должен быть в главном окне! За исключением случая работы в GUI режиме.
				pVCon->setFocus();
			}
			return 0;
		case WM_ERASEBKGND:
			result = 0;
			break;
		case WM_PAINT:
			result = pVCon->OnPaint();
			break;
		case WM_PRINTCLIENT:
			if (wParam && (lParam & PRF_CLIENT))
			{
				pVCon->PrintClient((HDC)wParam, false, NULL);
			}
			break;
		case WM_SIZE:
			#ifdef _DEBUG
			{
				RECT rc; GetClientRect(hWnd, &rc);
				short cx = LOWORD(lParam);
				rc.left = rc.left;
			}
			#endif
			result = pVCon->OnSize(wParam, lParam);
			break;
		case WM_MOVE:
			result = pVCon->OnMove(wParam, lParam);
			break;
		case WM_CREATE:
			break;
		case WM_KEYDOWN:
		case WM_KEYUP:
		case WM_SYSKEYDOWN:
		case WM_SYSKEYUP:
		case WM_MOUSEWHEEL:
		case WM_ACTIVATE:
		case WM_ACTIVATEAPP:
			//case WM_MOUSEACTIVATE:
		case WM_KILLFOCUS:
			//case WM_SETFOCUS:
		case WM_MOUSEMOVE:
		case WM_RBUTTONDOWN:
		case WM_RBUTTONUP:
		case WM_MBUTTONDOWN:
		case WM_MBUTTONUP:
		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		case WM_LBUTTONDBLCLK:
		case WM_MBUTTONDBLCLK:
		case WM_RBUTTONDBLCLK:
		case WM_XBUTTONDOWN:
		case WM_XBUTTONUP:
		case WM_XBUTTONDBLCLK:
		case WM_VSCROLL:
			// Вся обработка в родителе
			{
				switch (messg)
				{
					case WM_VSCROLL:
						switch (LOWORD(wParam))
						{
						case SB_THUMBTRACK:
						case SB_THUMBPOSITION:
							pVCon->mb_VTracking = TRUE;
							break;
						case SB_ENDSCROLL:
							pVCon->mb_VTracking = FALSE;
							break;
						}
						pVCon->RCon()->OnSetScrollPos(wParam);
						break;

					case WM_LBUTTONUP:
						pVCon->mb_VTracking = FALSE;
						break;
				}

				TODO("Обработка ghWndWork");
				HWND hParent = ghWnd;
				static bool bInFixStyle = false;
				if (!bInFixStyle)
				{
					hParent = GetParent(hWnd);
					if (hParent != ghWnd)
					{
						// Неправомерные действия плагинов фара?
						bInFixStyle = true;
						_ASSERTE(GetParent(hWnd)==ghWnd);
						SetParent(hWnd, ghWnd);
						bInFixStyle = false;
						hParent = ghWnd;
					}

					DWORD curStyle = GetWindowLong(hWnd, GWL_STYLE);

					if ((curStyle & CRITICAL_DCWND_STYLES) != (pVCon->mn_WndDCStyle & CRITICAL_DCWND_STYLES))
					{
						// DC window styles was changed externally!
						bInFixStyle = true;
						_ASSERTEX(((curStyle & CRITICAL_DCWND_STYLES) != (pVCon->mn_WndDCStyle & CRITICAL_DCWND_STYLES)));
						SetWindowLongPtr(hWnd, GWL_STYLE, (LONG_PTR)(DWORD_PTR)pVCon->mn_WndDCStyle);
						bInFixStyle = false;
					}
				}

				if (messg >= WM_MOUSEFIRST && messg <= WM_MOUSELAST)
				{
					POINT pt = {LOWORD(lParam),HIWORD(lParam)};
					MapWindowPoints(hWnd, hParent, &pt, 1);
					lParam = MAKELONG(pt.x,pt.y);
				}

				result = gpConEmu->WndProc(hParent, messg, wParam, lParam);
			}
			break;
		case WM_IME_NOTIFY:
			break;
		case WM_INPUTLANGCHANGE:
		case WM_INPUTLANGCHANGEREQUEST:
			{
				#ifdef _DEBUG
				if (IsDebuggerPresent())
				{
					WCHAR szMsg[128];
					_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"InChild %s(CP:%i, HKL:0x%08X)\n",
							  (messg == WM_INPUTLANGCHANGE) ? L"WM_INPUTLANGCHANGE" : L"WM_INPUTLANGCHANGEREQUEST",
							  (DWORD)wParam, (DWORD)lParam);
					DEBUGSTRLANG(szMsg);
				}
				#endif
				result = DefWindowProc(hWnd, messg, wParam, lParam);
			} break;

#ifdef _DEBUG
		case WM_WINDOWPOSCHANGING:
			{
				WINDOWPOS* pwp = (WINDOWPOS*)lParam;
				result = DefWindowProc(hWnd, messg, wParam, lParam);
			}
			return result;
		case WM_WINDOWPOSCHANGED:
			{
				WINDOWPOS* pwp = (WINDOWPOS*)lParam;
				result = DefWindowProc(hWnd, messg, wParam, lParam);
			}
			break;
#endif
		case WM_SETCURSOR:
			{
				gpConEmu->WndProc(hWnd, messg, wParam, lParam);

				//if (!result)
				//	result = DefWindowProc(hWnd, messg, wParam, lParam);
			}
			// If an application processes this message, it should return TRUE to halt further processing or FALSE to continue.
			break;

		case WM_SYSCOMMAND:
			// -- лишние ограничения, похоже
			result = DefWindowProc(hWnd, messg, wParam, lParam);
			//if (wParam >= SC_SIZE && wParam <= SC_CONTEXTHELP/*0xF180*/)
			//{
			//	// Изменение размеров/максимизация/и т.п. окна консоли - запрещена
			//	_ASSERTE(!(wParam >= SC_SIZE && wParam <= SC_CONTEXTHELP));
			//}
			//else
			//{
			//	// По идее, сюда ничего приходить больше не должно
			//	_ASSERTE(FALSE);
			//}
			break;

		case WM_TIMER:
			{
				switch(wParam)
				{
				#ifndef SKIP_HIDE_TIMER // Не будем прятать по таймеру - только по движению мышки
				case TIMER_SCROLL_CHECK:

					if (pVCon->mb_Scroll2Visible)
					{
						if (!pVCon->CheckMouseOverScroll())
						{
							pVCon->HideScroll(FALSE/*abImmediate*/);
						}
					}

					break;
				#endif

				case TIMER_SCROLL_SHOW:

					if (pVCon->CheckMouseOverScroll() || pVCon->CheckScrollAutoPopup())
						pVCon->ShowScroll(TRUE/*abImmediate*/);
					else
						pVCon->mb_Scroll2Visible = FALSE;

					if (pVCon->m_TScrollShow.IsStarted())
						pVCon->m_TScrollShow.Stop();

					break;

				case TIMER_SCROLL_HIDE:

					if (!pVCon->CheckMouseOverScroll())
						pVCon->HideScroll(TRUE/*abImmediate*/);
					else
						pVCon->mb_Scroll2Visible = TRUE;

					if (pVCon->m_TScrollHide.IsStarted())
						pVCon->m_TScrollHide.Stop();

					break;

				case TIMER_AUTOCOPY:
					pVCon->SetAutoCopyTimer(false);
					if (!isPressed(VK_LBUTTON))
					{
						pVCon->RCon()->AutoCopyTimer();
					}
					break;
				}
				break;
			} // case WM_TIMER:

		case WM_GESTURENOTIFY:
		case WM_GESTURE:
			{
				gpConEmu->ProcessGestureMessage(hWnd, messg, wParam, lParam, result);
				break;
			} // case WM_GESTURE, WM_GESTURENOTIFY

		default:

			// Сообщение приходит из ConEmuPlugin
			if (messg == pVCon->mn_MsgTabChanged)
			{
				if (gpSet->isTabs)
				{
					//изменились табы, их нужно перечитать
#ifdef MSGLOGGER
					WCHAR szDbg[128]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"Tabs:Notified(%i)\n", (DWORD)wParam);
					DEBUGSTRTABS(szDbg);
#endif
					TODO("здесь хорошо бы вместо OnTimer реально обновить mn_TopProcessID")
					// иначе во время запуска PID фара еще может быть не известен...
					//gpConEmu->OnTimer(0,0); не получилось. индекс конмана не менялся, из-за этого индекс активного фара так и остался 0
					WARNING("gpConEmu->mp_TabBar->Retrieve() ничего уже не делает вообще");
					_ASSERTE(FALSE);
					gpConEmu->mp_TabBar->Retrieve();
				}
			}
			else if (messg == pVCon->mn_MsgPostFullPaint)
			{
				pVCon->Redraw();
			}
			else if (messg == pVCon->mn_MsgSavePaneSnapshoot)
			{
				pVCon->SavePaneSnapshoot();
			}
			else if (messg == pVCon->mn_MsgDetachPosted)
			{
				pVCon->RCon()->Detach(true, (lParam == 1));
			}
			else if (messg == gn_MsgVConTerminated)
			{
				CVirtualConsole* pVCon = (CVirtualConsole*)lParam;

				#ifdef _DEBUG
				int i = -100;
				wchar_t szDbg[200];
				{
					lstrcpy(szDbg, L"gn_MsgVConTerminated");

					i = CVConGroup::GetVConIndex(pVCon);
					if (i >= 1)
					{
						ConEmuTab tab = {0};
						pVCon->RCon()->GetTab(0, &tab);
						tab.Name[128] = 0; // чтобы не вылезло из szDbg
						wsprintf(szDbg+_tcslen(szDbg), L": #%i: %s", i, tab.Name);
					}

					lstrcat(szDbg, L"\n");
					DEBUGSTRCONS(szDbg);
				}
				#endif

				// Do not "Guard" lParam here, validation will be made in ProcessVConClosed
				CConEmuChild::ProcessVConClosed(pVCon, TRUE);
				return 0;
			}
			#ifdef _DEBUG
			else if (messg == pVCon->mn_MsgCreateDbgDlg)
			{
				pVCon->CreateDbgDlg();
			}
			#endif
			else if (messg)
			{
				result = DefWindowProc(hWnd, messg, wParam, lParam);
			}
	}

wrap:
	return result;
}
Example #7
0
bool CConEmuUpdate::QueryConfirmation(CConEmuUpdate::UpdateStep step, LPCWSTR asParm)
{
	if (mb_RequestTerminate)
	{
		return false;
	}

	bool lbRc = false;
	wchar_t* pszMsg = NULL;
	size_t cchMax;

	switch (step)
	{
	case us_ConfirmDownload:
		{
			cchMax = _tcslen(asParm)+300;
			pszMsg = (wchar_t*)malloc(cchMax*sizeof(*pszMsg));

			if (mb_ManualCallMode == 2)
			{
				lbRc = true;
			}
			else if (mp_Set->isUpdateConfirmDownload || mb_ManualCallMode)
			{
				wchar_t* pszDup = lstrdup(asParm);
				wchar_t* pszFile = pszDup ? wcsrchr(pszDup, L'/') : NULL;
				if (pszFile)
				{
					pszFile[1] = 0;
					pszFile = (wchar_t*)(asParm + (pszFile - pszDup + 1));
					asParm = pszDup;
				}

				_wsprintf(pszMsg, SKIPLEN(cchMax) L"New %s version available: %s\n\nVersions on server\n%s\n\n%s\n%s\n\nDownload?",
					(mp_Set->isUpdateUseBuilds==1) ? L"stable" : (mp_Set->isUpdateUseBuilds==3) ? L"preview" : L"developer",
					ms_NewVersion,
					ms_VerOnServer,
					asParm ? asParm : L"",
					pszFile ? pszFile : L"");
				SafeFree(pszDup);

				m_UpdateStep = step;
				lbRc = QueryConfirmationInt(pszMsg);
			}
			else
			{
				_wsprintf(pszMsg, SKIPLEN(cchMax) L"New %s version available: %s\nClick here to download",
					(mp_Set->isUpdateUseBuilds==1) ? L"stable" : (mp_Set->isUpdateUseBuilds==3) ? L"preview" : L"developer",
					ms_NewVersion);
				Icon.ShowTrayIcon(pszMsg, tsa_Source_Updater);

				lbRc = false;
			}
		}
		break;
	case us_ConfirmUpdate:
		cchMax = 512;
		pszMsg = (wchar_t*)malloc(cchMax*sizeof(*pszMsg));
		_wsprintf(pszMsg, SKIPLEN(cchMax)
			L"Do you want to close ConEmu and\n"
			L"update to %s version %s?",
			mb_DroppedMode ? L"dropped" : (mp_Set->isUpdateUseBuilds==1) ? L"new stable"
			: (mp_Set->isUpdateUseBuilds==3) ? L"new preview" : L"new developer", ms_NewVersion);
		m_UpdateStep = step;
		lbRc = QueryConfirmationInt(pszMsg);
		break;
	default:
		_ASSERTE(step==us_ConfirmDownload);
		lbRc = false;
	}

	SafeFree(pszMsg);

	return lbRc;
}
Example #8
0
// вызывается при получении нового Background (CECMD_SETBACKGROUND) из плагина
// и для очистки при закрытии (рестарте) консоли
SetBackgroundResult CBackground::SetPluginBackgroundImageData(CESERVER_REQ_SETBACKGROUND* apImgData, bool&/*OUT*/ bUpdate)
{
	if (!this) return esbr_Unexpected;

	//if (!isMainThread())
	//{

	//// При вызове из серверной нити (только что пришло из плагина)
	//if (mp_RCon->isConsoleClosing())
	//	return esbr_ConEmuInShutdown;

	bool bIsEmf = false;
	UINT nSize = IsBackgroundValid(apImgData, &bIsEmf);

	if (!nSize)
	{
		_ASSERTE(FALSE && "!IsBackgroundValid(apImgData, NULL)");
		return esbr_InvalidArg;
	}

	if (!apImgData->bEnabled)
	{
		//mb_BkImgDelete = TRUE;
		mb_BkImgExist = FALSE;
		NeedBackgroundUpdate();
		//Update(true/*bForce*/);
		bUpdate = true;
		return gpSet->isBgPluginAllowed ? esbr_OK : esbr_PluginForbidden;
	}

#ifdef _DEBUG

	if ((GetKeyState(VK_SCROLL) & 1))
	{
		static UINT nBackIdx = 0;
		wchar_t szFileName[32];
		_wsprintf(szFileName, SKIPLEN(countof(szFileName)) L"PluginBack_%04u.bmp", nBackIdx++);
		char szAdvInfo[512];
		BITMAPINFOHEADER* pBmp = (BITMAPINFOHEADER*)((&apImgData->bmp)+1);
		_wsprintfA(szAdvInfo, SKIPLEN(countof(szAdvInfo)) "\r\nnType=%i, bEnabled=%i,\r\nWidth=%i, Height=%i, Bits=%i, Encoding=%i\r\n",
		           apImgData->nType, apImgData->bEnabled,
		           pBmp->biWidth, pBmp->biHeight, pBmp->biBitCount, pBmp->biCompression);
		HANDLE hFile = CreateFile(szFileName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

		if (hFile != INVALID_HANDLE_VALUE)
		{
			DWORD cbWrite;
			WriteFile(hFile, &apImgData->bmp, apImgData->bmp.bfSize, &cbWrite, 0);
			WriteFile(hFile, szAdvInfo, lstrlenA(szAdvInfo), &cbWrite, 0);
			CloseHandle(hFile);
		}
	}

#endif

	//	// Поскольку вызов асинхронный (сразу возвращаем в плагин), то нужно сделать копию данных
	//	CESERVER_REQ_SETBACKGROUND* pCopy = (CESERVER_REQ_SETBACKGROUND*)malloc(nSize);
	//	if (!pCopy)
	//		return esbr_Unexpected;
	//	memmove(pCopy, apImgData, nSize);
	//	// Запомнить последний актуальный, и послать в главную нить
	//	mp_LastImgData = pCopy;
	//	mb_BkImgDelete = FALSE;
	//	gpConEmu->PostSetBackground(this, pCopy);
	//	return gpSet->isBgPluginAllowed ? esbr_OK : esbr_PluginForbidden;
	//}

	//// Если вызов пришел во время закрытия консоли - игнорировать
	//if (mp_RCon->isConsoleClosing())
	////// Этот apImgData уже не актуален. Во время обработки сообщения пришел новый Background.
	////	|| (mp_LastImgData && mp_LastImgData != apImgData))
	//{
	//	free(apImgData);
	//	return esbr_Unexpected;
	//}

	// Ссылку на актуальный - не сбрасываем. Она просто информационная, и есть возможность наколоться с многопоточностью
	//mp_LastImgData = NULL;

	//UINT nSize = IsBackgroundValid(apImgData);
	//if (!nSize)
	//{
	//	// Не допустимый apImgData. Вроде такого быть не должно - все уже проверено
	//	_ASSERTE(IsBackgroundValid(apImgData) != 0);
	//	//free(apImgData);
	//	return esbr_InvalidArg;
	//}

	//MSectionLock SBK; SBK.Lock(&csBkImgData);
	//_ASSERTE(isMainThread());

	if (!mcs_BkImgData)
		mcs_BkImgData = new MSection();

	MSectionLock SC;
	SC.Lock(mcs_BkImgData, TRUE);

	if (bIsEmf)
	{
		if (!mp_BkEmfData || mn_BkEmfDataMax < nSize)
		{
			if (mp_BkEmfData)
			{
				free(mp_BkEmfData); mp_BkEmfData = NULL;
				mb_BkImgChanged = mb_BkEmfChanged = TRUE;
				mb_BkImgExist = FALSE;
				mn_BkImgWidth = mn_BkImgHeight = 0;
			}

			mn_BkEmfDataMax = nSize+8192;
			mp_BkEmfData = (CESERVER_REQ_SETBACKGROUND*)malloc(mn_BkEmfDataMax);
		}
	}
	else
	{
		if (!mp_BkImgData || mn_BkImgDataMax < nSize)
		{
			if (mp_BkImgData)
			{
				free(mp_BkImgData); mp_BkImgData = NULL;
				mb_BkImgChanged = TRUE;
				mb_BkImgExist = FALSE;
				mn_BkImgWidth = mn_BkImgHeight = 0;
			}

			mp_BkImgData = (CESERVER_REQ_SETBACKGROUND*)malloc(nSize);
		}
	}

	SetBackgroundResult rc;

	if (!(bIsEmf ? mp_BkEmfData : mp_BkImgData))
	{
		_ASSERTE((bIsEmf ? mp_BkEmfData : mp_BkImgData)!=NULL);
		rc = esbr_Unexpected;
	}
	else
	{
		if (bIsEmf)
			memmove(mp_BkEmfData, apImgData, nSize);
		else
			memmove(mp_BkImgData, apImgData, nSize);
		mb_BkImgChanged = TRUE;
		mb_BkEmfChanged = bIsEmf;
		mb_BkImgExist = TRUE;
		BITMAPINFOHEADER* pBmp = bIsEmf ? (&mp_BkEmfData->bi) : (&mp_BkImgData->bi);
		mn_BkImgWidth = pBmp->biWidth;
		mn_BkImgHeight = pBmp->biHeight;
		NeedBackgroundUpdate();

		//// Это была копия данных - нужно освободить
		//free(apImgData); apImgData = NULL;

		if (/*gpConEmu->isVisible(this) &&*/ gpSet->isBgPluginAllowed)
		{
			//Update(true/*bForce*/);
			bUpdate = true;
		}

		rc = esbr_OK;
	}

	return rc;
}
Example #9
0
BOOL WINAPI PlugServerCommand(LPVOID pInst, CESERVER_REQ* pIn, CESERVER_REQ* &ppReply, DWORD &pcbReplySize, DWORD &pcbMaxReplySize, LPARAM lParam)
{
	BOOL lbRc = FALSE;
	//HANDLE hPipe = (HANDLE)ahPipe;
	//CESERVER_REQ *pIn=NULL;
	//BYTE cbBuffer[64]; // Для большей части команд нам хватит
	//DWORD cbRead = 0, cbWritten = 0, dwErr = 0;
	BOOL fSuccess = FALSE;
	MSectionThread SCT(csTabs);
	// Send a message to the pipe server and read the response.
	//fSuccess = ReadFile(hPipe, cbBuffer, sizeof(cbBuffer), &cbRead, NULL);
	//dwErr = GetLastError();

	//if (!fSuccess && (dwErr != ERROR_MORE_DATA))
	//{
	//	_ASSERTE("ReadFile(pipe) failed"==NULL);
	//	CloseHandle(hPipe);
	//	return 0;
	//}

	//pIn = (CESERVER_REQ*)cbBuffer; // Пока cast, если нужно больше - выделим память
	//_ASSERTE(pIn->hdr.cbSize>=sizeof(CESERVER_REQ_HDR) && cbRead>=sizeof(CESERVER_REQ_HDR));
	//_ASSERTE(pIn->hdr.nVersion == CESERVER_REQ_VER);

	if (pIn->hdr.cbSize < sizeof(CESERVER_REQ_HDR) || /*in.nSize < cbRead ||*/ pIn->hdr.nVersion != CESERVER_REQ_VER)
	{
		//CloseHandle(hPipe);
		gpPlugServer->BreakConnection(pInst);
		return FALSE;
	}

	//int nAllSize = pIn->hdr.cbSize;
	//pIn = (CESERVER_REQ*)Alloc(nAllSize,1);
	//_ASSERTE(pIn!=NULL);

	//if (!pIn)
	//{
	//	CloseHandle(hPipe);
	//	return 0;
	//}

	//memmove(pIn, cbBuffer, cbRead);
	//_ASSERTE(pIn->hdr.nVersion==CESERVER_REQ_VER);
	//LPBYTE ptrData = ((LPBYTE)pIn)+cbRead;
	//nAllSize -= cbRead;

	//while(nAllSize>0)
	//{
	//	//_tprintf(TEXT("%s\n"), chReadBuf);

	//	// Break if TransactNamedPipe or ReadFile is successful
	//	if (fSuccess)
	//		break;

	//	// Read from the pipe if there is more data in the message.
	//	fSuccess = ReadFile(
	//	               hPipe,      // pipe handle
	//	               ptrData,    // buffer to receive reply
	//	               nAllSize,   // size of buffer
	//	               &cbRead,    // number of bytes read
	//	               NULL);      // not overlapped

	//	// Exit if an error other than ERROR_MORE_DATA occurs.
	//	if (!fSuccess && ((dwErr = GetLastError()) != ERROR_MORE_DATA))
	//		break;

	//	ptrData += cbRead;
	//	nAllSize -= cbRead;
	//}

	//TODO("Может возникнуть ASSERT, если консоль была закрыта в процессе чтения");
	//_ASSERTE(nAllSize==0);

	//if (nAllSize>0)
	//{
	//	if (((LPVOID)cbBuffer) != ((LPVOID)pIn))
	//		Free(pIn);

	//	CloseHandle(hPipe);
	//	return 0; // удалось считать не все данные
	//}

	UINT nDataSize = pIn->hdr.cbSize - sizeof(CESERVER_REQ_HDR);

	// Все данные из пайпа получены, обрабатываем команду и возвращаем (если нужно) результат
	//fSuccess = WriteFile( hPipe, pOut, pOut->nSize, &cbWritten, NULL);

	if (pIn->hdr.nCmd == CMD_LANGCHANGE)
	{
		_ASSERTE(nDataSize>=4); //-V112
		// LayoutName: "00000409", "00010409", ...
		// А HKL от него отличается, так что передаем DWORD
		// HKL в x64 выглядит как: "0x0000000000020409", "0xFFFFFFFFF0010409"
		DWORD hkl = pIn->dwData[0];
		DWORD dwLastError = 0;
		HKL hkl1 = NULL, hkl2 = NULL;

		if (hkl)
		{
			WCHAR szLoc[10]; _wsprintf(szLoc, SKIPLEN(countof(szLoc)) L"%08x", hkl);
			hkl1 = LoadKeyboardLayout(szLoc, KLF_ACTIVATE|KLF_REORDER|KLF_SUBSTITUTE_OK|KLF_SETFORPROCESS);
			hkl2 = ActivateKeyboardLayout(hkl1, KLF_SETFORPROCESS|KLF_REORDER);

			if (!hkl2)
				dwLastError = GetLastError();
			else
				fSuccess = TRUE;
		}

		pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD)*2;
		if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
		{
			lbRc = TRUE;
			ppReply->dwData[0] = fSuccess;
			ppReply->dwData[1] = fSuccess ? ((DWORD)(LONG)(LONG_PTR)hkl2) : dwLastError;
		}

	}
	//} else if (pIn->hdr.nCmd == CMD_DEFFONT) {
	//	// исключение - асинхронный, результат не требуется
	//	SetConsoleFontSizeTo(FarHwnd, 4, 6);
	//	MoveWindow(FarHwnd, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 1); // чтобы убрать возможные полосы прокрутки...
	else if (pIn->hdr.nCmd == CMD_REQTABS || pIn->hdr.nCmd == CMD_SETWINDOW)
	{
		MSectionLock SC; SC.Lock(csTabs, FALSE, 1000);
		DWORD nSetWindowWait = (DWORD)-1;

		if (pIn->hdr.nCmd == CMD_SETWINDOW)
		{
			ResetEvent(ghSetWndSendTabsEvent);

			// Для FAR2 - сброс QSearch выполняется в том же макро, в котором актирируется окно
			if (gFarVersion.dwVerMajor == 1 && pIn->dwData[1])
			{
				// А вот для FAR1 - нужно шаманить
				ProcessCommand(CMD_CLOSEQSEARCH, TRUE/*bReqMainThread*/, pIn->dwData/*хоть и не нужно?*/);
			}

			// Пересылается 2 DWORD
			BOOL bCmdRc = ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->dwData);

			DEBUGSTRCMD(L"Plugin: PlugServerThreadCommand: CMD_SETWINDOW waiting...\n");

			WARNING("Почему для FAR1 не ждем? Есть возможность заблокироваться в 1.7 или что?");
			if ((gFarVersion.dwVerMajor >= 2) && bCmdRc)
			{
				DWORD nTimeout = 2000;
				#ifdef _DEBUG
				if (IsDebuggerPresent()) nTimeout = 120000;
				#endif
				
				nSetWindowWait = WaitForSingleObject(ghSetWndSendTabsEvent, nTimeout);
			}

			DEBUGSTRCMD(L"Plugin: PlugServerThreadCommand: CMD_SETWINDOW finished\n");
		}

		if (gpTabs)
		{
			//fSuccess = WriteFile(hPipe, gpTabs, gpTabs->hdr.cbSize, &cbWritten, NULL);
			pcbReplySize = gpTabs->hdr.cbSize;
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				memmove(ppReply->Data, gpTabs->Data, pcbReplySize - sizeof(ppReply->hdr));
				lbRc = TRUE;
			}
		}

		SC.Unlock();
	}
	else if (pIn->hdr.nCmd == CMD_FARSETCHANGED)
	{
		// Установить переменные окружения
		// Плагин это получает в ответ на CECMD_RESOURCES, посланное в GUI при загрузке плагина
		_ASSERTE(nDataSize>=8);
		FAR_REQ_FARSETCHANGED *pFarSet = (FAR_REQ_FARSETCHANGED*)pIn->Data;

		cmd_FarSetChanged(pFarSet);

		pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD);
		if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
		{
			lbRc = TRUE;
			ppReply->dwData[0] = TRUE;
		}

		//_ASSERTE(nDataSize<sizeof(gsMonitorEnvVar));
		//gbMonitorEnvVar = false;
		//// Плагин FarCall "нарушает" COMSPEC (копирует содержимое запускаемого процесса)
		//bool lbOk = false;

		//if (nDataSize<sizeof(gsMonitorEnvVar))
		//{
		//	memcpy(gsMonitorEnvVar, pszName, nDataSize);
		//	lbOk = true;
		//}

		//UpdateEnvVar(pszName);
		////while (*pszName && *pszValue) {
		////	const wchar_t* pszChanged = pszValue;
		////	// Для ConEmuOutput == AUTO выбирается по версии ФАРа
		////	if (!lstrcmpi(pszName, L"ConEmuOutput") && !lstrcmp(pszChanged, L"AUTO")) {
		////		if (gFarVersion.dwVerMajor==1)
		////			pszChanged = L"ANSI";
		////		else
		////			pszChanged = L"UNICODE";
		////	}
		////	// Если в pszValue пустая строка - удаление переменной
		////	SetEnvironmentVariableW(pszName, (*pszChanged != 0) ? pszChanged : NULL);
		////	//
		////	pszName = pszValue + lstrlenW(pszValue) + 1;
		////	if (*pszName == 0) break;
		////	pszValue = pszName + lstrlenW(pszName) + 1;
		////}
		//gbMonitorEnvVar = lbOk;
	}
	else if (pIn->hdr.nCmd == CMD_DRAGFROM)
	{
		#ifdef _DEBUG
		BOOL  *pbClickNeed = (BOOL*)pIn->Data;
		COORD *crMouse = (COORD *)(pbClickNeed+1);
		#endif

		ProcessCommand(CMD_LEFTCLKSYNC, TRUE/*bReqMainThread*/, pIn->Data);
		CESERVER_REQ* pCmdRet = NULL;
		ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data, &pCmdRet);

		if (pCmdRet)
		{
			//fSuccess = WriteFile(hPipe, pCmdRet, pCmdRet->hdr.cbSize, &cbWritten, NULL);
			pcbReplySize = pCmdRet->hdr.cbSize;
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				lbRc = TRUE;
				memmove(ppReply->Data, pCmdRet->Data, pCmdRet->hdr.cbSize - sizeof(ppReply->hdr));
			}
			Free(pCmdRet);
		}

		//if (gpCmdRet && gpCmdRet == pCmdRet)
		//{
		//	Free(gpCmdRet);
		//	gpCmdRet = NULL; gpData = NULL; gpCursor = NULL;
		//}
	}
	else if (pIn->hdr.nCmd == CMD_EMENU)
	{
		COORD *crMouse = (COORD *)pIn->Data;
#ifdef _DEBUG
		const wchar_t *pszUserMacro = (wchar_t*)(crMouse+1);
#endif
		DWORD ClickArg[2] = {TRUE, MAKELONG(crMouse->X, crMouse->Y)};
		
		// Выделить файл под курсором
		DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_LEFTCLKSYNC) begin\n");
		BOOL lb1 = ProcessCommand(CMD_LEFTCLKSYNC, TRUE/*bReqMainThread*/, ClickArg/*pIn->Data*/);
		DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_LEFTCLKSYNC) done\n");

		// А теперь, собственно вызовем меню
		DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_EMENU) begin\n");
		BOOL lb2 = ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data);
		DEBUGSTRMENU(L"\n*** ServerThreadCommand->ProcessCommand(CMD_EMENU) done\n");

		pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD)*2;
		if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
		{
			lbRc = TRUE;
			ppReply->dwData[0] = lb1;
			ppReply->dwData[1] = lb1;
		}
	}
	else if (pIn->hdr.nCmd == CMD_ACTIVEWNDTYPE)
	{
		int nWindowType = -1;
		//CESERVER_REQ Out;
		//ExecutePrepareCmd(&Out, CMD_ACTIVEWNDTYPE, sizeof(CESERVER_REQ_HDR)+sizeof(DWORD));

		if (gFarVersion.dwVerMajor>=2)
			nWindowType = GetActiveWindowType();

		//fSuccess = WriteFile(hPipe, &Out, Out.hdr.cbSize, &cbWritten, NULL);

		pcbReplySize = sizeof(CESERVER_REQ_HDR) + sizeof(DWORD);
		if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
		{
			lbRc = TRUE;
			ppReply->dwData[0] = nDataSize;
		}		
	}
	else
	{
		CESERVER_REQ* pCmdRet = NULL;
		BOOL lbCmd = ProcessCommand(pIn->hdr.nCmd, TRUE/*bReqMainThread*/, pIn->Data, &pCmdRet);

		if (pCmdRet)
		{
			//fSuccess = WriteFile(hPipe, pCmdRet, pCmdRet->hdr.cbSize, &cbWritten, NULL);
			pcbReplySize = pCmdRet->hdr.cbSize;
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				lbRc = TRUE;
				memmove(ppReply->Data, pCmdRet->Data, pCmdRet->hdr.cbSize - sizeof(ppReply->hdr));
			}
			Free(pCmdRet);
		}

		//if (gpCmdRet && gpCmdRet == pCmdRet) {
		//	Free(gpCmdRet);
		//	gpCmdRet = NULL; gpData = NULL; gpCursor = NULL;
		//}
	}

	//// Освободить память
	//if (((LPVOID)cbBuffer) != ((LPVOID)pIn))
	//	Free(pIn);

	//CloseHandle(hPipe);
	return lbRc;
}
Example #10
0
// В asDir могут быть переменные окружения.
wchar_t* CConEmuUpdate::CreateTempFile(LPCWSTR asDir, LPCWSTR asFileNameTempl, HANDLE& hFile)
{
	wchar_t szFile[MAX_PATH*2+2];
	wchar_t szName[128];

	if (!asDir || !*asDir)
		asDir = L"%TEMP%\\ConEmu";
	if (!asFileNameTempl || !*asFileNameTempl)
		asFileNameTempl = L"ConEmu.tmp";

	if (wcschr(asDir, L'%'))
	{
		DWORD nExp = ExpandEnvironmentStrings(asDir, szFile, MAX_PATH);
		if (!nExp || (nExp >= MAX_PATH))
		{
			ReportError(L"CreateTempFile.ExpandEnvironmentStrings(%s) failed, code=%u", asDir, GetLastError());
			return NULL;
		}
	}
	else
	{
		lstrcpyn(szFile, asDir, MAX_PATH);
	}

	// Checking %TEMP% for valid path
	LPCWSTR pszColon1, pszColon2;
	if ((pszColon1 = wcschr(szFile, L':')) != NULL)
	{
		if ((pszColon2 = wcschr(pszColon1+1, L':')) != NULL)
		{
			ReportError(L"Invalid download path (%%TEMP%% variable?)\n%s", szFile, 0);
			return NULL;
		}
	}

	int nLen = lstrlen(szFile);
	if (nLen <= 0)
	{
		ReportError(L"CreateTempFile.asDir(%s) failed, path is null", asDir, 0);
		return NULL;
	}
	if (szFile[nLen-1] != L'\\')
	{
		szFile[nLen++] = L'\\'; szFile[nLen] = 0;
	}
	wchar_t* pszFilePart = szFile + nLen;

	wchar_t* pszDirectory = lstrdup(szFile);


	LPCWSTR pszName = PointToName(asFileNameTempl);
	_ASSERTE(pszName == asFileNameTempl);
	if (!pszName || !*pszName || (*pszName == L'.'))
	{
		_ASSERTE(pszName && *pszName && (*pszName != L'.'));
		pszName = L"ConEmu";
	}

	LPCWSTR pszExt = PointToExt(pszName);
	if (pszExt == NULL)
	{
		_ASSERTE(pszExt != NULL);
		pszExt = L".tmp";
	}

	lstrcpyn(szName, pszName, countof(szName)-16);
	wchar_t* psz = wcsrchr(szName, L'.');
	if (psz)
		*psz = 0;

	wchar_t* pszResult = NULL;
	DWORD dwErr = 0;

	for (UINT i = 0; i <= 9999; i++)
	{
		_wcscpy_c(pszFilePart, MAX_PATH, szName);
		if (i)
			_wsprintf(pszFilePart+_tcslen(pszFilePart), SKIPLEN(16) L"(%u)", i);
		_wcscat_c(pszFilePart, MAX_PATH, pszExt);

		hFile = CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_TEMPORARY, NULL);
		//ERROR_PATH_NOT_FOUND?
		if (!hFile || (hFile == INVALID_HANDLE_VALUE))
		{
			dwErr = GetLastError();
			// на первом обломе - попытаться создать директорию, может ее просто нет?
			if ((dwErr == ERROR_PATH_NOT_FOUND) && (i == 0))
			{
				if (!MyCreateDirectory(pszDirectory))
				{
					ReportError(L"CreateTempFile.asDir(%s) failed", asDir, 0);
					goto wrap;
				}
			}
		}

		if (hFile && hFile != INVALID_HANDLE_VALUE)
		{
			psz = lstrdup(szFile);
			if (!psz)
			{
				CloseHandle(hFile); hFile = NULL;
				ReportError(L"Can't allocate memory (%i bytes)", lstrlen(szFile));
			}
			pszResult = psz;
			goto wrap;
		}
	}

	ReportError(L"Can't create temp file(%s), code=%u", szFile, dwErr);
	hFile = NULL;
wrap:
	SafeFree(pszDirectory);
	return pszResult;
}
Example #11
0
BOOL ReloadFarInfoW995(/*BOOL abFull*/)
{
	if (!InfoW995 || !FSFW995) return FALSE;

	if (!gpFarInfo)
	{
		_ASSERTE(gpFarInfo!=NULL);
		return FALSE;
	}

	// Заполнить gpFarInfo->
	//BYTE nFarColors[col_LastIndex]; // Массив цветов фара
	//DWORD nFarInterfaceSettings;
	//DWORD nFarPanelSettings;
	//DWORD nFarConfirmationSettings;
	//BOOL  bFarPanelAllowed, bFarLeftPanel, bFarRightPanel;   // FCTL_CHECKPANELSEXIST, FCTL_GETPANELSHORTINFO,...
	//CEFAR_SHORT_PANEL_INFO FarLeftPanel, FarRightPanel;
	DWORD ldwConsoleMode = 0;	GetConsoleMode(/*ghConIn*/GetStdHandle(STD_INPUT_HANDLE), &ldwConsoleMode);
#ifdef _DEBUG
	static DWORD ldwDbgMode = 0;

	if (IsDebuggerPresent())
	{
		if (ldwDbgMode != ldwConsoleMode)
		{
			wchar_t szDbg[128]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"Far.ConEmuW: ConsoleMode(STD_INPUT_HANDLE)=0x%08X\n", ldwConsoleMode);
			OutputDebugStringW(szDbg);
			ldwDbgMode = ldwConsoleMode;
		}
	}

#endif
	gpFarInfo->nFarConsoleMode = ldwConsoleMode;
	
	LoadFarColorsW995(gpFarInfo->nFarColors);

	//_ASSERTE(FPS_SHOWCOLUMNTITLES==0x20 && FPS_SHOWSTATUSLINE==0x40); //-V112
	LoadFarSettingsW995(&gpFarInfo->FarInterfaceSettings, &gpFarInfo->FarPanelSettings);

	//gpFarInfo->nFarConfirmationSettings =
	//    (DWORD)InfoW995->AdvControl(InfoW995->ModuleNumber, ACTL_GETCONFIRMATIONS, 0);

	gpFarInfo->bMacroActive = IsMacroActiveW995();
	ActlKeyMacro area = {MCMD_GETAREA};
	INT_PTR nArea = InfoW995->AdvControl(InfoW995->ModuleNumber, ACTL_KEYMACRO, &area);
	switch(nArea)
	{
		case MACROAREA_SHELL:
		case MACROAREA_INFOPANEL:
		case MACROAREA_QVIEWPANEL:
		case MACROAREA_TREEPANEL:
		case MACROAREA_SEARCH:
			gpFarInfo->nMacroArea = fma_Panels;
			break;
		case MACROAREA_VIEWER:
			gpFarInfo->nMacroArea = fma_Viewer;
			break;
		case MACROAREA_EDITOR:
			gpFarInfo->nMacroArea = fma_Editor;
			break;
		case MACROAREA_DIALOG:
		case MACROAREA_DISKS:
		case MACROAREA_FINDFOLDER:
		case MACROAREA_AUTOCOMPLETION:
		case MACROAREA_MAINMENU:
		case MACROAREA_MENU:
		case MACROAREA_USERMENU:
			gpFarInfo->nMacroArea = fma_Dialog;
			break;
		default:
			gpFarInfo->nMacroArea = fma_Unknown;
	}

	gpFarInfo->bFarPanelAllowed = InfoW995->Control(PANEL_NONE, FCTL_CHECKPANELSEXIST, 0, 0);
	gpFarInfo->bFarPanelInfoFilled = FALSE;
	gpFarInfo->bFarLeftPanel = FALSE;
	gpFarInfo->bFarRightPanel = FALSE;
	// -- пока, во избежание глюков в FAR при неожиданных запросах информации о панелях
	//if (FALSE == (gpFarInfo->bFarPanelAllowed)) {
	//	gpConMapInfo->bFarLeftPanel = FALSE;
	//	gpConMapInfo->bFarRightPanel = FALSE;
	//} else {
	//	PanelInfo piA = {}, piP = {};
	//	BOOL lbActive  = InfoW995->Control(PANEL_ACTIVE, FCTL_GETPANELINFO, 0, (LONG_PTR)&piA);
	//	BOOL lbPassive = InfoW995->Control(PANEL_PASSIVE, FCTL_GETPANELINFO, 0, (LONG_PTR)&piP);
	//	if (!lbActive && !lbPassive)
	//	{
	//		gpConMapInfo->bFarLeftPanel = FALSE;
	//		gpConMapInfo->bFarRightPanel = FALSE;
	//	} else {
	//		PanelInfo *ppiL = NULL;
	//		PanelInfo *ppiR = NULL;
	//		if (lbActive) {
	//			if (piA.Flags & PFLAGS_PANELLEFT) ppiL = &piA; else ppiR = &piA;
	//		}
	//		if (lbPassive) {
	//			if (piP.Flags & PFLAGS_PANELLEFT) ppiL = &piP; else ppiR = &piP;
	//		}
	//		gpConMapInfo->bFarLeftPanel = ppiL!=NULL;
	//		gpConMapInfo->bFarRightPanel = ppiR!=NULL;
	//		if (ppiL) FarPanel2CePanel(ppiL, &(gpConMapInfo->FarLeftPanel));
	//		if (ppiR) FarPanel2CePanel(ppiR, &(gpConMapInfo->FarRightPanel));
	//	}
	//}
	return TRUE;
}
Example #12
0
int InjectRemote(DWORD nRemotePID, bool abDefTermOnly /*= false */)
{
	int iRc = -1;
	BOOL lbWin64 = WIN3264TEST(IsWindows64(),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(szSelf, 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 != 0)
		{
			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;
}
Example #13
0
int PrepareHookModule(wchar_t (&szModule)[MAX_PATH+16])
{
	int iRc = -251;
	wchar_t szNewPath[MAX_PATH+16] = {}, szAddName[32] = {}, szVer[2] = {};
	INT_PTR nLen = 0;
	bool bAlreadyExists = false;

	// Copy szModule to CSIDL_LOCAL_APPDATA and return new path
	HRESULT hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szNewPath);
	if ((hr != S_OK) || !*szNewPath)
	{
		iRc = -251;
		goto wrap;
	}

	szVer[0] = MVV_4a[0];
	_wsprintf(szAddName, SKIPLEN(countof(szAddName))
		L"\\" CEDEFTERMDLLFORMAT /*L"ConEmuHk%s.%02u%02u%02u%s.dll"*/,
		WIN3264TEST(L"",L"64"), MVV_1, MVV_2, MVV_3, szVer);

	nLen = lstrlen(szNewPath);
	if (szNewPath[nLen-1] != L'\\')
	{
		szNewPath[nLen++] = L'\\'; szNewPath[nLen] = 0;
	}

	if ((nLen + lstrlen(szAddName) + 8) >= countof(szNewPath))
	{
		iRc = -252;
		goto wrap;
	}

	wcscat_c(szNewPath, L"ConEmu");
	if (!DirectoryExists(szNewPath))
	{
		if (!CreateDirectory(szNewPath, NULL))
		{
			iRc = -253;
			goto wrap;
		}
	}

	wcscat_c(szNewPath, szAddName);

	if ((bAlreadyExists = FileExists(szNewPath)) && FileCompare(szNewPath, szModule))
	{
		// OK, file exists and match the required
	}
	else
	{
		if (bAlreadyExists)
		{
			_ASSERTE(FALSE && "Continue to overwrite existing ConEmuHk in AppLocal");

			// Try to delete or rename old version
			if (!DeleteFile(szNewPath))
			{
				//SYSTEMTIME st; GetLocalTime(&st);
				wchar_t szBakPath[MAX_PATH+32]; wcscpy_c(szBakPath, szNewPath);
				wchar_t* pszExt = (wchar_t*)PointToExt(szBakPath);
				msprintf(pszExt, 16, L".%u.dll", GetTickCount());
				DeleteFile(szBakPath);
				MoveFile(szNewPath, szBakPath);
			}
		}

		if (!CopyFile(szModule, szNewPath, FALSE))
		{
			iRc = -254;
			goto wrap;
		}
	}

	wcscpy_c(szModule, szNewPath);
	iRc = 0;
wrap:
	return iRc;
}
Example #14
0
//// Эта функция пайп не закрывает!
//void CGuiServer::GuiServerThreadCommand(HANDLE hPipe)
BOOL CGuiServer::GuiServerCommand(LPVOID pInst, CESERVER_REQ* pIn, CESERVER_REQ* &ppReply, DWORD &pcbReplySize, DWORD &pcbMaxReplySize, LPARAM lParam)
{
	BOOL lbRc = FALSE;
	CGuiServer* pGSrv = (CGuiServer*)lParam;

	if (!pGSrv)
	{
		_ASSERTE(((CGuiServer*)lParam)!=NULL);
		pGSrv = &gpConEmu->m_GuiServer;
	}
	
	if (pIn->hdr.bAsync)
		pGSrv->mp_GuiServer->BreakConnection(pInst);

	gpSetCls->debugLogCommand(pIn, TRUE, timeGetTime(), 0, pGSrv ? pGSrv->ms_ServerPipe : NULL);

	#ifdef _DEBUG
	UINT nDataSize = pIn->hdr.cbSize - sizeof(CESERVER_REQ_HDR);
	#endif
	// Все данные из пайпа получены, обрабатываем команду и возвращаем (если нужно) результат

	#ifdef ALLOW_WINE_MSG
	if (gbIsWine)
	{
		wchar_t szMsg[128];
		msprintf(szMsg, countof(szMsg), L"CGuiServer::GuiServerCommand.\nGUI TID=%u\nSrcPID=%u, SrcTID=%u, Cmd=%u",
			GetCurrentThreadId(), pIn->hdr.nSrcPID, pIn->hdr.nSrcThreadId, pIn->hdr.nCmd);
		MessageBox(szMsg, MB_ICONINFORMATION);
	}
	#endif

	switch (pIn->hdr.nCmd)
	{
		case CECMD_NEWCMD:
		{
			// Приходит из другой копии ConEmu.exe, когда она запущена с ключом /single, /showhide, /showhideTSA
			DEBUGSTR(L"GUI recieved CECMD_NEWCMD\n");

			if (gpSetCls->isAdvLogging)
			{
				size_t cchAll = 120 + _tcslen(pIn->NewCmd.szConEmu) + _tcslen(pIn->NewCmd.szCurDir) + _tcslen(pIn->NewCmd.szCommand);
				wchar_t* pszInfo = (wchar_t*)malloc(cchAll*sizeof(*pszInfo));
				if (pszInfo)
				{
					_wsprintf(pszInfo, SKIPLEN(cchAll) L"CECMD_NEWCMD: Wnd=x%08X, Act=%u, ConEmu=%s, Dir=%s, Cmd=%s",
						(DWORD)(DWORD_PTR)pIn->NewCmd.hFromConWnd, pIn->NewCmd.ShowHide,
						pIn->NewCmd.szConEmu, pIn->NewCmd.szCurDir, pIn->NewCmd.szCommand);
					gpConEmu->LogString(pszInfo);
					free(pszInfo);
				}
			}

			BOOL bAccepted = FALSE;

			if (pIn->NewCmd.szConEmu[0])
			{
				bAccepted = (lstrcmpi(gpConEmu->ms_ConEmuExeDir, pIn->NewCmd.szConEmu) == 0);
			}
			else
			{
				bAccepted = TRUE;
			}

			if (bAccepted)
			{
				bool bCreateTab = (pIn->NewCmd.ShowHide == sih_None || pIn->NewCmd.ShowHide == sih_StartDetached);
				gpConEmu->OnMinimizeRestore(bCreateTab ? sih_SetForeground : pIn->NewCmd.ShowHide);

				// Может быть пусто
				if (bCreateTab && pIn->NewCmd.szCommand[0])
				{
					RConStartArgs *pArgs = new RConStartArgs;
					pArgs->bDetached = (pIn->NewCmd.ShowHide == sih_StartDetached);
					pArgs->pszSpecialCmd = lstrdup(pIn->NewCmd.szCommand);
					if (pIn->NewCmd.szCurDir[0] == 0)
					{
						_ASSERTE(pIn->NewCmd.szCurDir[0] != 0);
					}
					else
					{
						pArgs->pszStartupDir = lstrdup(pIn->NewCmd.szCurDir);
					}

					if (gpSet->isMulti || CVConGroup::isDetached())
					{
						gpConEmu->PostCreateCon(pArgs);
					}
					else
					{
						// Если хотят в одном окне - только одну консоль
						gpConEmu->CreateWnd(pArgs);
						SafeDelete(pArgs);
					}
				}
				else
				{
					_ASSERTE(pIn->NewCmd.ShowHide==sih_ShowMinimize || pIn->NewCmd.ShowHide==sih_ShowHideTSA || pIn->NewCmd.ShowHide==sih_Show);
				}
			}

			pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(BYTE);
			lbRc = ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize);
			if (lbRc)
			{
				ppReply->Data[0] = bAccepted;
			}

			break;
		} //CECMD_NEWCMD

		case CECMD_TABSCMD:
		{
			// 0: спрятать/показать табы, 1: перейти на следующую, 2: перейти на предыдущую, 3: commit switch
			DEBUGSTR(L"GUI recieved CECMD_TABSCMD\n");
			_ASSERTE(nDataSize>=1);
			DWORD nTabCmd = pIn->Data[0];
			gpConEmu->TabCommand((ConEmuTabCommand)nTabCmd);

			pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(BYTE);
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				lbRc = TRUE;
				ppReply->Data[0] = TRUE;
			}
			break;
		} // CECMD_TABSCMD

		#if 0
		case CECMD_GETALLTABS:
		{
			int nConCount = gpConEmu->GetConCount();
			int nActiveCon = gpConEmu->ActiveConNum();
			size_t cchMax = nConCount*16;
			size_t cchCount = 0;
			CVirtualConsole* pVCon;
			CESERVER_REQ_GETALLTABS::TabInfo* pTabs = (CESERVER_REQ_GETALLTABS::TabInfo*)calloc(cchMax, sizeof(*pTabs));
			for (int V = 0; (pVCon = gpConEmu->GetVCon(V)) != NULL; V++)
			{
				if (!pTabs)
				{
					_ASSERTE(pTabs!=NULL);
					break;
				}

				CRealConsole* pRCon = pVCon->RCon();
				if (!pRCon)
					continue;

				ConEmuTab tab;
				wchar_t szModified[4];
				for (int T = 0; pRCon->GetTab(T, &tab); T++)
				{
					if (cchCount >= cchMax)
					{
						pTabs = (CESERVER_REQ_GETALLTABS::TabInfo*)realloc(pTabs, (cchMax+32)*sizeof(*pTabs));
						if (!pTabs)
						{
							_ASSERTE(pTabs!=NULL);
							break;
						}
						cchMax += 32;
						_ASSERTE(cchCount<cchMax);
					}

					pTabs[cchCount].ActiveConsole == (V == nActiveCon);
					pTabs[cchCount].ActiveTab == (tab.Current != 0);
					pTabs[cchCount].Disabled = ((tab.Type & fwt_Disabled) == fwt_Disabled);
					pTabs[cchCount].ConsoleIdx = V;
					pTabs[cchCount].TabIdx = T;

					// Text
					wcscpy_c(szModified, tab.Modified ? L" * " : L"   ");
					if (V == nActiveCon)
					{
						if (T < 9)
							_wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/&%i]%s", V+1, T+1, szModified);
						else if (T == 9)
							_wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/1&0]%s", V+1, szModified);
						else
							_wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/%i]%s", V+1, T+1, szModified);
					}
					else
					{
						_wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/%i]%s", V+1, T+1, szModified);
					}

					cchCount++;
				}
			}
			if (cchCount && pTabs)
			{
				pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_GETALLTABS)+((cchCount-1)*sizeof(CESERVER_REQ_GETALLTABS::TabInfo));
				if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
				{
					lbRc = TRUE;
					ppReply->GetAllTabs.Count = cchCount;
					memmove(ppReply->GetAllTabs.Tabs, pTabs, cchCount*sizeof(*pTabs));
				}
			}
			SafeFree(pTabs);
			break;
		} // CECMD_GETALLTABS

		case CECMD_ACTIVATETAB:
		{
			BOOL lbTabOk = FALSE;
			CVirtualConsole *pVCon = gpConEmu->GetVCon(pIn->dwData[0]);
			if (pVCon && pVCon->RCon())
			{
				lbTabOk = pVCon->RCon()->ActivateFarWindow(pIn->dwData[1]);
			}

			pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(DWORD);
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				lbRc = TRUE;
				ppReply->dwData[0] = lbTabOk;
			}
			break;
		} // CECMD_ACTIVATETAB
		#endif

		case CECMD_ATTACH2GUI:
		{
			// Получен запрос на Attach из сервера
			pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_STARTSTOPRET);
			if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
				goto wrap;
			//CESERVER_REQ* pOut = ExecuteNewCmd(CECMD_ATTACH2GUI, sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_STARTSTOPRET));

			gpConEmu->AttachRequested(pIn->StartStop.hWnd, &(pIn->StartStop), &(ppReply->StartStopRet));
			_ASSERTE((ppReply->StartStopRet.nBufferHeight == 0) || ((int)ppReply->StartStopRet.nBufferHeight > pIn->StartStop.sbi.dwSize.X));

			lbRc = TRUE;
			//ExecuteFreeResult(pOut);
			break;
		} // CECMD_ATTACH2GUI

		case CECMD_SRVSTARTSTOP:
		{
			pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_STARTSTOPRET);
			if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
				goto wrap;

			if (pIn->SrvStartStop.Started == srv_Started)
			{
				// Запущен процесс сервера
				HWND hConWnd = (HWND)pIn->dwData[1];
				_ASSERTE(hConWnd && IsWindow(hConWnd));

				DWORD nStartTick = timeGetTime();

				//LRESULT l = 0;
				//DWORD_PTR dwRc = 0;
				//2010-05-21 Поскольку это критично - лучше ждать до упора, хотя может быть DeadLock?
				//l = SendMessageTimeout(ghWnd, gpConEmu->mn_MsgSrvStarted, (WPARAM)hConWnd, pIn->hdr.nSrcPID,
				//	SMTO_BLOCK, 5000, &dwRc);

				//111002 - вернуть должен HWND окна отрисовки (дочернее окно ConEmu)
				MsgSrvStartedArg arg = {hConWnd, pIn->hdr.nSrcPID, pIn->SrvStartStop.dwKeybLayout, nStartTick};
				SendMessage(ghWnd, gpConEmu->mn_MsgSrvStarted, 0, (LPARAM)&arg);
				HWND hWndDC = arg.hWndDc;
				HWND hWndBack = arg.hWndBack;
				_ASSERTE(hWndDC!=NULL);

				#ifdef _DEBUG
				DWORD dwErr = GetLastError(), nEndTick = timeGetTime(), nDelta = nEndTick - nStartTick;
				if (hWndDC && nDelta >= EXECUTE_CMD_WARN_TIMEOUT)
				{
					if (!IsDebuggerPresent())
					{
						//_ASSERTE(nDelta <= EXECUTE_CMD_WARN_TIMEOUT || (pIn->hdr.nCmd == CECMD_CMDSTARTSTOP && nDelta <= EXECUTE_CMD_WARN_TIMEOUT2));
						_ASSERTEX(nDelta <= EXECUTE_CMD_WARN_TIMEOUT);
					}
				}
				#endif

				//pIn->dwData[0] = (DWORD)ghWnd; //-V205
				//pIn->dwData[1] = (DWORD)dwRc; //-V205
				//pIn->dwData[0] = (l == 0) ? 0 : 1;
				ppReply->StartStopRet.hWnd = ghWnd;
				ppReply->StartStopRet.hWndDc = hWndDC;
				ppReply->StartStopRet.hWndBack = hWndBack;
				ppReply->StartStopRet.dwPID = GetCurrentProcessId();
			}
			else if (pIn->SrvStartStop.Started == srv_Stopped)
			{
				// Процесс сервера завершается
				CRealConsole* pRCon = NULL;
				CVConGuard VCon;

				for (size_t i = 0;; i++)
				{
					if (!CVConGroup::GetVCon(i, &VCon))
						break;

					pRCon = VCon->RCon();
					if (pRCon && (pRCon->GetServerPID(true) == pIn->hdr.nSrcPID || pRCon->GetServerPID(false) == pIn->hdr.nSrcPID))
					{
						break;
					}
					pRCon = NULL;
				}

				if (pRCon)
					pRCon->OnServerClosing(pIn->hdr.nSrcPID);

				//pIn->dwData[0] = 1;
			}
			else
			{
				_ASSERTE((pIn->dwData[0] == 1) || (pIn->dwData[0] == 101));
			}

			lbRc = TRUE;
			//// Отправляем
			//fSuccess = WriteFile(
			//               hPipe,        // handle to pipe
			//               pOut,         // buffer to write from
			//               pOut->hdr.cbSize,  // number of bytes to write
			//               &cbWritten,   // number of bytes written
			//               NULL);        // not overlapped I/O

			//ExecuteFreeResult(pOut);
			break;
		} // CECMD_SRVSTARTSTOP

		case CECMD_ASSERT:
		{
			DWORD nBtn = MessageBox(NULL, pIn->AssertInfo.szDebugInfo, pIn->AssertInfo.szTitle, pIn->AssertInfo.nBtns);

			pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(DWORD);
			if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
			{
				lbRc = TRUE;
				ppReply->dwData[0] = nBtn;
			}

			//ExecutePrepareCmd(&pIn->hdr, CECMD_ASSERT, sizeof(CESERVER_REQ_HDR) + sizeof(DWORD));
			//pIn->dwData[0] = nBtn;
			//// Отправляем
			//fSuccess = WriteFile(
			//               hPipe,        // handle to pipe
			//               pIn,         // buffer to write from
			//               pIn->hdr.cbSize,  // number of bytes to write
			//               &cbWritten,   // number of bytes written
			//               NULL);        // not overlapped I/O
			break;
		} // CECMD_ASSERT

		case CECMD_ATTACHGUIAPP:
		{
			pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_ATTACHGUIAPP);
			if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
				goto wrap;
			ppReply->AttachGuiApp = pIn->AttachGuiApp;

			//CESERVER_REQ Out;
			//ExecutePrepareCmd(&Out.hdr, CECMD_ATTACHGUIAPP, sizeof(CESERVER_REQ_HDR)+sizeof(Out.AttachGuiApp));
			//Out.AttachGuiApp = pIn->AttachGuiApp;
			
			#ifdef SHOW_GUIATTACH_START
			if (pIn->AttachGuiApp.hWindow == NULL)
			{
				wchar_t szDbg[1024];
				_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"AttachGuiApp requested from:\n%s\nPID=%u", pIn->AttachGuiApp.sAppFileName, pIn->AttachGuiApp.nPID);
				//MBoxA(szDbg);
				MessageBox(NULL, szDbg, L"ConEmu", MB_SYSTEMMODAL);
			}
			#endif

			// Уведомить ожидающую вкладку
			CRealConsole* pRCon = gpConEmu->AttachRequestedGui(pIn->AttachGuiApp.sAppFileName, pIn->AttachGuiApp.nPID);
			if (pRCon)
			{
				CVConGuard VCon(pRCon->VCon());
				RECT rcPrev = ppReply->AttachGuiApp.rcWindow;
				HWND hBack = pRCon->VCon()->GetBack();

				//// Размер должен быть независим от возможности наличия прокрутки в VCon
				//GetWindowRect(hBack, &ppReply->AttachGuiApp.rcWindow);
				//ppReply->AttachGuiApp.rcWindow.right -= ppReply->AttachGuiApp.rcWindow.left;
				//ppReply->AttachGuiApp.rcWindow.bottom -= ppReply->AttachGuiApp.rcWindow.top;
				//ppReply->AttachGuiApp.rcWindow.left = ppReply->AttachGuiApp.rcWindow.top = 0;
				////MapWindowPoints(NULL, hBack, (LPPOINT)&ppReply->AttachGuiApp.rcWindow, 2);
				//pRCon->CorrectGuiChildRect(ppReply->AttachGuiApp.nStyle, ppReply->AttachGuiApp.nStyleEx, ppReply->AttachGuiApp.rcWindow);
				
				// Уведомить RCon и ConEmuC, что гуй подцепился
				// Вызывается два раза. Первый (при запуске exe) ahGuiWnd==NULL, второй - после фактического создания окна
				pRCon->SetGuiMode(pIn->AttachGuiApp.nFlags, pIn->AttachGuiApp.hAppWindow, pIn->AttachGuiApp.Styles.nStyle, pIn->AttachGuiApp.Styles.nStyleEx, pIn->AttachGuiApp.sAppFileName, pIn->AttachGuiApp.nPID, rcPrev);

				ppReply->AttachGuiApp.nFlags = agaf_Success | (pRCon->isActive(false) ? 0 : agaf_Inactive);
				ppReply->AttachGuiApp.nPID = pRCon->GetServerPID();
				ppReply->AttachGuiApp.hConEmuDc = pRCon->GetView();
				ppReply->AttachGuiApp.hConEmuBack = hBack;
				ppReply->AttachGuiApp.hConEmuWnd = ghWnd;
				ppReply->AttachGuiApp.hAppWindow = pIn->AttachGuiApp.hAppWindow;
				ppReply->AttachGuiApp.hSrvConWnd = pRCon->ConWnd();
				ppReply->AttachGuiApp.hkl = (DWORD)(LONG)(LONG_PTR)GetKeyboardLayout(gpConEmu->mn_MainThreadId);
				ZeroStruct(ppReply->AttachGuiApp.Styles.Shifts);
				CRealConsole::CorrectGuiChildRect(pIn->AttachGuiApp.Styles.nStyle, pIn->AttachGuiApp.Styles.nStyleEx, ppReply->AttachGuiApp.Styles.Shifts);
			}
			else
			{
				ppReply->AttachGuiApp.nFlags = agaf_Fail;
			}

			lbRc = TRUE;

			//// Отправляем
			//fSuccess = WriteFile(
			//               hPipe,        // handle to pipe
			//               &Out,         // buffer to write from
			//               Out.hdr.cbSize,  // number of bytes to write
			//               &cbWritten,   // number of bytes written
			//               NULL);        // not overlapped I/O
			break;
		} // CECMD_ATTACHGUIAPP

		case CECMD_GUICLIENTSHIFT:
		{
			pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(GuiStylesAndShifts);
			if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize))
				goto wrap;
			ppReply->GuiAppShifts = pIn->GuiAppShifts;

			ZeroStruct(ppReply->GuiAppShifts.Shifts);
			CRealConsole::CorrectGuiChildRect(pIn->GuiAppShifts.nStyle, pIn->GuiAppShifts.nStyleEx, ppReply->GuiAppShifts.Shifts);

			lbRc = TRUE;
			break;
		} // CECMD_GUICLIENTSHIFT
	}

	//// Освободить память
	//if (pIn && (LPVOID)pIn != (LPVOID)&in)
	//{
	//	free(pIn); pIn = NULL;
	//}
wrap:
	return lbRc;
}
Example #15
0
bool CConEmuUpdate::StartLocalUpdate(LPCWSTR asDownloadedPackage)
{
	bool bRc = false;
	LPCWSTR pszName, pszExt;
	HANDLE hTarget = NULL;
	wchar_t *pszLocalPackage = NULL, *pszBatchFile = NULL;
	DWORD nLocalCRC = 0;
	BOOL lbDownloadRc = FALSE, lbExecuteRc = FALSE;

	LPCWSTR pszPackPref = L"conemupack.";
	size_t lnPackPref = _tcslen(pszPackPref);
	LPCWSTR pszSetupPref = L"conemusetup.";
	size_t lnSetupPref = _tcslen(pszSetupPref);

	_ASSERTE(gpConEmu && gpConEmu->isMainThread());

	if (InUpdate() != us_NotStarted)
	{
		MBoxError(L"Checking for updates already started");
		goto wrap;
	}

	if (mb_InCheckProcedure)
	{
		Assert(mb_InCheckProcedure==FALSE);
		goto wrap;
	}

	DeleteBadTempFiles();
	Inet.Deinit(true);

	pszName = PointToName(asDownloadedPackage);
	pszExt = PointToExt(pszName);
	if (!pszName || !*pszName || !pszExt || !*pszExt)
	{
		AssertMsg(L"Invalid asDownloadedPackage");
		goto wrap;
	}

	// Запомнить текущие параметры обновления
	if (!mp_Set)
		mp_Set = new ConEmuUpdateSettings;
	mp_Set->LoadFrom(&gpSet->UpdSet);

	mb_ManualCallMode = TRUE;

	// Clear possible last error
	{
		MSectionLock SC; SC.Lock(mp_LastErrorSC, TRUE);
		SafeFree(ms_LastErrorInfo);
	}

	ms_NewVersion[0] = 0;

	if ((lstrcmpni(pszName, pszPackPref, lnPackPref) == 0)
		&& (lstrcmpi(pszExt, L".7z") == 0)
		&& (((pszExt - pszName) - lnPackPref + 1) < sizeof(ms_NewVersion)))
	{
		// Check it was NOT installed with "Setupper"
		if (mp_Set->UpdateDownloadSetup() == 1)
		{
			DontEnable de;
			LPCWSTR pszConfirm = L"ConEmu was installed with setup!\nAre you sure to update installation with 7zip?";
			int iBtn = MessageBox(NULL, pszConfirm, ms_DefaultTitle, MB_ICONEXCLAMATION|MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_YESNO|MB_DEFBUTTON2);
			if (iBtn != IDYES)
			{
				goto wrap;
			}
		}

		if (!Check7zipInstalled())
			goto wrap; // Error already reported

		// Forcing usage of 7zip package!
		mp_Set->isUpdateDownloadSetup = 2;

		//if (!CanUpdateInstallation())
		//{
		//	// Значит 7zip обломается при попытке распаковки
		//	goto wrap;
		//}

		// OK
		size_t nLen = (pszExt - pszName) - lnPackPref;
		wmemmove(ms_NewVersion, pszName+lnPackPref, nLen);
		ms_NewVersion[nLen] = 0;
	}
	else if ((lstrcmpni(pszName, pszSetupPref, lnSetupPref) == 0)
		&& (lstrcmpi(pszExt, L".exe") == 0)
		&& (((pszExt - pszName) - lnSetupPref + 1) < sizeof(ms_NewVersion)))
	{
		// Must be installed with "Setupper"
		if (mp_Set->UpdateDownloadSetup() != 1)
		{
			MBoxError(L"ConEmu was not installed with setup! Can't update!");
			goto wrap;
		}

		// OK
		size_t nLen = (pszExt - pszName) - lnSetupPref;
		wmemmove(ms_NewVersion, pszName+lnSetupPref, nLen);
		ms_NewVersion[nLen] = 0;
	}
	else
	{
		AssertMsg(L"Invalid asDownloadedPackage (2)");
		goto wrap;
	}


	// Сразу проверим, как нужно будет запускаться
	bNeedRunElevation = NeedRunElevation();

	_wsprintf(ms_CurVersion, SKIPLEN(countof(ms_CurVersion)) L"%02u%02u%02u%s", (MVV_1%100),MVV_2,MVV_3,_T(MVV_4a));
	//ms_NewVersion

	// StartLocalUpdate - запуск обновления из локального пакета

	mb_InetMode = false;
	mb_DroppedMode = true;



	pszLocalPackage = CreateTempFile(mp_Set->szUpdateDownloadPath, PointToName(asDownloadedPackage), hTarget);
	if (!pszLocalPackage)
		goto wrap;

	lbDownloadRc = DownloadFile(asDownloadedPackage, pszLocalPackage, hTarget, nLocalCRC, TRUE);
	CloseHandle(hTarget);
	if (!lbDownloadRc)
		goto wrap;


	if (mb_RequestTerminate)
		goto wrap;

	pszBatchFile = CreateBatchFile(pszLocalPackage);
	if (!pszBatchFile)
		goto wrap;

	if (!QueryConfirmation(us_ConfirmUpdate))
	{
		goto wrap;
	}

	Assert(mb_ManualCallMode==TRUE);
	Assert(mpsz_PendingBatchFile==NULL);

	mpsz_PendingPackageFile = pszLocalPackage;
	pszLocalPackage = NULL;
	mpsz_PendingBatchFile = pszBatchFile;
	pszBatchFile = NULL;
	m_UpdateStep = us_ExitAndUpdate;
	if (gpConEmu)
		gpConEmu->RequestExitUpdate();
	lbExecuteRc = TRUE;

wrap:
	_ASSERTE(mpsz_DeleteIniFile==NULL);

	_ASSERTE(mpsz_DeletePackageFile==NULL);
	mpsz_DeletePackageFile = NULL;
	if (pszLocalPackage)
	{
		if (*pszLocalPackage && (!lbDownloadRc || (!lbExecuteRc && !mp_Set->isUpdateLeavePackages)))
			mpsz_DeletePackageFile = pszLocalPackage;
			//DeleteFile(pszLocalPackage);
		else
			SafeFree(pszLocalPackage);
	}

	_ASSERTE(mpsz_DeleteBatchFile==NULL);
	mpsz_DeleteBatchFile = NULL;
	if (pszBatchFile)
	{
		if (*pszBatchFile && !lbExecuteRc)
			mpsz_DeleteBatchFile = pszBatchFile;
			//DeleteFile(pszBatchFile);
		else
			SafeFree(pszBatchFile);
	}

	if (!lbExecuteRc)
	{
		m_UpdateStep = us_NotStarted;
		mb_DroppedMode = false;
	}

	return bRc;
}
Example #16
0
bool CBackgroundInfo::LoadBackgroundFile(bool abShowErrors)
{
	// Пустой путь - значит БЕЗ обоев
	if (!*ms_BgImage)
	{
		return true;
	}

	//_ASSERTE(isMainThread());

	_ASSERTE(isMainThread());
	bool lRes = false;
	BY_HANDLE_FILE_INFORMATION inf = {0};
	BITMAPFILEHEADER* pBkImgData = NULL;

	if (wcspbrk(ms_BgImage, L"%\\.") == NULL)
	{
		// May be "Solid color"
		COLORREF clr = (COLORREF)-1;
		if (GetColorRef(ms_BgImage, &clr))
		{
			pBkImgData = CreateSolidImage(clr, 128, 128);
		}
	}

	if (!pBkImgData)
	{
		wchar_t* exPath = ExpandEnvStr(ms_BgImage);

		if (!exPath || !*exPath)
		{
			if (abShowErrors)
			{
				wchar_t szError[MAX_PATH*2];
				DWORD dwErr = GetLastError();
				_wsprintf(szError, SKIPLEN(countof(szError)) L"Can't expand environment strings:\r\n%s\r\nError code=0x%08X\r\nImage loading failed",
				          ms_BgImage, dwErr);
				MBoxA(szError);
			}

			SafeFree(exPath);
			return false;
		}

		pBkImgData = LoadImageEx(exPath, inf);
		SafeFree(exPath);
	}

	if (pBkImgData)
	{
		ftBgModified = inf.ftLastWriteTime;
		nBgModifiedTick = GetTickCount();
		//NeedBackgroundUpdate();
		//MSectionLock SBG; SBG.Lock(&mcs_BgImgData);
		SafeFree(mp_BgImgData);
		mb_IsBackgroundImageValid = true;
		mp_BgImgData = pBkImgData;
		lRes = true;
	}

	return lRes;
}
Example #17
0
DWORD CConEmuUpdate::CheckProcInt()
{
	BOOL lbDownloadRc = FALSE, lbExecuteRc = FALSE;
	LPCWSTR pszUpdateVerLocationSet = mp_Set->UpdateVerLocation();
	wchar_t *pszUpdateVerLocation = NULL, *pszLocalPackage = NULL, *pszBatchFile = NULL;
	bool bTempUpdateVerLocation = false;
	wchar_t szSection[64], szItem[64];
	wchar_t szSourceFull[1024];
	wchar_t szTemplFilename[128];
	wchar_t *pszSource, *pszEnd, *pszFileName;
	DWORD nSrcLen, nSrcCRC, nLocalCRC = 0;
	bool lbSourceLocal;
	//INT_PTR nShellRc = 0;

#ifdef _DEBUG
	// Чтобы успел сервер проинититься и не ругался под отладчиком...
	if (!mb_ManualCallMode)
		Sleep(2500);
#endif

	_ASSERTE(m_UpdateStep==us_NotStarted);
	m_UpdateStep = us_Check;

	DeleteBadTempFiles();

	//120315 - OK, положим в архив и 64битный гуй
	//#ifdef _WIN64
	//if (mp_Set->UpdateDownloadSetup() == 2)
	//{
	//	if (mb_ManualCallMode)
	//	{
	//		ReportError(L"64bit versions of ConEmu may be updated with ConEmuSetup.exe only!", 0);
	//	}
	//	goto wrap;
	//}
	//#endif

	// This implies Inet.Deinit(false) too
	if (!Inet.Init(this))
	{
		goto wrap;
	}

	_wsprintf(ms_CurVersion, SKIPLEN(countof(ms_CurVersion)) L"%02u%02u%02u%s", (MVV_1%100),MVV_2,MVV_3,_T(MVV_4a));

	// Загрузить информацию о файлах обновления
	if (IsLocalFile(pszUpdateVerLocationSet))
	{
		pszUpdateVerLocation = (wchar_t*)pszUpdateVerLocationSet;
	}
	else
	{
		HANDLE hInfo = NULL;
		BOOL bInfoRc;
		DWORD crc;

		TODO("Было бы хорошо избавиться от *ini-файла* и парсить данные в памяти");
		pszUpdateVerLocation = CreateTempFile(mp_Set->szUpdateDownloadPath/*L"%TEMP%"*/, L"ConEmuVersion.ini", hInfo);
		if (!pszUpdateVerLocation)
			goto wrap;
		bTempUpdateVerLocation = true;

		bInfoRc = DownloadFile(pszUpdateVerLocationSet, pszUpdateVerLocation, hInfo, crc);
		CloseHandle(hInfo);
		if (!bInfoRc)
		{
			if (!mb_ManualCallMode)
			{
				DeleteFile(pszUpdateVerLocation);
				SafeFree(pszUpdateVerLocation);
			}
			goto wrap;
		}
	}

	// Проверить версии
	_wcscpy_c(szSection, countof(szSection),
		(mp_Set->isUpdateUseBuilds==1) ? sectionConEmuStable :
		(mp_Set->isUpdateUseBuilds==3) ? sectionConEmuPreview
		: sectionConEmuDevel);
	_wcscpy_c(szItem, countof(szItem), (mp_Set->UpdateDownloadSetup()==1) ? L"location_exe" : L"location_arc");

	if (!GetPrivateProfileString(szSection, L"version", L"", ms_NewVersion, countof(ms_NewVersion), pszUpdateVerLocation) || !*ms_NewVersion)
	{
		ReportBrokenIni(szSection, L"version", pszUpdateVerLocationSet);
		goto wrap;
	}

	// URL may not contain file name at all, compile it (predefined)
	_wsprintf(szTemplFilename, SKIPLEN(countof(szTemplFilename))
		(mp_Set->UpdateDownloadSetup()==1) ? L"ConEmuSetup.%s.exe" : L"ConEmuPack.%s.7z",
		ms_NewVersion);

	if (!GetPrivateProfileString(szSection, szItem, L"", szSourceFull, countof(szSourceFull), pszUpdateVerLocation) || !*szSourceFull)
	{
		ReportBrokenIni(szSection, szItem, pszUpdateVerLocationSet);
		goto wrap;
	}

	GetVersionsFromIni(pszUpdateVerLocation, ms_VerOnServer, ms_CurVerInfo);

	if ((lstrcmpi(ms_NewVersion, ms_CurVersion) <= 0)
		// Если пользователь отказался от обновления в этом сеансе - не предлагать ту же версию при ежечасных проверках
		|| (!mb_ManualCallMode && (lstrcmp(ms_NewVersion, ms_SkipVersion) == 0)))
	{
		// Новых версий нет
		if (mb_ManualCallMode)
		{
			wchar_t szFull[300];

			_wsprintf(szFull, SKIPLEN(countof(szFull)) 
				L"Your current ConEmu version is %s\n\n"
				L"Versions on server\n%s\n\n"
				L"No newer %s version is available",
				ms_CurVerInfo, ms_VerOnServer,
				(mp_Set->isUpdateUseBuilds==1) ? L"stable" : (mp_Set->isUpdateUseBuilds==3) ? L"preview" : L"developer", 0);
			ReportError(szFull, 0);
		}

		if (bTempUpdateVerLocation && pszUpdateVerLocation && *pszUpdateVerLocation)
		{
			DeleteFile(pszUpdateVerLocation);
			SafeFree(pszUpdateVerLocation);
		}
		goto wrap;
	}

	pszSource = szSourceFull;
	nSrcLen = wcstoul(pszSource, &pszEnd, 10);
	if (!nSrcLen || !pszEnd || *pszEnd != L',' || *(pszEnd+1) != L'x')
	{
		ReportError(L"Invalid format in version description (size)\n%s", szSourceFull, 0);
		goto wrap;
	}
	mn_PackageSize = nSrcLen;
	pszSource = pszEnd+2;
	nSrcCRC = wcstoul(pszSource, &pszEnd, 16);
	if (!nSrcCRC || !pszEnd || *pszEnd != L',')
	{
		ReportError(L"Invalid format in version description (CRC32)\n%s", szSourceFull, 0);
		goto wrap;
	}
	pszSource = pszEnd+1;
	lbSourceLocal = IsLocalFile(pszSource);

	if (mb_RequestTerminate)
		goto wrap;

	// It returns true, if updating with "exe" installer.
	if (!Check7zipInstalled())
		goto wrap; // Error already reported

	if (!QueryConfirmation(us_ConfirmDownload, pszSource))
	{
		// Если пользователь отказался от обновления в этом сеансе - не предлагать ту же версию при ежечасных проверках
		wcscpy_c(ms_SkipVersion, ms_NewVersion);
		goto wrap;
	}

	mn_InternetContentReady = 0;
	m_UpdateStep = us_Downloading;
	// May be null, if update package was dropped on ConEmu icon
	if (gpConEmu && ghWnd)
	{
		gpConEmu->UpdateProgress();
	}

	pszFileName = wcsrchr(pszSource, lbSourceLocal ? L'\\' : L'/');
	if (!pszFileName)
	{
		ReportError(L"Invalid source url\n%s", szSourceFull, 0);
		goto wrap;
	}
	else
	{
		// Загрузить пакет обновления
		pszFileName++; // пропустить слеш

		HANDLE hTarget = NULL;

		pszLocalPackage = CreateTempFile(mp_Set->szUpdateDownloadPath, szTemplFilename, hTarget);
		if (!pszLocalPackage)
			goto wrap;

		lbDownloadRc = DownloadFile(pszSource, pszLocalPackage, hTarget, nLocalCRC, TRUE);
		if (lbDownloadRc)
		{
			wchar_t szInfo[2048];
			LARGE_INTEGER liSize = {};
			if (!GetFileSizeEx(hTarget, &liSize) || liSize.HighPart || liSize.LowPart != nSrcLen)
			{
				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"%s\nRequired size=%u, local size=%u", pszSource, nSrcLen, liSize.LowPart);
				ReportError(L"Downloaded file does not match\n%s\n%s", pszLocalPackage, szInfo, 0);
				lbDownloadRc = FALSE;
			}
			else if (nLocalCRC != nSrcCRC)
			{
				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Required CRC32=x%08X, local CRC32=x%08X", nSrcCRC, nLocalCRC);
				ReportError(L"Invalid local file\n%s\n%s", pszLocalPackage, szInfo, 0);
				lbDownloadRc = FALSE;
			}
		}
		CloseHandle(hTarget);
		if (!lbDownloadRc)
			goto wrap;
	}

	Inet.Deinit(true);

	if (mb_RequestTerminate)
		goto wrap;

	pszBatchFile = CreateBatchFile(pszLocalPackage);
	if (!pszBatchFile)
		goto wrap;

	/*
	nShellRc = (INT_PTR)ShellExecute(ghWnd, bNeedRunElevation ? L"runas" : L"open", pszBatchFile, NULL, NULL, SW_SHOWMINIMIZED);
	if (nShellRc <= 32)
	{
		ReportError(L"Failed to start update batch\n%s\nError code=%i", pszBatchFile, (int)nShellRc);
		goto wrap;
	}
	*/
	if (!QueryConfirmation(us_ConfirmUpdate))
	{
		// Если пользователь отказался от обновления в этом сеансе - не предлагать ту же версию при ежечасных проверках
		wcscpy_c(ms_SkipVersion, ms_NewVersion);
		goto wrap;
	}
	mpsz_PendingPackageFile = pszLocalPackage;
	pszLocalPackage = NULL;
	mpsz_PendingBatchFile = pszBatchFile;
	pszBatchFile = NULL;
	m_UpdateStep = us_ExitAndUpdate;
	if (gpConEmu)
		gpConEmu->RequestExitUpdate();
	lbExecuteRc = TRUE;

wrap:
	_ASSERTE(mpsz_DeleteIniFile==NULL);
	mpsz_DeleteIniFile = NULL;
	if (bTempUpdateVerLocation && pszUpdateVerLocation)
	{
		if (*pszUpdateVerLocation)
			mpsz_DeleteIniFile = pszUpdateVerLocation;
			//DeleteFile(pszUpdateVerLocation);
		else
			SafeFree(pszUpdateVerLocation);
	}

	_ASSERTE(mpsz_DeletePackageFile==NULL);
	mpsz_DeletePackageFile = NULL;
	if (pszLocalPackage)
	{
		if (*pszLocalPackage && (!lbDownloadRc || (!lbExecuteRc && !mp_Set->isUpdateLeavePackages)))
			mpsz_DeletePackageFile = pszLocalPackage;
			//DeleteFile(pszLocalPackage);
		else
			SafeFree(pszLocalPackage);
	}

	_ASSERTE(mpsz_DeleteBatchFile==NULL);
	mpsz_DeleteBatchFile = NULL;
	if (pszBatchFile)
	{
		if (*pszBatchFile && !lbExecuteRc)
			mpsz_DeleteBatchFile = pszBatchFile;
			//DeleteFile(pszBatchFile);
		else
			SafeFree(pszBatchFile);
	}

	if (!lbExecuteRc)
		m_UpdateStep = us_NotStarted;

	Inet.Deinit(true);

	mb_InCheckProcedure = FALSE;
	return 0;
}
Example #18
0
//
//	IDataObject::GetData
//
HRESULT __stdcall CDataObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium)
{
	int idx;

	#ifdef _DEBUG
	wchar_t szDbg[200];
	#endif

	//
	// try to match the requested FORMATETC with one of our supported formats
	//
	if ((idx = LookupFormatEtc(pFormatEtc)) == -1)
	{
		#ifdef _DEBUG
		_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"!!! CDataObject::LookupFormatEtc(%s) failed\n", GetFormatName(pFormatEtc->cfFormat));
		DEBUGSTRDATA(szDbg);
		#endif
		return DV_E_FORMATETC;
	}

	#ifdef _DEBUG
	_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"CDataObject::GetData {cfFormat=%s, lindex=%i, tymed=x%02X(%u)})",
		GetFormatName(pFormatEtc->cfFormat), pFormatEtc->lindex, pFormatEtc->tymed, pFormatEtc->tymed);
	LPCWSTR pszName = GetFormatName(pFormatEtc->cfFormat, true);
	DWORD nData = (DWORD)-1;
	if (lstrcmp(pszName, L"IsShowingLayered")==0
		|| lstrcmp(pszName, L"IsShowingText")==0
		|| lstrcmp(pszName, L"DragContext")==0
		|| lstrcmp(pszName, L"UsingDefaultDragImage")==0
		|| lstrcmp(pszName, L"DragSourceHelperFlags")==0
		|| lstrcmp(pszName, L"DragWindow")==0
		|| lstrcmp(pszName, L"DisableDragText")==0
		)
	{
		LPDWORD pdw = (LPDWORD)GlobalLock(m_Data[idx].StgMedium.hGlobal);
		if (pdw)
		{
			nData = *pdw;
			int nLen = lstrlen(szDbg);
			_wsprintf(szDbg+nLen, SKIPLEN(countof(szDbg)-nLen) L", Data=x%02X(%u)", nData, nData);
		}
		GlobalUnlock(m_Data[idx].StgMedium.hGlobal);
	}
	wcscat_c(szDbg, L"\n");
	DEBUGSTRDATA(szDbg);
	#endif


	HRESULT hr = DV_E_FORMATETC;


	switch (m_Data[idx].FormatEtc.tymed)
	{
		case TYMED_HGLOBAL:
			//ReleaseStgMedium(pMedium);
			pMedium->hGlobal = DupMem(m_Data[idx].StgMedium.hGlobal);
			pMedium->pUnkForRelease = NULL; // m_Data[idx].StgMedium.pUnkForRelease;
			hr = S_OK;
			break;

		case TYMED_ISTREAM:
			_ASSERTE(pMedium->pstm != m_Data[idx].StgMedium.pstm);
			//ReleaseStgMedium(pMedium);
			pMedium->pstm = m_Data[idx].StgMedium.pstm;
			if (m_Data[idx].StgMedium.pstm)
				m_Data[idx].StgMedium.pstm->AddRef();
			pMedium->pUnkForRelease = m_Data[idx].StgMedium.pUnkForRelease;
			hr = S_OK;
			break;

		case TYMED_ISTORAGE:
			_ASSERTE(pMedium->pstg != m_Data[idx].StgMedium.pstg);
			//ReleaseStgMedium(pMedium);
			pMedium->pstg = m_Data[idx].StgMedium.pstg;
			if (m_Data[idx].StgMedium.pstg)
				m_Data[idx].StgMedium.pstg->AddRef();
			pMedium->pUnkForRelease = m_Data[idx].StgMedium.pUnkForRelease;
			hr = S_OK;
			break;
		default:
			AssertMsg(L"Unsupported value in m_Data[idx].FormatEtc.tymed");
	}

	if (hr == S_OK)
	{
		//
		// found a match! transfer the data into the supplied storage-medium
		//
		pMedium->tymed			 = m_Data[idx].FormatEtc.tymed;
		//Assert(pMedium->pUnkForRelease==NULL && m_Data[idx].StgMedium.pUnkForRelease==NULL);
		//pMedium->pUnkForRelease  = NULL;
	}
	else
	{
		#ifdef _DEBUG
		_wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"!!! CDataObject::GetData(tymed=%u) failed", m_Data[idx].FormatEtc.tymed);
		DEBUGSTRDATA(szDbg);
		//_ASSERTE(FALSE && "Unsupported tymed!");
		#endif
	}

	return hr;
}
Example #19
0
CConEmuUpdate::~CConEmuUpdate()
{
	if (mh_CheckThread)
	{
		DWORD nWait;
		if ((nWait = WaitForSingleObject(mh_CheckThread, 0)) == WAIT_TIMEOUT)
		{
			RequestTerminate();
			nWait = WaitForSingleObject(mh_CheckThread, UPDATETHREADTIMEOUT);
		}

		if (nWait != WAIT_OBJECT_0)
		{
			TerminateThread(mh_CheckThread, 100);
		}

		CloseHandle(mh_CheckThread);
		mh_CheckThread = NULL;
	}

	//if (mh_StopThread)
	//{
	//	CloseHandle(mh_StopThread);
	//	mh_StopThread = NULL;
	//}

	DeleteBadTempFiles();

	Inet.Deinit(true);

	SafeFree(ms_LastErrorInfo);

	if (mp_LastErrorSC)
	{
		delete mp_LastErrorSC;
		mp_LastErrorSC = NULL;
	}

	if (m_UpdateStep == us_ExitAndUpdate && mpsz_PendingBatchFile)
	{
		WaitAllInstances();

		wchar_t *pszCmd = lstrdup(L"cmd.exe"); // Мало ли что в ComSpec пользователь засунул...
		size_t cchParmMax = lstrlen(mpsz_PendingBatchFile)+16;
		wchar_t *pszParm = (wchar_t*)calloc(cchParmMax,sizeof(*pszParm));
		// Обязательно двойное окавычивание. cmd.exe отбрасывает кавычки,
		// и при наличии разделителей (пробелы, скобки,...) получаем проблемы
		_wsprintf(pszParm, SKIPLEN(cchParmMax) L"/c \"\"%s\"\"", mpsz_PendingBatchFile);

		// Наверное на Elevated процесс это не распространится, но для четкости - взведем флажок
		SetEnvironmentVariable(ENV_CONEMU_INUPDATE, ENV_CONEMU_INUPDATE_YES);

		// ghWnd уже закрыт
		INT_PTR nShellRc = (INT_PTR)ShellExecute(NULL, bNeedRunElevation ? L"runas" : L"open", pszCmd, pszParm, NULL, SW_SHOWMINIMIZED);
		if (nShellRc <= 32)
		{
			wchar_t szErrInfo[MAX_PATH*4];
			_wsprintf(szErrInfo, SKIPLEN(countof(szErrInfo))
				L"Failed to start update batch\n%s\nError code=%i", mpsz_PendingBatchFile, (int)nShellRc);
			MessageBoxW(NULL, szErrInfo, L"ConEmu", MB_ICONSTOP|MB_SYSTEMMODAL);

			DeleteFile(mpsz_PendingBatchFile);
			if (!(mp_Set && mp_Set->isUpdateLeavePackages))
				DeleteFile(mpsz_PendingPackageFile);
		}
		SafeFree(pszCmd);
		SafeFree(pszParm);
	}
	SafeFree(mpsz_PendingBatchFile);
	SafeFree(mpsz_PendingPackageFile);

	if (mp_Set)
	{
		delete mp_Set;
		mp_Set = NULL;
	}
}
Example #20
0
// Вызывается для инициализации из Settings::LoadSettings()
HWND CConEmuInside::InsideFindParent()
{
	bool bFirstStep = true;
	DWORD nParentPID = 0;

	if (!m_InsideIntegration)
	{
		return NULL;
	}

	if (mh_InsideParentWND)
	{
		if (IsWindow(mh_InsideParentWND))
		{
			if (m_InsideIntegration == ii_Simple)
			{
				if (mh_InsideParentRoot == NULL)
				{
					// Если еще не искали "корневое" окно
					HWND hParent = mh_InsideParentWND;
					while (hParent)
					{
						mh_InsideParentRoot = hParent;
						hParent = GetParent(hParent);
					}
				}
				// В этом режиме занимаем всю клиентскую область
				_ASSERTE(mh_InsideParentRel==NULL);
				mh_InsideParentRel = NULL;
			}

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

	_ASSERTE(m_InsideIntegration!=ii_Simple);

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

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


	HWND hExistConEmu;
	if ((hExistConEmu = InsideFindConEmu(mh_InsideParentRoot)) != NULL)
	{
		_ASSERTE(FALSE && "Continue to create tab in existing instance");
		// Если в проводнике уже есть ConEmu - открыть в нем новую вкладку
		gpSetCls->SingleInstanceShowHide = sih_None;
		LPCWSTR pszCmdLine = GetCommandLine();
		LPCWSTR pszCmd = StrStrI(pszCmdLine, L" /cmd ");
		gpConEmu->RunSingleInstance(hExistConEmu, pszCmd ? (pszCmd + 6) : NULL);

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

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

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

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

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

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

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

	return mh_InsideParentWND;
}
Example #21
0
wchar_t* CConEmuUpdate::CreateBatchFile(LPCWSTR asPackage)
{
	BOOL lbRc = FALSE;
	HANDLE hBatch = NULL;
	wchar_t* pszBatch = NULL;
	wchar_t* pszCommand = NULL;
	BOOL lbWrite;
	DWORD nLen, nWritten;
	char szOem[4096];
	LPCWSTR pszFormat = NULL;
	size_t cchCmdMax = 0;

	wchar_t szPID[16]; _wsprintf(szPID, SKIPLEN(countof(szPID)) L"%u", GetCurrentProcessId());
	wchar_t szCPU[4]; wcscpy_c(szCPU, WIN3264TEST(L"x86",L"x64"));
	WARNING("Битность установщика? Если ставим в ProgramFiles64 на Win64");

	if (!gpConEmu)
	{
		ReportError(L"CreateBatchFile failed, gpConEmu==NULL", 0); goto wrap;
	}

	pszBatch = CreateTempFile(mp_Set->szUpdateDownloadPath, L"ConEmuUpdate.cmd", hBatch);
	if (!pszBatch)
		goto wrap;

	#define WRITE_BATCH_A(s) \
		nLen = lstrlenA(s); \
		lbWrite = WriteFile(hBatch, s, nLen, &nWritten, NULL); \
		if (!lbWrite || (nLen != nWritten)) { ReportError(L"WriteBatch failed, code=%u", GetLastError()); goto wrap; }

	#define WRITE_BATCH_W(s) \
		nLen = WideCharToMultiByte(CP_OEMCP, 0, s, -1, szOem, countof(szOem), NULL, NULL); \
		if (!nLen) { ReportError(L"WideCharToMultiByte failed, len=%i", lstrlen(s)); goto wrap; } \
		WRITE_BATCH_A(szOem);

	WRITE_BATCH_A("@echo off\r\n");

	// "set ConEmuInUpdate=YES"
	WRITE_BATCH_W(L"\r\nset " ENV_CONEMU_INUPDATE L"=" ENV_CONEMU_INUPDATE_YES L"\r\n");

	WRITE_BATCH_A("cd /d \"");
	WRITE_BATCH_W(gpConEmu->ms_ConEmuExeDir);
	WRITE_BATCH_A("\\\"\r\necho Current folder\r\ncd\r\necho .\r\n\r\necho Starting update...\r\n");

	// Формат.
	pszFormat = (mp_Set->UpdateDownloadSetup()==1) ? mp_Set->UpdateExeCmdLine() : mp_Set->UpdateArcCmdLine();

	// Замена %1 и т.п.
	for (int s = 0; s < 2; s++)
	{
		// На первом шаге - считаем требуемый размер под pszCommand, на втором - формируем команду
		if (s)
		{
			if (!cchCmdMax)
			{
				ReportError(L"Invalid %s update command (%s)", (mp_Set->UpdateDownloadSetup()==1) ? L"exe" : L"arc", pszFormat, 0);
				goto wrap;
			}
			pszCommand = (wchar_t*)malloc((cchCmdMax+1)*sizeof(wchar_t));
		}
		wchar_t* pDst = pszCommand;
		LPCWSTR pszMacro;
		for (LPCWSTR pSrc = pszFormat; *pSrc; pSrc++)
		{
			switch (*pSrc)
			{
			case L'%':
				pSrc++;
				switch (*pSrc)
				{
				case L'%':
					pszMacro = L"%";
					break;
				// "%1"-archive or setup file, "%2"-ConEmu.exe folder, "%3"-x86/x64, "%4"-ConEmu PID
				case L'1':
					pszMacro = asPackage;
					break;
				case L'2':
					pszMacro = gpConEmu->ms_ConEmuExeDir;
					break;
				case L'3':
					pszMacro = szCPU;
					break;
				case L'4':
					pszMacro = szPID;
					break;
				default:
					// Недопустимый управляющий символ, это может быть переменная окружения
					pszMacro = NULL;
					pSrc--;
					if (s)
						*(pDst++) = L'%';
					else
						cchCmdMax++;
				}

				if (pszMacro)
				{
					size_t cchLen = _tcslen(pszMacro);
					if (s)
					{
						_wcscpy_c(pDst, cchLen+1, pszMacro);
						pDst += cchLen;
					}
					else
					{
						cchCmdMax += cchLen;
					}
				}
				break;
			default:
				if (s)
					*(pDst++) = *pSrc;
				else
					cchCmdMax++;
			}
		}
		if (s)
			*pDst = 0;
	}

	// Выполнить команду обновления
	WRITE_BATCH_A("echo ");
	WRITE_BATCH_W(pszCommand);
	WRITE_BATCH_A("\r\ncall ");
	WRITE_BATCH_W(pszCommand);
	WRITE_BATCH_A("\r\nif errorlevel 1 goto err\r\n");

	// Если юзер просил что-то выполнить после распаковки установки	
	if (mp_Set->szUpdatePostUpdateCmd && *mp_Set->szUpdatePostUpdateCmd)
	{
		WRITE_BATCH_A("\r\n");
		WRITE_BATCH_W(mp_Set->szUpdatePostUpdateCmd);
		WRITE_BATCH_A("\r\n");
	}

	// Сброс переменной окружения: "set ConEmuInUpdate="
	WRITE_BATCH_W(L"\r\nset " ENV_CONEMU_INUPDATE L"=\r\n");

	// Перезапуск ConEmu
	WRITE_BATCH_A("\r\necho Starting ConEmu...\r\nstart \"ConEmu\" \"");
	WRITE_BATCH_W(gpConEmu->ms_ConEmuExe);
	WRITE_BATCH_A("\" ");
	if (bNeedRunElevation)
	{
		WRITE_BATCH_A("/demote /cmd \"");
		WRITE_BATCH_W(gpConEmu->ms_ConEmuExe);
		WRITE_BATCH_A("\" ");
	}
	if (gpConEmu->mpsz_ConEmuArgs)
	{
		WRITE_BATCH_W(gpConEmu->mpsz_ConEmuArgs);
	}
	// Fin
	WRITE_BATCH_A("\r\ngoto fin\r\n");

	// Сообщение об ошибке?
	WRITE_BATCH_A("\r\n:err\r\n");
	WRITE_BATCH_A((mp_Set->UpdateDownloadSetup()==1) ? "echo \7Installation failed\7" : "echo \7Extraction failed\7\r\n");
	WRITE_BATCH_A("\r\npause\r\n:fin\r\n");

	// Грохнуть пакет обновления
	if (!mp_Set->isUpdateLeavePackages)
	{
		WRITE_BATCH_A("del \"");
		WRITE_BATCH_W(asPackage);
		WRITE_BATCH_A("\"\r\n");
	}

	// Грохнуть сам батч и позвать "exit" чтобы в консоли
	// не появлялось "Batch not found" при попытке выполнить следующую строку файла
	WRITE_BATCH_A("del \"%~0\" & exit\r\n");

	//// Для отладки
	//WRITE_BATCH_A("\r\npause\r\n");

	// Succeeded
	lbRc = TRUE;
wrap:
	SafeFree(pszCommand);

	if (!lbRc)
	{
		SafeFree(pszBatch);
	}

	if (hBatch && hBatch != INVALID_HANDLE_VALUE)
	{
		CloseHandle(hBatch);
	}
	return pszBatch;
}
Example #22
0
LRESULT CConEmuChild::BackWndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)
{
	LRESULT result = 0;

	// Logger
	MSG msgStr = {hWnd, messg, wParam, lParam};
	ConEmuMsgLogger::Log(msgStr, ConEmuMsgLogger::msgBack);

	if (gpSetCls->isAdvLogging >= 4)
	{
		gpConEmu->LogMessage(hWnd, messg, wParam, lParam);
	}

	CVConGuard guard;
	CVirtualConsole* pVCon = NULL;
	if (messg == WM_CREATE || messg == WM_NCCREATE)
	{
		LPCREATESTRUCT lp = (LPCREATESTRUCT)lParam;
		guard = (CVirtualConsole*)lp->lpCreateParams;
		pVCon = guard.VCon();
		if (pVCon)
			gVConBkMap.Set(hWnd, pVCon);
	}
	else if (hWnd != ghBkInDestroing)
	{
		if (!gVConBkMap.Get(hWnd, &pVCon) || !guard.Attach(pVCon))
			pVCon = NULL;
	}

	if (messg == WM_SYSCHAR)
	{
		_ASSERTE(FALSE); // по идее, фокуса тут быть не должно
		// Чтобы не пищало
		result = TRUE;
		goto wrap;
	}

	if (!pVCon)
	{
		_ASSERTE(pVCon!=NULL || hWnd==ghBkInDestroing);
		result = DefWindowProc(hWnd, messg, wParam, lParam);
		goto wrap;
	}

	switch (messg)
	{
	case WM_SHOWWINDOW:
			if (wParam)
			{
				HWND hView = pVCon->GetView();
				SetWindowPos(hView, HWND_TOP, 0, 0, 0,0, SWP_NOSIZE|SWP_NOMOVE);
				SetWindowPos(hWnd, hView, 0, 0, 0,0, SWP_NOSIZE|SWP_NOMOVE);
			}
			break; // DefaultProc
		case WM_SETFOCUS:
			// Если в консоли работает "GUI" окно (GUI режим), то фокус нужно отдать туда.
			{
				// Фокус должен быть в главном окне! За исключением случая работы в GUI режиме.
				pVCon->setFocus();
			}
			return 0;
		case WM_ERASEBKGND:
			result = 0;
			break;
		case WM_PAINT:
			_ASSERTE(hWnd == pVCon->mh_WndBack);
			pVCon->OnPaintGaps();
			break;
		case WM_KEYDOWN:
		case WM_KEYUP:
		case WM_SYSKEYDOWN:
		case WM_SYSKEYUP:
		case WM_MOUSEWHEEL:
		case WM_ACTIVATE:
		case WM_ACTIVATEAPP:
			//case WM_MOUSEACTIVATE:
		case WM_KILLFOCUS:
			//case WM_SETFOCUS:
		case WM_MOUSEMOVE:
		case WM_RBUTTONDOWN:
		case WM_RBUTTONUP:
		case WM_MBUTTONDOWN:
		case WM_MBUTTONUP:
		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		case WM_LBUTTONDBLCLK:
		case WM_MBUTTONDBLCLK:
		case WM_RBUTTONDBLCLK:
		case WM_XBUTTONDOWN:
		case WM_XBUTTONUP:
		case WM_XBUTTONDBLCLK:
		case WM_VSCROLL:
			// Вся обработка в родителе
			{
				switch (messg)
				{
					case WM_VSCROLL:
						switch (LOWORD(wParam))
						{
						case SB_THUMBTRACK:
						case SB_THUMBPOSITION:
							pVCon->mb_VTracking = TRUE;
							break;
						case SB_ENDSCROLL:
							pVCon->mb_VTracking = FALSE;
							break;
						}
						pVCon->RCon()->OnSetScrollPos(wParam);
						break;

					case WM_LBUTTONUP:
						pVCon->mb_VTracking = FALSE;
						break;
				}

				TODO("Обработка ghWndWork");
				HWND hParent = ghWnd;
				_ASSERTE(GetParent(hWnd)==ghWnd);

				if (messg >= WM_MOUSEFIRST && messg <= WM_MOUSELAST)
				{
					POINT pt = {LOWORD(lParam),HIWORD(lParam)};
					MapWindowPoints(hWnd, hParent, &pt, 1);
					lParam = MAKELONG(pt.x,pt.y);
				}

				result = gpConEmu->WndProc(hParent, messg, wParam, lParam);
			}
			break;
		case WM_IME_NOTIFY:
			break;
		case WM_INPUTLANGCHANGE:
		case WM_INPUTLANGCHANGEREQUEST:
			{
				#ifdef _DEBUG
				if (IsDebuggerPresent())
				{
					WCHAR szMsg[128];
					_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"InChild %s(CP:%i, HKL:0x%08X)\n",
							  (messg == WM_INPUTLANGCHANGE) ? L"WM_INPUTLANGCHANGE" : L"WM_INPUTLANGCHANGEREQUEST",
							  (DWORD)wParam, (DWORD)lParam);
					DEBUGSTRLANG(szMsg);
				}
				#endif
				result = DefWindowProc(hWnd, messg, wParam, lParam);
			} break;

#ifdef _DEBUG
		case WM_WINDOWPOSCHANGING:
			{
				WINDOWPOS* pwp = (WINDOWPOS*)lParam;
				result = DefWindowProc(hWnd, messg, wParam, lParam);
			}
			return result;
		case WM_WINDOWPOSCHANGED:
			{
				WINDOWPOS* pwp = (WINDOWPOS*)lParam;
				result = DefWindowProc(hWnd, messg, wParam, lParam);
			}
			break;
#endif
		case WM_SETCURSOR:
			{
				gpConEmu->WndProc(hWnd, messg, wParam, lParam);

				//if (!result)
				//	result = DefWindowProc(hWnd, messg, wParam, lParam);
			}
			// If an application processes this message, it should return TRUE to halt further processing or FALSE to continue.
			break;

		case WM_SYSCOMMAND:
			// -- лишние ограничения, похоже
			result = DefWindowProc(hWnd, messg, wParam, lParam);
			//if (wParam >= SC_SIZE && wParam <= SC_CONTEXTHELP/*0xF180*/)
			//{
			//	// Изменение размеров/максимизация/и т.п. окна консоли - запрещена
			//	_ASSERTE(!(wParam >= SC_SIZE && wParam <= SC_CONTEXTHELP));
			//}
			//else
			//{
			//	// По идее, сюда ничего приходить больше не должно
			//	_ASSERTE(FALSE);
			//}
			break;

		case WM_GESTURENOTIFY:
		case WM_GESTURE:
			{
				gpConEmu->ProcessGestureMessage(hWnd, messg, wParam, lParam, result);
				break;
			} // case WM_GESTURE, WM_GESTURENOTIFY

		default:

			if (pVCon && (messg == pVCon->mn_MsgRestoreChildFocus))
			{
				if (!gpConEmu->CanSetChildFocus())
				{
					// Клик по иконке открывает системное меню
					//_ASSERTE(FALSE && "Must not get here?");
				}
				else
				{
					CRealConsole* pRCon = pVCon->RCon();
					if (gpConEmu->isActive(pVCon, false))
					{
						pRCon->GuiWndFocusRestore();
					}

					if (pRCon->GuiWnd())
					{
						pRCon->StoreGuiChildRect(NULL);
					}
				}
			}
			else
			{
				result = DefWindowProc(hWnd, messg, wParam, lParam);
			}
	}

wrap:
	return result;
}
Example #23
0
LRESULT TrayIcon::OnTryIcon(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam)
{
	#ifdef _DEBUG
	wchar_t szMsg[128];
	#endif

	switch (lParam)
	{
		case WM_LBUTTONUP:
		case NIN_BALLOONUSERCLICK:
			#ifdef _DEBUG
			_wsprintf(szMsg, SKIPLEN(countof(szMsg)) (lParam==WM_LBUTTONUP) ? L"TSA: WM_LBUTTONUP(%i,0x%08X)\n" : L"TSA: NIN_BALLOONUSERCLICK(%i,0x%08X)\n", (int)wParam, (DWORD)lParam);
			DEBUGSTRICON(szMsg);
			#endif
			if (gpSet->isQuakeStyle)
			{
				SingleInstanceShowHideType sih = sih_ShowHideTSA;
				if (IsWindowVisible(ghWnd))
				{
					if (gpSet->isAlwaysOnTop || (gpSet->isQuakeStyle == 2))
					{
						sih = sih_HideTSA;
					}
					else
					{
						// Хм. Тут проблема. Если поверх ConEmu есть какое-то окно, то ConEmu нужно поднять?
					}
				}
				gpConEmu->OnMinimizeRestore(sih);
			}
			else
				Icon.RestoreWindowFromTray();
			if (m_MsgSource == tsa_Source_Updater)
			{
				m_MsgSource = tsa_Source_None;
				gpConEmu->CheckUpdates(2);
			}
			break;
		case NIN_BALLOONSHOW:
			#ifdef _DEBUG
			_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"TSA: NIN_BALLOONSHOW(%i,0x%08X)\n", (int)wParam, (DWORD)lParam);
			DEBUGSTRICON(szMsg);
			#endif
			mn_BalloonShowTick = GetTickCount();
			break;
		case NIN_BALLOONTIMEOUT:
			{
				#ifdef _DEBUG
				_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"TSA: NIN_BALLOONTIMEOUT(%i,0x%08X)\n", (int)wParam, (DWORD)lParam);
				DEBUGSTRICON(szMsg);
				#endif

				if (mb_SecondTimeoutMsg
					|| (mn_BalloonShowTick && ((GetTickCount() - mn_BalloonShowTick) > MY_BALLOON_TICK)))
				{
					m_MsgSource = tsa_Source_None;
					Icon.RestoreWindowFromTray(TRUE);
				}
				else if (!mb_SecondTimeoutMsg && (mn_BalloonShowTick && ((GetTickCount() - mn_BalloonShowTick) > MY_BALLOON_TICK)))
				{
					mb_SecondTimeoutMsg = true;
				}
			}
			break;
		case WM_RBUTTONUP:
		{
			#ifdef _DEBUG
			_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"TSA: WM_RBUTTONUP(%i,0x%08X)\n", (int)wParam, (DWORD)lParam);
			DEBUGSTRICON(szMsg);
			#endif
			POINT mPos;
			GetCursorPos(&mPos);
			apiSetForegroundWindow(ghWnd);
			gpConEmu->ShowSysmenu(mPos.x, mPos.y);
			PostMessage(hWnd, WM_NULL, 0, 0);
		}
		break;

	#ifdef _DEBUG
	default:
		_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"TSA: OnTryIcon(uMsg, wParam=%i, lParam=0x%04X)\n", messg, (int)wParam, (DWORD)lParam);
		DEBUGSTRICON(szMsg);
	#endif
	}

	return 0;
}
Example #24
0
bool GetAliases(wchar_t* asExeName, wchar_t** rsAliases, LPDWORD rnAliasesSize)
{
    bool lbRc = false;
    DWORD nAliasRC, nAliasErr, nAliasAErr = 0, nSizeA = 0;
    _ASSERTE(asExeName && rsAliases && rnAliasesSize);
    _ASSERTE(*rsAliases == NULL);
    *rnAliasesSize = GetConsoleAliasesLength(asExeName);

    if (*rnAliasesSize == 0)
    {
        lbRc = true;
    }
    else
    {
        *rsAliases = (wchar_t*)calloc(*rnAliasesSize+2,1);
        nAliasRC = GetConsoleAliases(*rsAliases,*rnAliasesSize,asExeName);

        if (nAliasRC)
        {
            lbRc = true;
        }
        else
        {
            nAliasErr = GetLastError();

            if (nAliasErr == ERROR_NOT_ENOUGH_MEMORY)
            {
                // Попробовать ANSI функции
                UINT nCP = CP_OEMCP;
                char szExeName[MAX_PATH+1];
                char *pszAliases = NULL;
                WideCharToMultiByte(nCP,0,asExeName,-1,szExeName,MAX_PATH+1,0,0);
                nSizeA = GetConsoleAliasesLengthA(szExeName);

                if (nSizeA)
                {
                    pszAliases = (char*)calloc(nSizeA+1,1);
                    nAliasRC = GetConsoleAliasesA(pszAliases,nSizeA,szExeName);

                    if (nAliasRC)
                    {
                        lbRc = true;
                        MultiByteToWideChar(nCP,0,pszAliases,nSizeA,*rsAliases,((*rnAliasesSize)/2)+1);
                    }
                    else
                    {
                        nAliasAErr = GetLastError();
                    }

                    free(pszAliases);
                }
            }

            if (!nAliasRC)
            {
                if ((*rnAliasesSize) < 255) {
                    free(*rsAliases);
                    *rsAliases = (wchar_t*)calloc(128,2);
                }

                _wsprintf(*rsAliases, SKIPLEN(127) L"\nConEmuC: GetConsoleAliases failed, ErrCode=0x%08X(0x%08X), AliasesLength=%i(%i)\n\n", nAliasErr, nAliasAErr, *rnAliasesSize, nSizeA);
            }
        }
    }

    return lbRc;
}
Example #25
0
int main(int argc, char** argv)
{
	int iRc = 0;
	HMODULE hConEmu;
	char szErrInfo[512];
	DWORD dwErr, dwOut;
	typedef int (__stdcall* ConsoleMain2_t)(BOOL abAlternative);
	ConsoleMain2_t lfConsoleMain2;

	#if defined(SHOW_STARTED_MSGBOX)
	if (!IsDebuggerPresent())
	{
		wchar_t szTitle[100]; _wsprintf(szTitle, SKIPLEN(countof(szTitle)) WIN3264TEST(L"ConEmuC",L"ConEmuC64") L" Loaded (PID=%i)", GetCurrentProcessId());
		const wchar_t* pszCmdLine = GetCommandLineW();
		MessageBox(NULL,pszCmdLine,szTitle,0);
	}
	#endif

	// Обязательно, иначе по CtrlC мы свалимся
	SetConsoleCtrlHandler((PHANDLER_ROUTINE)HandlerRoutine, true);

	#ifdef _DEBUG
	UnitTests();
	#endif
	

	hConEmu = LoadLibrary(WIN3264TEST(L"ConEmuCD.dll",L"ConEmuCD64.dll"));
	dwErr = GetLastError();

	if (!hConEmu)
	{
		_wsprintfA(szErrInfo, SKIPLEN(countof(szErrInfo))
		           "Can't load library \"%s\", ErrorCode=0x%08X\n",
		           WIN3264TEST(L"ConEmuCD.dll",L"ConEmuCD64.dll"),
		           dwErr);
		WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), szErrInfo, lstrlenA(szErrInfo), &dwOut, NULL);
		return CERR_CONEMUHK_NOTFOUND;
	}

	// Загрузить функи из ConEmuHk
	lfConsoleMain2 = (ConsoleMain2_t)GetProcAddress(hConEmu, "ConsoleMain2");
	gfHandlerRoutine = (PHANDLER_ROUTINE)GetProcAddress(hConEmu, "HandlerRoutine");

	if (!lfConsoleMain2 || !gfHandlerRoutine)
	{
		dwErr = GetLastError();
		_wsprintfA(szErrInfo, SKIPLEN(countof(szErrInfo))
		           "Procedure \"%s\"  not found in library \"%s\"",
		           lfConsoleMain2 ? "HandlerRoutine" : "ConsoleMain2",
		           WIN3264TEST(L"ConEmuCD.dll",L"ConEmuCD64.dll"));
		WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), szErrInfo, lstrlenA(szErrInfo), &dwOut, NULL);
		FreeLibrary(hConEmu);
		return CERR_CONSOLEMAIN_NOTFOUND;
	}

	// Main dll entry point for Server & ComSpec
	iRc = lfConsoleMain2(0/*WorkMode*/);
	// Exiting
	gfHandlerRoutine = NULL;
	//FreeLibrary(hConEmu); -- Shutdown Server/Comspec уже выполнен
	ExitProcess(iRc);
	return iRc;
}
Example #26
0
//
//	Wrapper around WM_SETCONSOLEINFO. We need to create the
//  necessary section (file-mapping) object in the context of the
//  process which owns the console, before posting the message
//
BOOL SetConsoleInfo(HWND hwndConsole, CONSOLE_INFO *pci)
{
    DWORD   dwConsoleOwnerPid, dwCurProcId;
    PVOID   ptrView = 0;
    DWORD   dwLastError=0;
    WCHAR   ErrText[255];
    //
    //	Retrieve the process which "owns" the console
    //
    dwCurProcId = GetCurrentProcessId();

    DEBUGTEST(DWORD dwConsoleThreadId =)
    GetWindowThreadProcessId(hwndConsole, &dwConsoleOwnerPid);

    // We'll fail, if console was created by other process
    if (dwConsoleOwnerPid != dwCurProcId)
    {
#ifdef _DEBUG
        // Wine related
        PROCESSENTRY32W pi = {};
        GetProcessInfo(dwConsoleOwnerPid, &pi);
        if (lstrcmpi(pi.szExeFile, L"wineconsole.exe")!=0)
        {
            wchar_t szDbgMsg[512], szTitle[128];
            szDbgMsg[0] = 0;
            GetModuleFileName(NULL, szDbgMsg, countof(szDbgMsg));
            msprintf(szTitle, countof(szTitle), L"%s: PID=%u", PointToName(szDbgMsg), GetCurrentProcessId());
            msprintf(szDbgMsg, countof(szDbgMsg), L"GetWindowThreadProcessId()\nPID=%u, TID=%u, %s\n%s",
                     dwConsoleOwnerPid, dwConsoleThreadId,
                     pi.szExeFile, szTitle);
            MessageBox(NULL, szDbgMsg, szTitle, MB_SYSTEMMODAL);
        }
        //_ASSERTE(dwConsoleOwnerPid == dwCurProcId);
#endif

        return FALSE;
    }

    //
    // Create a SECTION object backed by page-file, then map a view of
    // this section into the owner process so we can write the contents
    // of the CONSOLE_INFO buffer into it
    //
    if (!ghConsoleSection)
    {
        ghConsoleSection = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, gnConsoleSectionSize, 0);

        if (!ghConsoleSection)
        {
            dwLastError = GetLastError();
            _wsprintf(ErrText, SKIPLEN(countof(ErrText)) L"Can't CreateFileMapping(ghConsoleSection). ErrCode=%i", dwLastError);
            MessageBox(NULL, ErrText, L"ConEmu", MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
            return FALSE;
        }

        _ASSERTE(OnShutdownConsole==NULL || OnShutdownConsole==ShutdownConsole);
        OnShutdownConsole = ShutdownConsole;
    }

    //
    //	Copy our console structure into the section-object
    //
    ptrView = MapViewOfFile(ghConsoleSection, FILE_MAP_WRITE|FILE_MAP_READ, 0, 0, gnConsoleSectionSize);

    if (!ptrView)
    {
        dwLastError = GetLastError();
        _wsprintf(ErrText, SKIPLEN(countof(ErrText)) L"Can't MapViewOfFile. ErrCode=%i", dwLastError);
        MessageBox(NULL, ErrText, L"ConEmu", MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
    }
    else
    {
        _ASSERTE(pci->Length==sizeof(CONSOLE_INFO));
        //2010-09-19 что-то на XP стало окошко мелькать.
        // при отсылке WM_SETCONSOLEINFO консоль отображается :(
        BOOL lbWasVisible = IsWindowVisible(hwndConsole);
        RECT rcOldPos = {0}, rcAllMonRect = {0};

        if (!lbWasVisible)
        {
            GetWindowRect(hwndConsole, &rcOldPos);
            // В много-мониторных конфигурациях координаты на некоторых могут быть отрицательными!
            rcAllMonRect = GetAllMonitorsWorkspace();
            pci->AutoPosition = FALSE;
            pci->WindowPosX = rcAllMonRect.left - 1280;
            pci->WindowPosY = rcAllMonRect.top - 1024;
        }

        memcpy(ptrView, pci, pci->Length); //-V106
        UnmapViewOfFile(ptrView);

        //  Send console window the "update" message
        DEBUGTEST(LRESULT dwConInfoRc =)
        SendMessage(hwndConsole, WM_SETCONSOLEINFO, (WPARAM)ghConsoleSection, 0);

        DEBUGTEST(DWORD dwConInfoErr = GetLastError());

        if (!lbWasVisible && IsWindowVisible(hwndConsole))
        {
            //DEBUGTEST(Sleep(10));

            ShowWindow(hwndConsole, SW_HIDE);
            //SetWindowPos(hwndConsole, NULL, rcOldPos.left, rcOldPos.top, 0,0, SWP_NOSIZE|SWP_NOZORDER);
            // -- чтобы на некоторых системах не возникала проблема с позиционированием -> {0,0}
            // Issue 274: Окно реальной консоли позиционируется в неудобном месте
            SetWindowPos(hwndConsole, NULL, 0, 0, 0,0, SWP_NOSIZE|SWP_NOZORDER);
        }
    }

    return TRUE;
}
Example #27
0
BOOL CConEmuChild::ShowView(int nShowCmd)
{
	if (!this || !mh_WndDC)
		return FALSE;

	BOOL bRc = FALSE;
	DWORD nTID = 0, nPID = 0;
	wchar_t sInfo[200];

	// Должно быть создано в главной нити!
	nTID = GetWindowThreadProcessId(mh_WndDC, &nPID);

	#ifdef _DEBUG
	DWORD nMainThreadID = GetWindowThreadProcessId(ghWnd, &nPID);
	_ASSERTE(nTID==nMainThreadID);
	#endif

	// Если это "GUI" режим - могут возникать блокировки из-за дочернего окна
	CVirtualConsole* pVCon = mp_VCon;
	_ASSERTE(pVCon!=NULL);
	CVConGuard guard(pVCon);

	HWND hChildGUI = pVCon->GuiWnd();
	BOOL bGuiVisible = (hChildGUI && nShowCmd) ? pVCon->RCon()->isGuiVisible() : FALSE;
	DWORD nDcShowCmd = nShowCmd;


	if (gpSetCls->isAdvLogging)
	{
		if (hChildGUI != NULL)
			_wsprintf(sInfo, SKIPLEN(countof(sInfo)) L"ShowView: Back=x%08X, DC=x%08X, ChildGUI=x%08X, ShowCMD=%u, ChildVisible=%u",
				(DWORD)mh_WndBack, (DWORD)mh_WndDC, (DWORD)hChildGUI, nShowCmd, bGuiVisible);
		else
			_wsprintf(sInfo, SKIPLEN(countof(sInfo)) L"ShowView: Back=x%08X, DC=x%08X, ShowCMD=%u",
				(DWORD)mh_WndBack, (DWORD)mh_WndDC, nShowCmd);
		gpConEmu->LogString(sInfo);
	}


	if (hChildGUI || (GetCurrentThreadId() != nTID))
	{
		// Только Async, иначе можно получить dead-lock
		bRc = ShowWindowAsync(mh_WndBack, nShowCmd);
		if (bGuiVisible && !mp_VCon->RCon()->isGuiForceConView())
			nDcShowCmd = SW_HIDE;
		bRc = ShowWindowAsync(mh_WndDC, nDcShowCmd);
	}
	else
	{
		bRc = ShowWindow(mh_WndBack, nShowCmd);
		bRc = ShowWindow(mh_WndDC, nShowCmd);
		if (nShowCmd)
		{
			SetWindowPos(mh_WndDC, HWND_TOP, 0, 0, 0,0, SWP_NOSIZE|SWP_NOMOVE);
			SetWindowPos(mh_WndBack, mh_WndDC, 0, 0, 0,0, SWP_NOSIZE|SWP_NOMOVE);
		}
	}

	if (nShowCmd && bGuiVisible)
	{
		// Если активируется таб с ChildGui
		if (pVCon->isActive(false))
		{
			PostRestoreChildFocus();
		}
	}

	return bRc;
}
// Warning, напрямую НЕ вызывать. Пользоваться "общей" PostMacro
void CPluginW2800::PostMacroApi(const wchar_t* asMacro, INPUT_RECORD* apRec, bool abShowParseErrors)
{
	if (!InfoW2800 || !InfoW2800->AdvControl)
		return;

	MacroSendMacroText mcr = {sizeof(MacroSendMacroText)};
	//mcr.Flags = 0; // По умолчанию - вывод на экран разрешен
	bool bEnableOutput = true;

	while ((asMacro[0] == L'@' || asMacro[0] == L'^') && asMacro[1] && asMacro[1] != L' ')
	{
		switch (*asMacro)
		{
		case L'@':
			bEnableOutput = false;
			break;
		case L'^':
			mcr.Flags |= KMFLAGS_NOSENDKEYSTOPLUGINS;
			break;
		}
		asMacro++;
	}

	if (bEnableOutput)
		mcr.Flags |= KMFLAGS_ENABLEOUTPUT;

	// This macro was not adopted to Lua?
	_ASSERTE(*asMacro && *asMacro != L'$');

	// Вообще говоря, если тут попадается макрос в старом формате - то мы уже ничего не сделаем...
	// Начиная с Far 3 build 2851 - все макросы переведены на Lua

	mcr.SequenceText = asMacro;
	if (apRec)
		mcr.AKey = *apRec;

	mcr.Flags |= KMFLAGS_SILENTCHECK;

	if (!InfoW2800->MacroControl(&guid_ConEmu, MCTL_SENDSTRING, MSSC_CHECK, &mcr))
	{
		if (abShowParseErrors)
		{
			wchar_t* pszErrText = NULL;
			size_t iRcSize = InfoW2800->MacroControl(&guid_ConEmu, MCTL_GETLASTERROR, 0, NULL);
			MacroParseResult* Result = iRcSize ? (MacroParseResult*)calloc(iRcSize,1) : NULL;
			if (Result)
			{
				Result->StructSize = sizeof(*Result);
				_ASSERTE(FALSE && "Check MCTL_GETLASTERROR");
				InfoW2800->MacroControl(&guid_ConEmu, MCTL_GETLASTERROR, iRcSize, Result);

				size_t cchMax = (Result->ErrSrc ? lstrlen(Result->ErrSrc) : 0) + lstrlen(asMacro) + 255;
				pszErrText = (wchar_t*)malloc(cchMax*sizeof(wchar_t));
				_wsprintf(pszErrText, SKIPLEN(cchMax)
					L"Error in Macro. Far %u.%u build %u r%u\n"
					L"ConEmu plugin %02u%02u%02u%s[%u] {2800}\n"
					L"Code: %u, Line: %u, Col: %u%s%s\n"
					L"----------------------------------\n"
					L"%s",
					gFarVersion.dwVerMajor, gFarVersion.dwVerMinor, gFarVersion.dwBuild, gFarVersion.Bis ? 1 : 0,
					MVV_1, MVV_2, MVV_3, _CRT_WIDE(MVV_4a), WIN3264TEST(32,64),
					Result->ErrCode, (UINT)(int)Result->ErrPos.Y+1, (UINT)(int)Result->ErrPos.X+1,
					Result->ErrSrc ? L", Hint: " : L"", Result->ErrSrc ? Result->ErrSrc : L"",
					asMacro);

				SafeFree(Result);
			}
			else
			{
				size_t cchMax = lstrlen(asMacro) + 255;
				pszErrText = (wchar_t*)malloc(cchMax*sizeof(wchar_t));
				_wsprintf(pszErrText, SKIPLEN(cchMax)
					L"Error in Macro. Far %u.%u build %u r%u\n"
					L"ConEmu plugin %02u%02u%02u%s[%u] {2800}\n"
					L"----------------------------------\n"
					L"%s",
					gFarVersion.dwVerMajor, gFarVersion.dwVerMinor, gFarVersion.dwBuild, gFarVersion.Bis ? 1 : 0,
					MVV_1, MVV_2, MVV_3, _CRT_WIDE(MVV_4a), WIN3264TEST(32,64),
					asMacro);
			}

			if (pszErrText)
			{
				DWORD nTID;
				HANDLE h = CreateThread(NULL, 0, BackgroundMacroError, pszErrText, 0, &nTID);
				SafeCloseHandle(h);
			}
		}
	}
	else
	{
		//gFarVersion.dwBuild
		InfoW2800->MacroControl(&guid_ConEmu, MCTL_SENDSTRING, 0, &mcr);
	}
}
// Main function of this class decodes gesture information
// in:
//      hWnd        window handle
//      wParam      message parameter (message-specific)
//      lParam      message parameter (message-specific)
bool CGestures::ProcessGestureMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult)
{
	if ((uMsg != WM_GESTURENOTIFY) && (uMsg != WM_GESTURE))
		return false;

	if (!_isGestures)
	{
		_ASSERTE(_isGestures);
		gpConEmu->LogString(L"Gesture message received but not allowed, skipping");
		return false;
	}

	if (uMsg == WM_GESTURENOTIFY)
	{
		// This is the right place to define the list of gestures that this
		// application will support. By populating GESTURECONFIG structure
		// and calling SetGestureConfig function. We can choose gestures
		// that we want to handle in our application. In this app we
		// decide to handle all gestures.
		GESTURECONFIG gc[] = {
			{GID_ZOOM, GC_ZOOM},
			{GID_ROTATE, GC_ROTATE},
			{GID_PAN,
				GC_PAN|GC_PAN_WITH_GUTTER|GC_PAN_WITH_INERTIA,
				GC_PAN_WITH_SINGLE_FINGER_VERTICALLY|GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY
			},
			{GID_PRESSANDTAP, GC_PRESSANDTAP},
			{GID_TWOFINGERTAP, GC_TWOFINGERTAP},
		};

		BOOL bResult = _SetGestureConfig(hWnd, 0, countof(gc), gc, sizeof(GESTURECONFIG));
		DWORD dwErr = GetLastError();

		if (gpSetCls->isAdvLogging)
		{
			wchar_t szNotify[60];
			_wsprintf(szNotify, SKIPLEN(countof(szNotify)) L"SetGestureConfig -> %u,%u", bResult, dwErr);
			gpConEmu->LogString(szNotify);
		}

		if (!bResult)
		{
			DisplayLastError(L"Error in execution of SetGestureConfig", dwErr);
		}

		lResult = ::DefWindowProc(hWnd, WM_GESTURENOTIFY, wParam, lParam);

		return true;
	}

	// Остался только WM_GESTURE
	Assert(uMsg==WM_GESTURE);

	// helper variables
	POINT ptZoomCenter;
	double k;

	GESTUREINFO gi = {sizeof(gi)};
	// Checking for compiler alignment errors
	if (gi.cbSize != WIN3264TEST(48,56))
	{
		// Struct member alignment must be 8bytes even on x86
		Assert(sizeof(GESTUREINFO)==WIN3264TEST(48,56));
		_isGestures = false;
		return false;
	}
	BOOL bResult = _GetGestureInfo((HGESTUREINFO)lParam, &gi);

	if (!bResult)
	{
		//_ASSERT(L"_GetGestureInfo failed!" && 0);
		DWORD dwErr = GetLastError();
		DisplayLastError(L"Error in execution of _GetGestureInfo", dwErr);
		return FALSE;
	}

	#ifdef USE_DUMPGEST
	bool bLog = (gpSetCls->isAdvLogging >= 2);
	UNREFERENCED_PARAMETER(bLog);
	bLog = true;
	#endif

	#define DUMPGEST(tp) DumpGesture(tp, gi)

	//#ifdef USE_DUMPGEST
	//	wchar_t szDump[256];
	//	#define DUMPGEST(tp)
	//		_wsprintf(szDump, SKIPLEN(countof(szDump))
	//			L"Gesture(x%08X {%i,%i} %s",
	//			(DWORD)gi.hwndTarget, gi.ptsLocation.x, gi.ptsLocation.y,
	//			tp);
	//		if (gi.dwID==GID_PRESSANDTAP) {
	//			DWORD h = LODWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32)
	//				L" Dist={%i,%i}", (int)(short)LOWORD(h), (int)(short)HIWORD(h)); }
	//		if (gi.dwID==GID_ROTATE) {
	//			DWORD h = LODWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32)
	//				L" %i", (int)LOWORD(h)); }
	//		if (gi.dwFlags&GF_BEGIN) wcscat_c(szDump, L" GF_BEGIN");
	//		if (gi.dwFlags&GF_END) wcscat_c(szDump, L" GF_END");
	//		if (gi.dwFlags&GF_INERTIA) { wcscat_c(szDump, L" GF_INERTIA");
	//			DWORD h = HIDWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32)
	//				L" {%i,%i}", (int)(short)LOWORD(h), (int)(short)HIWORD(h)); }
	//		wcscat_c(szDump, L")\n");
	//		DEBUGSTR(szDump)
	//#else
	//#define DUMPGEST(s)
	//#endif

	switch (gi.dwID)
	{
	case GID_BEGIN:
		DUMPGEST(L"GID_BEGIN");
		break;

	case GID_END:
		DUMPGEST(L"GID_END");
		break;

	case GID_ZOOM:
		DUMPGEST(L"GID_ZOOM");
		if (gi.dwFlags & GF_BEGIN)
		{
			_dwArguments = LODWORD(gi.ullArguments);
			_ptFirst.x = gi.ptsLocation.x;
			_ptFirst.y = gi.ptsLocation.y;
			ScreenToClient(hWnd,&_ptFirst);
		}
		else
		{
			// We read here the second point of the gesture. This is middle point between
			// fingers in this new position.
			_ptSecond.x = gi.ptsLocation.x;
			_ptSecond.y = gi.ptsLocation.y;
			ScreenToClient(hWnd,&_ptSecond);

			// We have to calculate zoom center point
			ptZoomCenter.x = (_ptFirst.x + _ptSecond.x)/2;
			ptZoomCenter.y = (_ptFirst.y + _ptSecond.y)/2;

			// The zoom factor is the ratio between the new and the old distance.
			// The new distance between two fingers is stored in gi.ullArguments
			// (lower DWORD) and the old distance is stored in _dwArguments.
			k = (double)(LODWORD(gi.ullArguments))/(double)(_dwArguments);

			// Now we process zooming in/out of the object
			ProcessZoom(hWnd, k, ptZoomCenter.x, ptZoomCenter.y);

			// Now we have to store new information as a starting information
			// for the next step in this gesture.
			_ptFirst = _ptSecond;
			_dwArguments = LODWORD(gi.ullArguments);
		}
		break;

	case GID_PAN:
		DUMPGEST(L"GID_PAN");
		if (gi.dwFlags & GF_BEGIN)
		{
			_ptFirst.x = gi.ptsLocation.x;
			_ptFirst.y = gi.ptsLocation.y;
			_ptBegin.x = gi.ptsLocation.x;
			_ptBegin.y = gi.ptsLocation.y;
			ScreenToClient(hWnd, &_ptFirst);
		}
		else
		{
			// We read the second point of this gesture. It is a middle point
			// between fingers in this new position
			_ptSecond.x = gi.ptsLocation.x;
			_ptSecond.y = gi.ptsLocation.y;
			ScreenToClient(hWnd, &_ptSecond);

			if (!(gi.dwFlags & (GF_END/*|GF_INERTIA*/)))
			{
				// We apply move operation of the object
				if (ProcessMove(hWnd, _ptSecond.x-_ptFirst.x, _ptSecond.y-_ptFirst.y))
				{
					// We have to copy second point into first one to prepare
					// for the next step of this gesture.
					_ptFirst = _ptSecond;
				}
			}

		}
		break;

	case GID_ROTATE:
		DUMPGEST(L"GID_ROTATE");
		if (gi.dwFlags & GF_BEGIN)
		{
			_inRotate = false;
			_dwArguments = LODWORD(gi.ullArguments); // Запомним начальный угол
		}
		else
		{
			_ptFirst.x = gi.ptsLocation.x;
			_ptFirst.y = gi.ptsLocation.y;
			ScreenToClient(hWnd, &_ptFirst);
			// Пока угол не станет достаточным для смены таба - игнорируем
			if (ProcessRotate(hWnd,
					LODWORD(gi.ullArguments) - _dwArguments,
					_ptFirst.x,_ptFirst.y, ((gi.dwFlags & GF_END) == GF_END)))
			{
				_dwArguments = LODWORD(gi.ullArguments);
			}
		}
		break;

	case GID_TWOFINGERTAP:
		DUMPGEST(L"GID_TWOFINGERTAP");
		_ptFirst.x = gi.ptsLocation.x;
		_ptFirst.y = gi.ptsLocation.y;
		ScreenToClient(hWnd,&_ptFirst);
		ProcessTwoFingerTap(hWnd, _ptFirst.x, _ptFirst.y, LODWORD(gi.ullArguments));
		break;

	case GID_PRESSANDTAP:
		DUMPGEST(L"GID_PRESSANDTAP");
		if (gi.dwFlags & GF_BEGIN)
		{
			_ptFirst.x = gi.ptsLocation.x;
			_ptFirst.y = gi.ptsLocation.y;
			ScreenToClient(hWnd,&_ptFirst);
			DWORD nDelta = LODWORD(gi.ullArguments);
			short nDeltaX = (short)LOWORD(nDelta);
			short nDeltaY = (short)HIWORD(nDelta);
			ProcessPressAndTap(hWnd, _ptFirst.x, _ptFirst.y, nDeltaX, nDeltaY);
		}
		break;
	default:
		DUMPGEST(L"GID_<UNKNOWN>");
	}

	_CloseGestureInfoHandle((HGESTUREINFO)lParam);

	return TRUE;
}
Example #30
-1
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);
		}
	}
}