void * __cdecl xf_calloc(size_t _Count, size_t _Size XF_PLACE_ARGS_DEF) { _ASSERTE(ghHeap); _ASSERTE((_Count*_Size)>0); #ifdef TRACK_MEMORY_ALLOCATIONS #ifdef USE_XF_DUMP_CHK xf_dump_chk(); #endif size_t nTotalSize = _Count*_Size+sizeof(xf_mem_block)+8; xf_mem_block* p = (xf_mem_block*)HeapAlloc(ghHeap, HEAP_ZERO_MEMORY, nTotalSize); if (p) { p->bBlockUsed = TRUE; p->nBlockSize = _Count*_Size; xf_set_tag(p+1, lpszFileName, nLine); memset(((LPBYTE)(p+1))+_Count*_Size, 0xCC, 8); } else { _ASSERTE(p!=NULL); } return p?(p+1):p; #else void* p = HeapAlloc(ghHeap, HEAP_ZERO_MEMORY, _Count*_Size); return p; #endif }
void __cdecl xf_free ( void * _Memory #ifdef TRACK_MEMORY_ALLOCATIONS , LPCSTR lpszFileName, int nLine #endif ) { if (!_Memory) { return; // Nothing to do } if (!ghHeap) { //_ASSERTE(ghHeap && _Memory); #ifdef _DEBUG _CrtDbgBreak(); #endif return; } #ifdef TRACK_MEMORY_ALLOCATIONS xf_mem_block* p = ((xf_mem_block*)_Memory)-1; if (p->bBlockUsed == TRUE) { int nCCcmp = memcmp(((LPBYTE)_Memory)+p->nBlockSize, "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC", 8); _ASSERTE(nCCcmp == 0); memset(_Memory, 0xFD, p->nBlockSize); } else { _ASSERTE(p->bBlockUsed == TRUE); } p->bBlockUsed = FALSE; msprintf(p->sCreatedFrom, countof(p->sCreatedFrom), "-- %s:%i", _PointToName(lpszFileName), nLine); _Memory = (void*)p; #endif #ifdef _DEBUG size_t _Size1 = HeapSize(ghHeap, 0, _Memory); _ASSERTE(_Size1 > 0); #endif HeapFree(ghHeap, 0, _Memory); #ifdef FORCE_HEAP_CHECK xf_dump_chk(); #endif //#ifdef _DEBUG //SIZE_T _Size2 = HeapSize(ghHeap, 0, _Memory); //if (_Size1 == _Size2) { // _ASSERTE(_Size1 != _Size2); //} //#endif }
void * __cdecl xf_malloc ( size_t _Size #ifdef TRACK_MEMORY_ALLOCATIONS , LPCSTR lpszFileName, int nLine #endif ) { _ASSERTE(ghHeap); _ASSERTE(_Size>0); #ifdef TRACK_MEMORY_ALLOCATIONS #ifdef FORCE_HEAP_CHECK xf_dump_chk(); #endif size_t nTotalSize = _Size+sizeof(xf_mem_block)+8; xf_mem_block* p = (xf_mem_block*)HeapAlloc(ghHeap, 0, nTotalSize); if (p) { p->bBlockUsed = TRUE; p->nBlockSize = _Size; msprintf(p->sCreatedFrom, countof(p->sCreatedFrom), "%s:%i", _PointToName(lpszFileName), nLine); #ifdef _DEBUG if (_Size > 0) memset(p+1, 0xFD, _Size); #endif memset(((LPBYTE)(p+1))+_Size, 0xCC, 8); } else { _ASSERTE(p!=NULL); } return p?(p+1):p; #else void* p = HeapAlloc(ghHeap, 0, _Size); return p; #endif }
int ComspecInit() { TODO("Определить код родительского процесса, и если это FAR - запомнить его (для подключения к пайпу плагина)"); TODO("Размер получить из GUI, если оно есть, иначе - по умолчанию"); TODO("GUI может скорректировать размер с учетом полосы прокрутки"); WARNING("CreateFile(CONOUT$) по идее возвращает текущий ScreenBuffer. Можно его самим возвращать в ComspecDone"); // Правда нужно проверить, что там происходит с ghConOut.Close(),... // Размер должен менять сам GUI, через серверный ConEmuC! #ifdef SHOW_STARTED_MSGBOX MessageBox(GetConEmuHWND(2), L"ConEmuC (comspec mode) is about to START", L"ConEmuC.ComSpec", 0); #endif //int nNewBufferHeight = 0; //COORD crNewSize = {0,0}; //SMALL_RECT rNewWindow = gpSrv->sbi.srWindow; BOOL lbSbiRc = FALSE; gbRootWasFoundInCon = 2; // не добавлять к "Press Enter to close console" - "or wait" gbComspecInitCalled = TRUE; // Нельзя вызывать ComspecDone, если не было вызова ComspecInit // в режиме ComSpec - запрещено! gbAlwaysConfirmExit = FALSE; gbAutoDisableConfirmExit = FALSE; #ifdef _DEBUG xf_validate(); xf_dump_chk(); #endif // Это наверное и не нужно, просто для информации... lbSbiRc = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &gpSrv->sbi); #ifdef _DEBUG DWORD nErrCode = lbSbiRc ? 0 : GetLastError(); // Процесс запущен с редиректом вывода? _ASSERTE(lbSbiRc || (nErrCode == ERROR_INVALID_HANDLE)); #endif #if 0 // 111211 - "-new_console" теперь передается в GUI и исполняется в нем // Сюда мы попадаем если был ключик -new_console // А этом случае нужно завершить ЭТОТ экземпляр и запустить в ConEmu новую вкладку if (gpSrv->bNewConsole) { #ifdef _DEBUG xf_validate(); xf_dump_chk(); #endif PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); STARTUPINFOW si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USECOUNTCHARS; si.dwXCountChars = gpSrv->sbi.dwSize.X; si.dwYCountChars = gpSrv->sbi.dwSize.Y; si.wShowWindow = SW_HIDE; PRINT_COMSPEC(L"Creating new console for:\n%s\n", gpszRunCmd); #ifdef _DEBUG xf_validate(); xf_dump_chk(); #endif // CREATE_NEW_PROCESS_GROUP - низя, перестает работать Ctrl-C // Запускается новый сервер (новая консоль), сюда хуки ставить не надо. BOOL lbRc = createProcess(TRUE, NULL, gpszRunCmd, NULL,NULL, TRUE, NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); DWORD dwErr = GetLastError(); if (!lbRc) { PrintExecuteError(gpszRunCmd, dwErr); return CERR_CREATEPROCESS; } #ifdef _DEBUG xf_validate(); xf_dump_chk(); #endif //delete psNewCmd; psNewCmd = NULL; AllowSetForegroundWindow(pi.dwProcessId); PRINT_COMSPEC(L"New console created. PID=%i. Exiting...\n", pi.dwProcessId); SafeCloseHandle(pi.hProcess); SafeCloseHandle(pi.hThread); DisableAutoConfirmExit(); //gpSrv->nProcessStartTick = GetTickCount() - 2*CHECK_ROOTSTART_TIMEOUT; // менять nProcessStartTick не нужно. проверка только по флажкам #ifdef _DEBUG xf_validate(); xf_dump_chk(); #endif return CERR_RUNNEWCONSOLE; } #endif // Если определена ComSpecC - значит ConEmuC переопределил стандартный ComSpec // Вернем его wchar_t szComSpec[MAX_PATH+1]; const wchar_t* pszComSpecName; //110202 - comspec более не переопределяется //if (GetEnvironmentVariable(L"ComSpecC", szComSpec, MAX_PATH) && szComSpec[0] != 0) WARNING("TCC/ComSpec"); if (GetEnvironmentVariable(L"ComSpec", szComSpec, MAX_PATH) && szComSpec[0] != 0) { //// Только если это (случайно) не conemuc.exe //wchar_t* pwszCopy = (wchar_t*)PointToName(szComSpec); //wcsrchr(szComSpec, L'\\'); ////if (!pwszCopy) pwszCopy = szComSpec; //#pragma warning( push ) //#pragma warning(disable : 6400) //if (lstrcmpiW(pwszCopy, L"ConEmuC")==0 || lstrcmpiW(pwszCopy, L"ConEmuC.exe")==0 // /*|| lstrcmpiW(pwszCopy, L"ConEmuC64")==0 || lstrcmpiW(pwszCopy, L"ConEmuC64.exe")==0*/) // szComSpec[0] = 0; //#pragma warning( pop ) //if (szComSpec[0]) //{ // SetEnvironmentVariable(L"ComSpec", szComSpec); // SetEnvironmentVariable(L"ComSpecC", NULL); //} pszComSpecName = (wchar_t*)PointToName(szComSpec); } else { WARNING("TCC/ComSpec"); pszComSpecName = L"cmd.exe"; } lstrcpyn(gpSrv->szComSpecName, pszComSpecName, countof(gpSrv->szComSpecName)); if (pszComSpecName) { wchar_t szSelf[MAX_PATH+1]; if (GetModuleFileName(NULL, szSelf, MAX_PATH)) { lstrcpyn(gpSrv->szSelfName, (wchar_t*)PointToName(szSelf), countof(gpSrv->szSelfName)); if (!GetAliases(gpSrv->szSelfName, &gpSrv->pszPreAliases, &gpSrv->nPreAliasSize)) { if (gpSrv->pszPreAliases) { _wprintf(gpSrv->pszPreAliases); free(gpSrv->pszPreAliases); gpSrv->pszPreAliases = NULL; } } } } SendStarted(); //ConOutCloseHandle() return 0; }
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); }