HWND WINAPI OnGetConsoleWindow(void) { //typedef HWND (WINAPI* OnGetConsoleWindow_t)(void); ORIGINALFAST(GetConsoleWindow); _ASSERTE(F(GetConsoleWindow) != GetRealConsoleWindow); // && F(GetConsoleWindow) != GetConsoleWindow - for minhook generation if (ghConEmuWndDC && IsWindow(ghConEmuWndDC) /*ghConsoleHwnd*/) { if (ghAttachGuiClient) { // В GUI режиме (notepad, putty) отдавать реальный результат GetRealConsoleWindow() // в этом режиме не нужно отдавать ни ghConEmuWndDC, ни серверную консоль HWND hReal = GetRealConsoleWindow(); return hReal; } else { //return ghConsoleHwnd; return ghConEmuWndDC; } } HWND h; h = F(GetConsoleWindow)(); return h; }
BOOL GuiSetForeground(HWND hWnd) { BOOL lbRc = FALSE; if (ghConEmuWndDC) { CESERVER_REQ *pIn = (CESERVER_REQ*)malloc(sizeof(*pIn)), *pOut; if (pIn) { ExecutePrepareCmd(pIn, CECMD_SETFOREGROUND, sizeof(CESERVER_REQ_HDR)+sizeof(u64)); //-V119 DWORD nConEmuPID = ASFW_ANY; GetWindowThreadProcessId(ghConEmuWndDC, &nConEmuPID); AllowSetForegroundWindow(nConEmuPID); pIn->qwData[0] = (u64)hWnd; HWND hConWnd = GetRealConsoleWindow(); pOut = ExecuteGuiCmd(hConWnd, pIn, hConWnd); if (pOut) { if (pOut->hdr.cbSize == (sizeof(CESERVER_REQ_HDR)+sizeof(DWORD))) lbRc = pOut->dwData[0]; ExecuteFreeResult(pOut); } free(pIn); } } return lbRc; }
DWORD WINAPI OnGetConsoleAliasesW(LPWSTR AliasBuffer, DWORD AliasBufferLength, LPWSTR ExeName) { //typedef DWORD (WINAPI* OnGetConsoleAliasesW_t)(LPWSTR AliasBuffer, DWORD AliasBufferLength, LPWSTR ExeName); ORIGINALFAST(GetConsoleAliasesW); DWORD nError = 0; DWORD nRc = F(GetConsoleAliasesW)(AliasBuffer,AliasBufferLength,ExeName); if (!nRc) { nError = GetLastError(); // финт ушами if (nError == ERROR_NOT_ENOUGH_MEMORY) // && gdwServerPID) { DWORD nServerPID = gnServerPID; HWND hConWnd = GetRealConsoleWindow(); _ASSERTE(hConWnd == ghConWnd); //MFileMapping<CESERVER_CONSOLE_MAPPING_HDR> ConInfo; //ConInfo.InitName(CECONMAPNAME, (DWORD)hConWnd); //-V205 //CESERVER_CONSOLE_MAPPING_HDR *pInfo = ConInfo.Open(); //if (pInfo // && (pInfo->cbSize >= sizeof(CESERVER_CONSOLE_MAPPING_HDR)) // //&& (pInfo->nProtocolVersion == CESERVER_REQ_VER) // ) //{ // nServerPID = pInfo->nServerPID; // ConInfo.CloseMap(); //} if (nServerPID) { CESERVER_REQ_HDR In; ExecutePrepareCmd(&In, CECMD_GETALIASES, sizeof(CESERVER_REQ_HDR)); CESERVER_REQ* pOut = ExecuteSrvCmd(nServerPID/*gdwServerPID*/, (CESERVER_REQ*)&In, hConWnd); if (pOut) { size_t nData = min(AliasBufferLength,(pOut->hdr.cbSize-sizeof(pOut->hdr))); if (nData) { memmove(AliasBuffer, pOut->Data, nData); nRc = TRUE; } ExecuteFreeResult(pOut); } } } if (!nRc) SetLastError(nError); // вернуть, вдруг какая функция его поменяла } return nRc; }
HWND CDefTermHk::AllocHiddenConsole(bool bTempForVS) { // функция AttachConsole есть только в WinXP и выше AttachConsole_t _AttachConsole = GetAttachConsoleProc(); if (!_AttachConsole) { LogHookingStatus(L"Can't create hidden console, function does not exist"); return NULL; } LogHookingStatus(L"AllocHiddenConsole"); ReloadSettings(); _ASSERTEX(isDefTermEnabled() && (gbIsNetVsHost || bTempForVS)); if (!isDefTermEnabled()) { // Disabled in settings or registry LogHookingStatus(L"Application skipped by settings"); return NULL; } HANDLE hSrvProcess = NULL; DWORD nAttachPID = bTempForVS ? 0 : gnSelfPID; DWORD nSrvPID = StartConsoleServer(nAttachPID, true, &hSrvProcess); if (!nSrvPID) { // Failed to start process? return NULL; } _ASSERTEX(hSrvProcess!=NULL); HWND hCreatedCon = NULL; // Do while server process is alive DWORD nStart = GetTickCount(), nMaxDelta = 30000, nDelta = 0; DWORD nWait = WaitForSingleObject(hSrvProcess, 0); while (nWait != WAIT_OBJECT_0) { if (_AttachConsole(nSrvPID)) { hCreatedCon = GetRealConsoleWindow(); if (hCreatedCon) break; } nWait = WaitForSingleObject(hSrvProcess, 150); nDelta = (GetTickCount() - nStart); if (nDelta > nMaxDelta) break; } return hCreatedCon; }
bool AttachServerConsole() { bool lbAttachRc = false; DWORD nErrCode; HWND hCurCon = GetRealConsoleWindow(); if (hCurCon == NULL && gnServerPID != 0) { // функция есть только в WinXP и выше AttachConsole_t _AttachConsole = GetAttachConsoleProc(); if (_AttachConsole) { lbAttachRc = (_AttachConsole(gnServerPID) != 0); if (!lbAttachRc) { nErrCode = GetLastError(); _ASSERTE(nErrCode==0 && lbAttachRc); } } } return lbAttachRc; }
void GuiFlashWindow(CEFlashType fType, HWND hWnd, BOOL bInvert, DWORD dwFlags, UINT uCount, DWORD dwTimeout) { if (ghConEmuWndDC) { CESERVER_REQ *pIn = (CESERVER_REQ*)malloc(sizeof(*pIn)), *pOut; if (pIn) { ExecutePrepareCmd(pIn, CECMD_FLASHWINDOW, sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_FLASHWINFO)); //-V119 pIn->Flash.fType = fType; pIn->Flash.hWnd = hWnd; pIn->Flash.bInvert = bInvert; pIn->Flash.dwFlags = dwFlags; pIn->Flash.uCount = uCount; pIn->Flash.dwTimeout = dwTimeout; HWND hConWnd = GetRealConsoleWindow(); pOut = ExecuteGuiCmd(hConWnd, pIn, hConWnd); if (pOut) ExecuteFreeResult(pOut); free(pIn); } } }
HINSTANCE WINAPI OnShellExecuteW(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd) { //typedef HINSTANCE(WINAPI* OnShellExecuteW_t)(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd); ORIGINAL_EX(ShellExecuteW); if (!F(ShellExecuteW)) { SetLastError(ERROR_INVALID_FUNCTION); return FALSE; } if (ghConEmuWndDC) { if (!hwnd || hwnd == GetRealConsoleWindow()) hwnd = ghConEmuWnd; } //gbInShellExecuteEx = TRUE; CShellProc* sp = new CShellProc(); if (!sp || !sp->OnShellExecuteW(&lpOperation, &lpFile, &lpParameters, &lpDirectory, NULL, (DWORD*)&nShowCmd)) { delete sp; SetLastError(ERROR_FILE_NOT_FOUND); return (HINSTANCE)ERROR_FILE_NOT_FOUND; } HINSTANCE lhRc; lhRc = F(ShellExecuteW)(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd); DWORD dwErr = GetLastError(); sp->OnShellFinished(((INT_PTR)lhRc > 32), lhRc, NULL); //-V112 delete sp; //gbInShellExecuteEx = FALSE; SetLastError(dwErr); return lhRc; }
BOOL WINAPI OnAllocConsole(void) { //typedef BOOL (WINAPI* OnAllocConsole_t)(void); ORIGINALFAST(AllocConsole); BOOL lbRc = FALSE, lbAllocated = FALSE; COORD crLocked; HMODULE hKernel = NULL; DWORD nErrCode = 0; BOOL lbAttachRc = FALSE; HWND hOldConWnd = GetRealConsoleWindow(); if (ph && ph->PreCallBack) { SETARGS(&lbRc); if (!ph->PreCallBack(&args)) return lbRc; } if (gbPrepareDefaultTerminal && gbIsNetVsHost) { if (!ghConWnd) gnVsHostStartConsole = 2; else gnVsHostStartConsole = 0; } // Попытаться создать консольное окно "по тихому" if (gpDefTerm && !hOldConWnd && !gnServerPID) { HWND hCreatedCon = gpDefTerm->AllocHiddenConsole(false); if (hCreatedCon) { hOldConWnd = hCreatedCon; lbAllocated = TRUE; } } // GUI приложение во вкладке. Если окна консоли еще нет - попробовать прицепиться // к родительской консоли (консоли серверного процесса) if ((gbAttachGuiClient || ghAttachGuiClient) && !gbPrepareDefaultTerminal) { if (AttachServerConsole()) { hOldConWnd = GetRealConsoleWindow(); lbAllocated = TRUE; // Консоль уже есть, ничего не надо } } DefTermMsg(L"AllocConsole calling"); if (!lbAllocated && F(AllocConsole)) { lbRc = F(AllocConsole)(); if (lbRc && !gbPrepareDefaultTerminal && IsVisibleRectLocked(crLocked)) { // Размер _видимой_ области. Консольным приложениям запрещено менять его "изнутри". // Размер может менять только пользователь ресайзом окна ConEmu HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO csbi = {}; if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) { //specified width and height cannot be less than the width and height of the console screen buffer's window SMALL_RECT rNewRect = {0, 0, crLocked.X-1, crLocked.Y-1}; OnSetConsoleWindowInfo(hStdOut, TRUE, &rNewRect); #ifdef _DEBUG COORD crNewSize = {crLocked.X, max(crLocked.Y, csbi.dwSize.Y)}; #endif hkFunc.setConsoleScreenBufferSize(hStdOut, crLocked); } } } //InitializeConsoleInputSemaphore(); if (ph && ph->PostCallBack) { SETARGS(&lbRc); ph->PostCallBack(&args); } HWND hNewConWnd = GetRealConsoleWindow(); // Обновить ghConWnd и мэппинг OnConWndChanged(hNewConWnd); #ifdef _DEBUG //_ASSERTEX(lbRc && ghConWnd); wchar_t szAlloc[500], szFile[MAX_PATH]; GetModuleFileName(NULL, szFile, countof(szFile)); msprintf(szAlloc, countof(szAlloc), L"OnAllocConsole\nOld=x%08X, New=x%08X, ghConWnd=x%08X\ngbPrepareDefaultTerminal=%i, gbIsNetVsHost=%i\n%s", LODWORD(hOldConWnd), LODWORD(hNewConWnd), LODWORD(ghConWnd), gbPrepareDefaultTerminal, gbIsNetVsHost, szFile); // VisualStudio host file calls AllocConsole TWICE(!) // Second call is totally spare (console already created) //MessageBox(NULL, szAlloc, L"OnAllocConsole called", MB_SYSTEMMODAL); #endif if (hNewConWnd && (hNewConWnd != hOldConWnd) && gpDefTerm && gbIsNetVsHost) { DefTermMsg(L"Calling gpDefTerm->OnAllocConsoleFinished"); gpDefTerm->OnAllocConsoleFinished(); SetLastError(0); } else if (hNewConWnd) { DefTermMsg(L"Console was already allocated"); } else { DefTermMsg(L"Something was wrong"); } TODO("Можно бы по настройке установить параметры. Кодовую страницу, например"); return lbRc; }