bool GetShortFileName(LPCWSTR asFullPath, int cchShortNameMax, wchar_t* rsShortName/*[MAX_PATH+1]-name only*/, BOOL abFavorLength/*=FALSE*/) { WARNING("FindFirstFile использовать нельзя из-за симлинков"); WIN32_FIND_DATAW fnd; memset(&fnd, 0, sizeof(fnd)); HANDLE hFind = FindFirstFile(asFullPath, &fnd); if (hFind == INVALID_HANDLE_VALUE) return false; FindClose(hFind); if (fnd.cAlternateFileName[0]) { if ((abFavorLength && (lstrlenW(fnd.cAlternateFileName) < lstrlenW(fnd.cFileName))) //-V303 || (wcschr(fnd.cFileName, L' ') != NULL)) { if (lstrlen(fnd.cAlternateFileName) >= cchShortNameMax) //-V303 return false; _wcscpy_c(rsShortName, cchShortNameMax, fnd.cAlternateFileName); //-V106 return TRUE; } } else if (wcschr(fnd.cFileName, L' ') != NULL) { return false; } if (lstrlen(fnd.cFileName) >= cchShortNameMax) //-V303 return false; _wcscpy_c(rsShortName, cchShortNameMax, fnd.cFileName); //-V106 return true; }
wchar_t* lstrmerge(const wchar_t* asStr1, const wchar_t* asStr2, const wchar_t* asStr3 /*= NULL*/, const wchar_t* asStr4 /*= NULL*/) { size_t cchMax = 1; const size_t Count = 4; size_t cch[Count] = {}; const wchar_t* pszStr[Count] = {asStr1, asStr2, asStr3, asStr4}; for (size_t i = 0; i < Count; i++) { cch[i] = pszStr[i] ? lstrlen(pszStr[i]) : 0; cchMax += cch[i]; } wchar_t* pszRet = (wchar_t*)malloc(cchMax*sizeof(*pszRet)); if (!pszRet) return NULL; *pszRet = 0; wchar_t* psz = pszRet; for (size_t i = 0; i < Count; i++) { if (!cch[i]) continue; _wcscpy_c(psz, cch[i]+1, pszStr[i]); psz += cch[i]; } return pszRet; }
void CommandTasks::SetName(LPCWSTR asName, int anCmdIndex) { wchar_t szCmd[16]; if (anCmdIndex == -1) { wcscpy_c(szCmd, AutoStartTaskName); asName = szCmd; } else if (!asName || !*asName) { _wsprintf(szCmd, SKIPLEN(countof(szCmd)) L"Group%i", (anCmdIndex+1)); asName = szCmd; } // Для простоты дальнейшей работы - имя должно быть заключено в угловые скобки size_t iLen = wcslen(asName); if (!pszName || ((iLen+2) >= cchNameMax)) { SafeFree(pszName); cchNameMax = iLen+16; pszName = (wchar_t*)malloc(cchNameMax*sizeof(wchar_t)); if (!pszName) { _ASSERTE(pszName!=NULL); return; } } if (asName[0] == TaskBracketLeft) { _wcscpy_c(pszName, iLen+1, asName); } else { *pszName = TaskBracketLeft; _wcscpy_c(pszName+1, iLen+1, asName); } if (asName[iLen-1] != TaskBracketRight) { iLen = wcslen(pszName); pszName[iLen++] = TaskBracketRight; pszName[iLen] = 0; } }
// Set resource item bool CLngRc::SetResource(MArray<LngRcItem>& arr, int idx, LPCWSTR asValue, bool bLocalized) { if (idx < 0) { _ASSERTE(idx >= 0); return false; } _ASSERTE(!bLocalized || (asValue && *asValue)); if (idx >= arr.size()) { LngRcItem dummy = {}; arr.set_at(idx, dummy); } bool bOk = false; LngRcItem& item = arr[idx]; // Caching: no resource was found for that id if (!asValue || !*asValue) { if (item.Str) item.Str[0] = 0; item.Processed = true; item.Localized = false; return true; } size_t iLen = wcslen(asValue); if (iLen >= (u16)-1) { // Too long string? _ASSERTE(iLen < (u16)-1); } else { if (item.Str && (item.MaxLen >= iLen)) { _wcscpy_c(item.Str, item.MaxLen, asValue); } else { //TODO: thread-safe SafeFree(item.Str); item.MaxLen = iLen; item.Str = lstrdup(asValue); } bOk = (item.Str != NULL); } item.Processed = bOk; item.Localized = (bOk && bLocalized); return bOk; }
wchar_t* GetCliboardText(DWORD& rnErrCode, wchar_t* rsErrText, INT_PTR cchErrMax) { if (!rsErrText || cchErrMax < 255) { _ASSERTE(FALSE && "Invalid arguments"); return NULL; } HGLOBAL hglb; LPCWSTR lptstr; wchar_t* pszBuf = NULL; if ((hglb = GetClipboardData(CF_UNICODETEXT)) == NULL) { rnErrCode = GetLastError(); _wsprintf(rsErrText, SKIPLEN(cchErrMax) L"Clipboard does not contain CF_UNICODETEXT, nothing to paste (code=%u)", rnErrCode); gpConEmu->LogString(rsErrText); _wcscpy_c(rsErrText, cchErrMax, L"Available formats:"); int nLen = lstrlen(rsErrText); UINT fmt = 0; while (((nLen + 11) < cchErrMax) && ((fmt = EnumClipboardFormats(fmt)) != 0)) { _wsprintf(rsErrText+nLen, SKIPLEN(cchErrMax-nLen) L" x%04X", fmt); nLen += lstrlen(rsErrText+nLen); } gpConEmu->LogString(rsErrText); rsErrText[0] = 0; // Don't call DisplayLastError TODO("Сделать статусное сообщение с таймаутом"); //this->SetConStatus(L"Clipboard does not contains text. Nothing to paste."); } else if ((lptstr = (LPCWSTR)GlobalLock(hglb)) == NULL) { rnErrCode = GetLastError(); _wsprintf(rsErrText, SKIPLEN(cchErrMax) L"Can't lock CF_UNICODETEXT, paste failed (code=%u)", rnErrCode); gpConEmu->LogString(rsErrText); } else if (*lptstr == 0) { rnErrCode = GetLastError(); _wsprintf(rsErrText, SKIPLEN(cchErrMax) L"CF_UNICODETEXT is empty, nothing to paste (code=%u)", rnErrCode); gpConEmu->LogString(rsErrText); rsErrText[0] = 0; // Don't call DisplayLastError GlobalUnlock(hglb); } else { pszBuf = lstrdup(lptstr, 1); // Reserve memory for space-termination Assert(pszBuf!=NULL); GlobalUnlock(hglb); } return pszBuf; }
/* ************** */ HMODULE WINAPI OnLoadLibraryWWork(FARPROC lpfn, HookItem *ph, BOOL bMainThread, const wchar_t* lpFileName) { typedef HMODULE(WINAPI* OnLoadLibraryW_t)(const wchar_t* lpFileName); HMODULE module = NULL; OnLoadLibraryLog(NULL,lpFileName); // Спрятать ExtendedConsole.dll с глаз долой, в сервисную папку "ConEmu" if (lpFileName && ((lstrcmpiW(lpFileName, L"ExtendedConsole.dll") == 0) || lstrcmpiW(lpFileName, L"ExtendedConsole64.dll") == 0)) { CESERVER_CONSOLE_MAPPING_HDR *Info = (CESERVER_CONSOLE_MAPPING_HDR*)calloc(1,sizeof(*Info)); if (Info && ::LoadSrvMapping(ghConWnd, *Info)) { size_t cchMax = countof(Info->ComSpec.ConEmuBaseDir)+64; wchar_t* pszFullPath = (wchar_t*)calloc(cchMax,sizeof(*pszFullPath)); if (pszFullPath) { _wcscpy_c(pszFullPath, cchMax, Info->ComSpec.ConEmuBaseDir); _wcscat_c(pszFullPath, cchMax, WIN3264TEST(L"\\ExtendedConsole.dll",L"\\ExtendedConsole64.dll")); module = ((OnLoadLibraryW_t)lpfn)(pszFullPath); SafeFree(pszFullPath); } } SafeFree(Info); } if (!module) module = ((OnLoadLibraryW_t)lpfn)(lpFileName); DWORD dwLoadErrCode = GetLastError(); if (gbLdrDllNotificationUsed) return module; // Issue 1079: Almost hangs with PHP if (lstrcmpi(lpFileName, L"kernel32.dll") == 0) return module; if (PrepareNewModule(module, NULL, lpFileName)) { if (ph && ph->PostCallBack) { SETARGS1(&module,lpFileName); ph->PostCallBack(&args); } } SetLastError(dwLoadErrCode); return module; }
void AppSettings::SetNames(LPCWSTR asAppNames) { size_t iLen = wcslen(asAppNames); if (!AppNames || !AppNamesLwr || (iLen >= cchNameMax)) { SafeFree(AppNames); SafeFree(AppNamesLwr); cchNameMax = iLen+32; AppNames = (wchar_t*)malloc(cchNameMax*sizeof(wchar_t)); AppNamesLwr = (wchar_t*)malloc(cchNameMax*sizeof(wchar_t)); if (!AppNames || !AppNamesLwr) { _ASSERTE(AppNames!=NULL && AppNamesLwr!=NULL); return; } } _wcscpy_c(AppNames, iLen+1, asAppNames); _wcscpy_c(AppNamesLwr, iLen+1, asAppNames); CharLowerBuff(AppNamesLwr, iLen); }
INT_PTR CSetDlgLists::GetSelectedString(HWND hParent, WORD nListCtrlId, wchar_t** ppszStr) { INT_PTR nCur = SendDlgItemMessage(hParent, nListCtrlId, CB_GETCURSEL, 0, 0); INT_PTR nLen = (nCur >= 0) ? SendDlgItemMessage(hParent, nListCtrlId, CB_GETLBTEXTLEN, nCur, 0) : -1; if (!ppszStr) return nLen; if (nLen<=0) { if (*ppszStr) {free(*ppszStr); *ppszStr = NULL;} } else { wchar_t* pszNew = (TCHAR*)calloc(nLen+1, sizeof(TCHAR)); if (!pszNew) { _ASSERTE(pszNew!=NULL); } else { SendDlgItemMessage(hParent, nListCtrlId, CB_GETLBTEXT, nCur, (LPARAM)pszNew); if (*ppszStr) { if (lstrcmp(*ppszStr, pszNew) == 0) { free(pszNew); return nLen; // Изменений не было } } if (nLen > (*ppszStr ? (INT_PTR)_tcslen(*ppszStr) : 0)) { if (*ppszStr) free(*ppszStr); *ppszStr = pszNew; pszNew = NULL; } else { _wcscpy_c(*ppszStr, nLen+1, pszNew); SafeFree(pszNew); } } } return nLen; }
size_t CConEmuCtrl::GetOpenedPanels(wchar_t*& pszDirs, int& iCount, int& iCurrent) { CmdArg szActiveDir, szPassive; CVConGuard VCon; MArray<wchar_t*> Dirs; size_t cchAllLen = 1; iCount = iCurrent = 0; for (int V = 0; CVConGroup::GetVCon(V, &VCon, true); V++) { VCon->RCon()->GetPanelDirs(szActiveDir, szPassive); if (VCon->isActive(false)) iCurrent = iCount; LPCWSTR psz[] = {szActiveDir.ms_Arg, szPassive.ms_Arg}; for (int i = 0; i <= 1; i++) { if (psz[i] && psz[i][0]) { int iLen = lstrlen(psz[i]); cchAllLen += (iLen+1); Dirs.push_back(lstrdup(psz[i])); iCount++; } } } _ASSERTE(pszDirs == NULL); pszDirs = (wchar_t*)malloc(cchAllLen*sizeof(*pszDirs)); if (!pszDirs) return 0; wchar_t* psz = pszDirs; for (int i = 0; i < Dirs.size(); i++) { wchar_t* p = Dirs[i]; _wcscpy_c(psz, cchAllLen, p); psz += lstrlen(psz)+1; free(p); } return cchAllLen; }
void CommandTasks::SetCommands(LPCWSTR asCommands) { if (!asCommands) asCommands = L""; size_t iLen = wcslen(asCommands); if (!pszCommands || (iLen >= cchCmdMax)) { SafeFree(pszCommands); cchCmdMax = iLen+1024; pszCommands = (wchar_t*)malloc(cchCmdMax*sizeof(wchar_t)); if (!pszCommands) { _ASSERTE(pszCommands!=NULL); return; } } _wcscpy_c(pszCommands, cchCmdMax, asCommands); }
void CommandTasks::SetGuiArg(LPCWSTR asGuiArg) { if (!asGuiArg) asGuiArg = L""; size_t iLen = wcslen(asGuiArg); if (!pszGuiArgs || (iLen >= cchGuiArgMax)) { SafeFree(pszGuiArgs); cchGuiArgMax = iLen+256; pszGuiArgs = (wchar_t*)malloc(cchGuiArgMax*sizeof(wchar_t)); if (!pszGuiArgs) { _ASSERTE(pszGuiArgs!=NULL); return; } } _wcscpy_c(pszGuiArgs, cchGuiArgMax, asGuiArg); }
int InjectRemote(DWORD nRemotePID, bool abDefTermOnly /*= false */) { int iRc = -1; bool lbWin64 = WIN3264TEST((IsWindows64()!=0),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(szHooks, 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 != CERR_HOOKS_WAS_SET) && (nWrapperResult != CERR_HOOKS_WAS_ALREADY_SET)) { 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; }
DWORD WINAPI DebugThread(LPVOID lpvParam) { DWORD nWait = WAIT_TIMEOUT; //DWORD nExternalExitCode = -1; wchar_t szInfo[1024]; if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL) { STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi = {}; if (gpSrv->DbgInfo.bDebugProcessTree) { SetEnvironmentVariable(ENV_CONEMU_BLOCKCHILDDEBUGGERS_W, ENV_CONEMU_BLOCKCHILDDEBUGGERS_YES); } if (!CreateProcess(NULL, gpSrv->DbgInfo.pszDebuggingCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE| DEBUG_PROCESS | (gpSrv->DbgInfo.bDebugProcessTree ? 0 : DEBUG_ONLY_THIS_PROCESS), NULL, NULL, &si, &pi)) { DWORD dwErr = GetLastError(); wchar_t szProc[64]; szProc[0] = 0; PROCESSENTRY32 pi = {sizeof(pi)}; if (GetProcessInfo(gpSrv->dwRootProcess, &pi)) _wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc)); _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start debugging process. ErrCode=0x%08X\n", dwErr); lstrcpyn(szInfo+lstrlen(szInfo), gpSrv->DbgInfo.pszDebuggingCmdLine, 400); wcscat_c(szInfo, L"\n"); _wprintf(szInfo); return CERR_CANTSTARTDEBUGGER; } gpSrv->hRootProcess = pi.hProcess; gpSrv->hRootThread = pi.hThread; gpSrv->dwRootProcess = pi.dwProcessId; gpSrv->dwRootThread = pi.dwThreadId; gpSrv->dwRootStartTime = GetTickCount(); } /* ************************* */ int iDbgIdx = 0, iAttachedCount = 0; while (true) { HANDLE hDbgProcess = NULL; DWORD nDbgProcessID = 0; bool bFirstPID = ((iDbgIdx++) == 0); if (bFirstPID) { hDbgProcess = gpSrv->hRootProcess; nDbgProcessID = gpSrv->dwRootProcess; } else { // Взять из pDebugAttachProcesses if (!gpSrv->DbgInfo.pDebugAttachProcesses) break; if (!gpSrv->DbgInfo.pDebugAttachProcesses->pop_back(nDbgProcessID)) break; hDbgProcess = GetProcessHandleForDebug(nDbgProcessID); if (!hDbgProcess) { _ASSERTE(hDbgProcess!=NULL && "Can't open debugging process handle"); continue; } } _ASSERTE(hDbgProcess!=NULL && "Process handle must be opened"); // Битность отладчика должна соответствовать битности приложения! if (IsWindows64()) { int nBits = GetProcessBits(nDbgProcessID, hDbgProcess); if ((nBits == 32 || nBits == 64) && (nBits != WIN3264TEST(32,64))) { if (gpSrv->DbgInfo.pszDebuggingCmdLine != NULL) { _printf("Bitness of ConEmuC and debugging program does not match\n"); if (bFirstPID) return CERR_CANTSTARTDEBUGGER; else continue; } wchar_t szExe[MAX_PATH+16]; wchar_t szCmdLine[MAX_PATH*2]; if (GetModuleFileName(NULL, szExe, countof(szExe)-16)) { wchar_t* pszName = (wchar_t*)PointToName(szExe); _wcscpy_c(pszName, 16, (nBits == 32) ? L"ConEmuC.exe" : L"ConEmuC64.exe"); _wsprintf(szCmdLine, SKIPLEN(countof(szCmdLine)) L"\"%s\" /DEBUGPID=%u %s", szExe, nDbgProcessID, (gpSrv->DbgInfo.nDebugDumpProcess == 1) ? L"/DUMP" : (gpSrv->DbgInfo.nDebugDumpProcess == 2) ? L"/MINIDUMP" : (gpSrv->DbgInfo.nDebugDumpProcess == 3) ? L"/FULLDUMP" : L""); STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi = {}; if (CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { // Ждать НЕ будем, сразу на выход //HANDLE hEvents[2] = {pi.hProcess, ghExitQueryEvent}; //nWait = WaitForMultipleObjects(countof(hEvents), hEvents, FALSE, INFINITE); //if (nWait == WAIT_OBJECT_0) //{ // //GetExitCodeProcess(pi.hProcess, &nExternalExitCode); // nExternalExitCode = 0; //} //CloseHandle(pi.hProcess); //CloseHandle(pi.hThread); //if (nExternalExitCode == 0) //{ // goto done; //} // Может там еще процессы в списке на дамп? continue; } else { DWORD dwErr = GetLastError(); _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't start external debugger '%s'. ErrCode=0x%08X\n", szCmdLine, dwErr); _wprintf(szInfo); if (bFirstPID) return CERR_CANTSTARTDEBUGGER; else continue; } } wchar_t szProc[64]; szProc[0] = 0; PROCESSENTRY32 pi = {sizeof(pi)}; if (GetProcessInfo(nDbgProcessID, &pi)) _wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc)); _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Bits are incompatible. Can't debug '%s' PID=%i\n", szProc[0] ? szProc : L"not found", nDbgProcessID); _wprintf(szInfo); if (bFirstPID) return CERR_CANTSTARTDEBUGGER; else continue; } } if (gpSrv->DbgInfo.pszDebuggingCmdLine == NULL) { if (!DebugActiveProcess(nDbgProcessID)) { DWORD dwErr = GetLastError(); wchar_t szProc[64]; szProc[0] = 0; PROCESSENTRY32 pi = {sizeof(pi)}; if (GetProcessInfo(nDbgProcessID, &pi)) _wcscpyn_c(szProc, countof(szProc), pi.szExeFile, countof(szProc)); _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Can't attach debugger to '%s' PID=%i. ErrCode=0x%08X\n", szProc[0] ? szProc : L"not found", nDbgProcessID, dwErr); _wprintf(szInfo); return CERR_CANTSTARTDEBUGGER; } } iAttachedCount++; } if (iAttachedCount == 0) { return CERR_CANTSTARTDEBUGGER; } /* **************** */ // Дополнительная инициализация, чтобы закрытие дебагера (наш процесс) не привело // к закрытию "отлаживаемой" программы pfnDebugActiveProcessStop = (FDebugActiveProcessStop)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugActiveProcessStop"); pfnDebugSetProcessKillOnExit = (FDebugSetProcessKillOnExit)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"DebugSetProcessKillOnExit"); if (pfnDebugSetProcessKillOnExit) pfnDebugSetProcessKillOnExit(FALSE/*KillOnExit*/); gpSrv->DbgInfo.bDebuggerActive = TRUE; PrintDebugInfo(); SetEvent(gpSrv->DbgInfo.hDebugReady); while (nWait == WAIT_TIMEOUT) { ProcessDebugEvent(); if (ghExitQueryEvent) nWait = WaitForSingleObject(ghExitQueryEvent, 0); } //done: gbRootAliveLess10sec = FALSE; gbInShutdown = TRUE; gbAlwaysConfirmExit = FALSE; _ASSERTE(gbTerminateOnCtrlBreak==FALSE); if (!nExitQueryPlace) nExitQueryPlace = 12+(nExitPlaceStep); SetTerminateEvent(ste_DebugThread); return 0; }
wchar_t* RConStartArgs::CreateCommandLine(bool abForTasks /*= false*/) const { wchar_t* pszFull = NULL; size_t cchMaxLen = (pszSpecialCmd ? (lstrlen(pszSpecialCmd) + 3) : 0); // только команда cchMaxLen += (pszStartupDir ? (lstrlen(pszStartupDir) + 20) : 0); // "-new_console:d:..." cchMaxLen += (pszIconFile ? (lstrlen(pszIconFile) + 20) : 0); // "-new_console:C:..." cchMaxLen += (pszWallpaper ? (lstrlen(pszWallpaper) + 20) : 0); // "-new_console:W:..." // Some values may contain 'invalid' symbols (like '<', '>' and so on). They will be escaped. Thats why "len*2". cchMaxLen += (pszRenameTab ? (lstrlen(pszRenameTab)*2 + 20) : 0); // "-new_console:t:..." cchMaxLen += (pszPalette ? (lstrlen(pszPalette)*2 + 20) : 0); // "-new_console:P:..." cchMaxLen += 15; if (RunAsAdministrator == crb_On) cchMaxLen++; // -new_console:a if (RunAsRestricted == crb_On) cchMaxLen++; // -new_console:r cchMaxLen += (pszUserName ? (lstrlen(pszUserName) + 32 // "-new_console:u:<user>:<pwd>" + (pszDomain ? lstrlen(pszDomain) : 0) + (szUserPassword ? lstrlen(szUserPassword) : 0)) : 0); if (ForceUserDialog == crb_On) cchMaxLen++; // -new_console:u if (BackgroundTab == crb_On) cchMaxLen++; // -new_console:b if (ForegroungTab == crb_On) cchMaxLen++; // -new_console:f if (BufHeight == crb_On) cchMaxLen += 32; // -new_console:h<lines> if (LongOutputDisable == crb_On) cchMaxLen++; // -new_console:o if (OverwriteMode == crb_On) cchMaxLen++; // -new_console:w cchMaxLen += (nPTY ? 15 : 0); // -new_console:e if (InjectsDisable == crb_On) cchMaxLen++; // -new_console:i if (ForceNewWindow == crb_On) cchMaxLen++; // -new_console:N if (eConfirmation) cchMaxLen++; // -new_console:c / -new_console:n if (ForceDosBox == crb_On) cchMaxLen++; // -new_console:x if (ForceInherit == crb_On) cchMaxLen++; // -new_console:I if (eSplit) cchMaxLen += 64; // -new_console:s[<SplitTab>T][<Percents>](H|V) pszFull = (wchar_t*)malloc(cchMaxLen*sizeof(*pszFull)); if (!pszFull) { _ASSERTE(pszFull!=NULL); return NULL; } if (pszSpecialCmd) { if ((RunAsAdministrator == crb_On) && abForTasks) _wcscpy_c(pszFull, cchMaxLen, L"*"); else *pszFull = 0; // Не окавычиваем. Этим должен озаботиться пользователь _wcscat_c(pszFull, cchMaxLen, pszSpecialCmd); //131008 - лишние пробелы не нужны wchar_t* pS = pszFull + lstrlen(pszFull); while ((pS > pszFull) && wcschr(L" \t\r\n", *(pS - 1))) *(--pS) = 0; //_wcscat_c(pszFull, cchMaxLen, L" "); } else { *pszFull = 0; } wchar_t szAdd[128] = L""; if (RunAsAdministrator == crb_On) wcscat_c(szAdd, L"a"); else if (RunAsRestricted == crb_On) wcscat_c(szAdd, L"r"); if ((ForceUserDialog == crb_On) && !(pszUserName && *pszUserName)) wcscat_c(szAdd, L"u"); if (BackgroundTab == crb_On) wcscat_c(szAdd, L"b"); else if (ForegroungTab == crb_On) wcscat_c(szAdd, L"f"); if (ForceDosBox == crb_On) wcscat_c(szAdd, L"x"); if (ForceInherit == crb_On) wcscat_c(szAdd, L"I"); if (eConfirmation == eConfAlways) wcscat_c(szAdd, L"c"); else if (eConfirmation == eConfNever) wcscat_c(szAdd, L"n"); if (LongOutputDisable == crb_On) wcscat_c(szAdd, L"o"); if (OverwriteMode == crb_On) wcscat_c(szAdd, L"w"); if (nPTY) wcscat_c(szAdd, (nPTY == 1) ? L"p1" : (nPTY == 2) ? L"p2" : L"p0"); if (InjectsDisable == crb_On) wcscat_c(szAdd, L"i"); if (ForceNewWindow == crb_On) wcscat_c(szAdd, L"N"); if (BufHeight == crb_On) { if (nBufHeight) msprintf(szAdd+lstrlen(szAdd), 16, L"h%u", nBufHeight); else wcscat_c(szAdd, L"h"); } // -new_console:s[<SplitTab>T][<Percents>](H|V) if (eSplit) { wcscat_c(szAdd, L"s"); if (nSplitPane) msprintf(szAdd+lstrlen(szAdd), 16, L"%uT", nSplitPane); if (nSplitValue > 0 && nSplitValue < 1000) { UINT iPercent = (1000-nSplitValue)/10; msprintf(szAdd+lstrlen(szAdd), 16, L"%u", max(1,min(iPercent,99))); } wcscat_c(szAdd, (eSplit == eSplitHorz) ? L"H" : L"V"); } if (szAdd[0]) { _wcscat_c(pszFull, cchMaxLen, (NewConsole == crb_On) ? L" -new_console:" : L" -cur_console:"); _wcscat_c(pszFull, cchMaxLen, szAdd); } struct CopyValues { wchar_t cOpt; bool bEscape; LPCWSTR pVal; } values[] = { {L'd', false, this->pszStartupDir}, {L't', true, this->pszRenameTab}, {L'C', false, this->pszIconFile}, {L'P', true, this->pszPalette}, {L'W', false, this->pszWallpaper}, {0} }; wchar_t szCat[32]; for (CopyValues* p = values; p->cOpt; p++) { if (p->pVal && *p->pVal) { bool bQuot = wcspbrk(p->pVal, L" \"") != NULL; if (bQuot) msprintf(szCat, countof(szCat), (NewConsole == crb_On) ? L" \"-new_console:%c:" : L" \"-cur_console:%c:", p->cOpt); else msprintf(szCat, countof(szCat), (NewConsole == crb_On) ? L" -new_console:%c:" : L" -cur_console:%c:", p->cOpt); _wcscat_c(pszFull, cchMaxLen, szCat); if (p->bEscape) { wchar_t* pD = pszFull + lstrlen(pszFull); const wchar_t* pS = p->pVal; while (*pS) { if (wcschr(L"<>()&|^\"", *pS)) *(pD++) = (*pS == L'"') ? L'"' : L'^'; *(pD++) = *(pS++); } _ASSERTE(pD < (pszFull+cchMaxLen)); *pD = 0; } else { _wcscat_c(pszFull, cchMaxLen, p->pVal); } if (bQuot) _wcscat_c(pszFull, cchMaxLen, L"\""); } } // "-new_console:u:<user>:<pwd>" if (pszUserName && *pszUserName) { _wcscat_c(pszFull, cchMaxLen, (NewConsole == crb_On) ? L" \"-new_console:u:" : L" \"-cur_console:u:"); if (pszDomain && *pszDomain) { _wcscat_c(pszFull, cchMaxLen, pszDomain); _wcscat_c(pszFull, cchMaxLen, L"\\"); } _wcscat_c(pszFull, cchMaxLen, pszUserName); if (*szUserPassword || (ForceUserDialog != crb_On)) { _wcscat_c(pszFull, cchMaxLen, L":"); } if (*szUserPassword) { _wcscat_c(pszFull, cchMaxLen, szUserPassword); } _wcscat_c(pszFull, cchMaxLen, L"\""); } return pszFull; }
bool FindImageSubsystem(const wchar_t *Module, /*wchar_t* pstrDest,*/ DWORD& ImageSubsystem, DWORD& ImageBits, DWORD& FileAttrs) { if (!Module || !*Module) return false; bool Result = false; //ImageSubsystem = IMAGE_SUBSYSTEM_UNKNOWN; // Исключения нас не интересуют - команда уже сформирована и отдана в CreateProcess! //// нулевой проход - смотрим исключения //// Берем "исключения" из реестра, которые должны исполняться директом, //// например, некоторые внутренние команды ком. процессора. //string strExcludeCmds; //GetRegKey(strSystemExecutor,L"ExcludeCmds",strExcludeCmds,L""); //UserDefinedList ExcludeCmdsList; //ExcludeCmdsList.Set(strExcludeCmds); //while (!ExcludeCmdsList.IsEmpty()) //{ // if (!StrCmpI(Module,ExcludeCmdsList.GetNext())) // { // ImageSubsystem=IMAGE_SUBSYSTEM_WINDOWS_CUI; // Result=true; // break; // } //} //string strFullName=Module; LPCWSTR ModuleExt = PointToExt(Module); wchar_t *strPathExt/*[32767]*/ = NULL; //(L".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WSH"); wchar_t *strPathEnv/*[32767]*/ = NULL; wchar_t *strExpand/*[32767]*/ = NULL; wchar_t *strTmpName/*[32767]*/ = NULL; wchar_t *pszFilePart = NULL; DWORD nPathExtLen = 0; LPCWSTR pszPathExtEnd = NULL; LPWSTR Ext = NULL; typedef LONG (WINAPI *RegOpenKeyExW_t)(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); RegOpenKeyExW_t _RegOpenKeyEx = NULL; typedef LONG (WINAPI *RegQueryValueExW_t)(HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); RegQueryValueExW_t _RegQueryValueEx = NULL; typedef LONG (WINAPI *RegCloseKey_t)(HKEY hKey); RegCloseKey_t _RegCloseKey = NULL; HMODULE hAdvApi = NULL; int cchstrPathExt = 32767; strPathExt = (wchar_t*)malloc(cchstrPathExt*sizeof(wchar_t)); *strPathExt = 0; int cchstrPathEnv = 32767; strPathEnv = (wchar_t*)malloc(cchstrPathEnv*sizeof(wchar_t)); *strPathEnv = 0; int cchstrExpand = 32767; strExpand = (wchar_t*)malloc(cchstrExpand*sizeof(wchar_t)); *strExpand = 0; int cchstrTmpName = 32767; strTmpName = (wchar_t*)malloc(cchstrTmpName*sizeof(wchar_t)); *strTmpName = 0; nPathExtLen = GetEnvironmentVariable(L"PATHEXT", strPathExt, cchstrPathExt-2); if (!nPathExtLen) { _wcscpy_c(strPathExt, cchstrPathExt, L".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WSH"); nPathExtLen = lstrlen(strPathExt); } pszPathExtEnd = strPathExt+nPathExtLen; // Разбить на токены strPathExt[nPathExtLen] = strPathExt[nPathExtLen+1] = 0; Ext = wcschr(strPathExt, L';'); while (Ext) { *Ext = 0; Ext = wcschr(Ext+1, L';'); } TODO("Проверить на превышение длин строк"); // первый проход - в текущем каталоге LPWSTR pszExtCur = strPathExt; while (pszExtCur < pszPathExtEnd) { Ext = pszExtCur; pszExtCur = pszExtCur + lstrlen(pszExtCur)+1; _wcscpyn_c(strTmpName, cchstrTmpName, Module, cchstrTmpName); //-V501 if (!ModuleExt) { if (!*Ext) continue; _wcscatn_c(strTmpName, cchstrTmpName, Ext, cchstrTmpName); } if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits/*16/32/64*/, FileAttrs)) { Result = true; goto wrap; } if (ModuleExt) { break; } } // второй проход - по правилам SearchPath // поиск по переменной PATH if (GetEnvironmentVariable(L"PATH", strPathEnv, cchstrPathEnv)) { LPWSTR pszPathEnvEnd = strPathEnv + lstrlen(strPathEnv); LPWSTR pszPathCur = strPathEnv; while (pszPathCur && (pszPathCur < pszPathEnvEnd)) { LPWSTR Path = pszPathCur; LPWSTR pszPathNext = wcschr(pszPathCur, L';'); if (pszPathNext) { *pszPathNext = 0; pszPathCur = pszPathNext+1; } else { pszPathCur = pszPathEnvEnd; } if (!*Path) continue; pszExtCur = strPathExt; while (pszExtCur < pszPathExtEnd) { Ext = pszExtCur; pszExtCur = pszExtCur + lstrlen(pszExtCur)+1; if (!*Ext) continue; if (SearchPath(Path, Module, Ext, cchstrTmpName, strTmpName, &pszFilePart)) { if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits, FileAttrs)) { Result = true; goto wrap; } } } } } pszExtCur = strPathExt; while (pszExtCur < pszPathExtEnd) { Ext = pszExtCur; pszExtCur = pszExtCur + lstrlen(pszExtCur)+1; if (!*Ext) continue; if (SearchPath(NULL, Module, Ext, cchstrTmpName, strTmpName, &pszFilePart)) { if (GetImageSubsystem(strTmpName, ImageSubsystem, ImageBits, FileAttrs)) { Result = true; goto wrap; } } } // третий проход - лезем в реестр в "App Paths" if (!wcschr(Module, L'\\')) { hAdvApi = LoadLibrary(L"AdvApi32.dll"); if (!hAdvApi) goto wrap; _RegOpenKeyEx = (RegOpenKeyExW_t)GetProcAddress(hAdvApi, "RegOpenKeyExW"); _RegQueryValueEx = (RegQueryValueExW_t)GetProcAddress(hAdvApi, "RegQueryValueExW"); _RegCloseKey = (RegCloseKey_t)GetProcAddress(hAdvApi, "RegCloseKey"); if (!_RegOpenKeyEx || !_RegQueryValueEx || !_RegCloseKey) goto wrap; LPCWSTR RegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\"; // В строке Module заменить исполняемый модуль на полный путь, который // берется из SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths // Сначала смотрим в HKCU, затем - в HKLM HKEY RootFindKey[] = {HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_LOCAL_MACHINE}; BOOL lbAddExt = FALSE; pszExtCur = strPathExt; while (pszExtCur < pszPathExtEnd) { if (!lbAddExt) { Ext = NULL; lbAddExt = TRUE; } else { Ext = pszExtCur; pszExtCur = pszExtCur + lstrlen(pszExtCur)+1; if (!*Ext) continue; } _wcscpy_c(strTmpName, cchstrTmpName, RegPath); _wcscatn_c(strTmpName, cchstrTmpName, Module, cchstrTmpName); if (Ext) _wcscatn_c(strTmpName, cchstrTmpName, Ext, cchstrTmpName); DWORD samDesired = KEY_QUERY_VALUE; DWORD RedirectionFlag = 0; // App Paths key is shared in Windows 7 and above OSVERSIONINFO osv = {sizeof(OSVERSIONINFO)}; GetVersionEx(&osv); if (osv.dwMajorVersion < 6 || (osv.dwMajorVersion == 6 && osv.dwMinorVersion < 1)) { #ifdef _WIN64 RedirectionFlag = KEY_WOW64_32KEY; #else RedirectionFlag = IsWindows64() ? KEY_WOW64_64KEY : 0; #endif } for (size_t i = 0; i < countof(RootFindKey); i++) { if (i == (countof(RootFindKey)-1)) { if (RedirectionFlag) samDesired |= RedirectionFlag; else break; } HKEY hKey; if (_RegOpenKeyEx(RootFindKey[i], strTmpName, 0, samDesired, &hKey) == ERROR_SUCCESS) { DWORD nType = 0, nSize = sizeof(strTmpName)-2; int RegResult = _RegQueryValueEx(hKey, L"", NULL, &nType, (LPBYTE)strTmpName, &nSize); _RegCloseKey(hKey); if ((RegResult == ERROR_SUCCESS) && (nType == REG_SZ || nType == REG_EXPAND_SZ || nType == REG_MULTI_SZ)) { strTmpName[(nSize >> 1)+1] = 0; if (!ExpandEnvironmentStrings(strTmpName, strExpand, cchstrExpand)) _wcscpy_c(strExpand, cchstrExpand, strTmpName); if (GetImageSubsystem(Unquote(strExpand), ImageSubsystem, ImageBits, FileAttrs)) { Result = true; goto wrap; } } } }
INT_PTR CDlgItemHelper::GetString(HWND hParent, WORD nCtrlId, wchar_t** ppszStr, LPCWSTR asNoDefault /*= NULL*/, bool abListBox /*= false*/) { INT_PTR nSel = abListBox ? SendDlgItemMessage(hParent, nCtrlId, CB_GETCURSEL, 0, 0) : -1; INT_PTR nLen = abListBox ? ((nSel >= 0) ? SendDlgItemMessage(hParent, nCtrlId, CB_GETLBTEXTLEN, nSel, 0) : 0) : SendDlgItemMessage(hParent, nCtrlId, WM_GETTEXTLENGTH, 0, 0); if (!ppszStr) return nLen; if (nLen<=0) { SafeFree(*ppszStr); return nLen; } wchar_t* pszNew = (TCHAR*)calloc(nLen+1, sizeof(TCHAR)); if (!pszNew) { _ASSERTE(pszNew!=NULL); } else { if (abListBox) { if (nSel >= 0) SendDlgItemMessage(hParent, nCtrlId, CB_GETLBTEXT, nSel, (LPARAM)pszNew); } else { GetDlgItemText(hParent, nCtrlId, pszNew, nLen+1); } if (*ppszStr) { if (lstrcmp(*ppszStr, pszNew) == 0) { free(pszNew); return nLen; // Изменений не было } } // Значение "по умолчанию" не запоминаем if (asNoDefault && lstrcmp(pszNew, asNoDefault) == 0) { SafeFree(*ppszStr); SafeFree(pszNew); nLen = 0; // Reset (it is default value!) return nLen; } if (nLen > (*ppszStr ? (INT_PTR)_tcslen(*ppszStr) : 0)) { if (*ppszStr) free(*ppszStr); *ppszStr = pszNew; pszNew = NULL; } else if (*ppszStr) { _wcscpy_c(*ppszStr, nLen+1, pszNew); } SafeFree(pszNew); } return nLen; }
wchar_t* RConStartArgs::CreateCommandLine(bool abForTasks /*= false*/) { wchar_t* pszFull = NULL; size_t cchMaxLen = (pszSpecialCmd ? (lstrlen(pszSpecialCmd) + 3) : 0); // только команда cchMaxLen += (pszStartupDir ? (lstrlen(pszStartupDir) + 20) : 0); // "-new_console:d:..." cchMaxLen += (pszRenameTab ? (lstrlen(pszRenameTab) + 20) : 0); // "-new_console:t:..." cchMaxLen += (bRunAsAdministrator ? 15 : 0); // -new_console:a cchMaxLen += (bRunAsRestricted ? 15 : 0); // -new_console:r cchMaxLen += (pszUserName ? (lstrlen(pszUserName) + 32 // "-new_console:u:<user>:<pwd>" + (pszDomain ? lstrlen(pszDomain) : 0) + (szUserPassword ? lstrlen(szUserPassword) : 0)) : 0); cchMaxLen += (bForceUserDialog ? 15 : 0); // -new_console:u cchMaxLen += (bBackgroundTab ? 15 : 0); // -new_console:b cchMaxLen += (bBufHeight ? 32 : 0); // -new_console:h<lines> cchMaxLen += (bLongOutputDisable ? 15 : 0); // -new_console:o cchMaxLen += (bOverwriteMode ? 15 : 0); // -new_console:w cchMaxLen += (nPTY ? 15 : 0); // -new_console:e cchMaxLen += (bInjectsDisable ? 15 : 0); // -new_console:i cchMaxLen += (eConfirmation ? 15 : 0); // -new_console:c / -new_console:n cchMaxLen += (bForceDosBox ? 15 : 0); // -new_console:x cchMaxLen += (eSplit ? 64 : 0); // -new_console:s[<SplitTab>T][<Percents>](H|V) pszFull = (wchar_t*)malloc(cchMaxLen*sizeof(*pszFull)); if (!pszFull) { _ASSERTE(pszFull!=NULL); return NULL; } if (pszSpecialCmd) { if (bRunAsAdministrator && abForTasks) _wcscpy_c(pszFull, cchMaxLen, L"*"); else *pszFull = 0; // Не окавычиваем. Этим должен озаботиться пользователь _wcscat_c(pszFull, cchMaxLen, pszSpecialCmd); _wcscat_c(pszFull, cchMaxLen, L" "); } else { *pszFull = 0; } wchar_t szAdd[128] = L""; if (bRunAsAdministrator) wcscat_c(szAdd, L"a"); else if (bRunAsRestricted) wcscat_c(szAdd, L"r"); if (bForceUserDialog) wcscat_c(szAdd, L"u"); if (bBackgroundTab) wcscat_c(szAdd, L"b"); if (bForceDosBox) wcscat_c(szAdd, L"x"); if (eConfirmation == eConfAlways) wcscat_c(szAdd, L"c"); else if (eConfirmation == eConfNever) wcscat_c(szAdd, L"n"); if (bLongOutputDisable) wcscat_c(szAdd, L"o"); if (bOverwriteMode) wcscat_c(szAdd, L"w"); if (nPTY) wcscat_c(szAdd, (nPTY == 1) ? L"p1" : (nPTY == 2) ? L"p2" : L"p0"); if (bInjectsDisable) wcscat_c(szAdd, L"i"); if (bBufHeight) { if (nBufHeight) _wsprintf(szAdd+lstrlen(szAdd), SKIPLEN(16) L"h%u", nBufHeight); else wcscat_c(szAdd, L"h"); } // -new_console:s[<SplitTab>T][<Percents>](H|V) if (eSplit) { wcscat_c(szAdd, L"s"); if (nSplitPane) _wsprintf(szAdd+lstrlen(szAdd), SKIPLEN(16) L"%uT", nSplitPane); if ((int)(nSplitValue/10) != 0) _wsprintf(szAdd+lstrlen(szAdd), SKIPLEN(16) L"%u", (UINT)(nSplitValue/10)); wcscat_c(szAdd, (eSplit == eSplitHorz) ? L"H" : L"V"); } if (szAdd[0]) { _wcscat_c(pszFull, cchMaxLen, bNewConsole ? L" -new_console:" : L" -cur_console:"); _wcscat_c(pszFull, cchMaxLen, szAdd); } // "-new_console:d:..." if (pszStartupDir && *pszStartupDir) { bool bQuot = wcschr(pszStartupDir, L' ') != NULL; if (bQuot) _wcscat_c(pszFull, cchMaxLen, bNewConsole ? L" \"-new_console:d:" : L" \"-cur_console:d:"); else _wcscat_c(pszFull, cchMaxLen, bNewConsole ? L" -new_console:d:" : L" -cur_console:d:"); _wcscat_c(pszFull, cchMaxLen, pszStartupDir); if (bQuot) _wcscat_c(pszFull, cchMaxLen, L"\""); } // "-new_console:t:..." if (pszRenameTab && *pszRenameTab) { bool bQuot = wcschr(pszRenameTab, L' ') != NULL; if (bQuot) _wcscat_c(pszFull, cchMaxLen, bNewConsole ? L" \"-new_console:t:" : L" \"-cur_console:t:"); else _wcscat_c(pszFull, cchMaxLen, bNewConsole ? L" -new_console:t:" : L" -cur_console:t:"); _wcscat_c(pszFull, cchMaxLen, pszRenameTab); if (bQuot) _wcscat_c(pszFull, cchMaxLen, L"\""); } // "-new_console:u:<user>:<pwd>" if (pszUserName && *pszUserName) { _wcscat_c(pszFull, cchMaxLen, bNewConsole ? L" \"-new_console:u:" : L" \"-cur_console:u:"); if (pszDomain && *pszDomain) { _wcscat_c(pszFull, cchMaxLen, pszDomain); _wcscat_c(pszFull, cchMaxLen, L"\\"); } _wcscat_c(pszFull, cchMaxLen, pszUserName); if (szUserPassword) { _wcscat_c(pszFull, cchMaxLen, L":"); _wcscat_c(pszFull, cchMaxLen, szUserPassword); } _wcscat_c(pszFull, cchMaxLen, L"\""); } return pszFull; }
// cmd.exe only! LONG WINAPI OnRegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) { //typedef LONG (WINAPI* OnRegQueryValueExW_t)(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); ORIGINAL_EX(RegQueryValueExW); LONG lRc = -1; if (gbIsCmdProcess && hKey && lpValueName) { // Allow `CD` to network paths if (lstrcmpi(lpValueName, L"DisableUNCCheck") == 0) { if (lpData) { if (lpcbData && *lpcbData >= sizeof(DWORD)) *((LPDWORD)lpData) = gbAllowUncPaths; else *lpData = gbAllowUncPaths; } if (lpType) *lpType = REG_DWORD; if (lpcbData) *lpcbData = sizeof(DWORD); lRc = 0; goto wrap; } if (gbIsCmdProcess && hKey && lpValueName && (lstrcmpi(lpValueName, L"AutoRun") == 0) && InitializeClink()) { if (gbAllowClinkUsage && gszClinkCmdLine && IsInteractive()) { // Is already loaded? if (!IsClinkLoaded() && !gbClinkInjectRequested) { // Do this once, to avoid multiple initializations gbClinkInjectRequested = true; // May be it is set up itself? typedef LONG (WINAPI* RegOpenKeyEx_t)(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); typedef LONG (WINAPI* RegCloseKey_t)(HKEY hKey); HMODULE hAdvApi = LoadLibrary(L"AdvApi32.dll"); if (hAdvApi) { RegOpenKeyEx_t _RegOpenKeyEx = (RegOpenKeyEx_t)GetProcAddress(hAdvApi, "RegOpenKeyExW"); RegCloseKey_t _RegCloseKey = (RegCloseKey_t)GetProcAddress(hAdvApi, "RegCloseKey"); if (_RegOpenKeyEx && _RegCloseKey) { const DWORD cchMax = 0x3FF0; const DWORD cbMax = cchMax*2; wchar_t* pszCmd = (wchar_t*)malloc(cbMax); if (pszCmd) { DWORD cbSize; bool bClinkInstalled = false; for (int i = 0; i <= 1 && !bClinkInstalled; i++) { HKEY hk; if (_RegOpenKeyEx(i?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER, L"Software\\Microsoft\\Command Processor", 0, KEY_READ, &hk)) continue; if (!F(RegQueryValueExW)(hk, lpValueName, NULL, NULL, (LPBYTE)pszCmd, &(cbSize = cbMax)) && (cbSize+2) < cbMax) { cbSize /= 2; pszCmd[cbSize] = 0; CharLowerBuffW(pszCmd, cbSize); if (wcsstr(pszCmd, L"\\clink.bat")) bClinkInstalled = true; } _RegCloseKey(hk); } // Not installed via "Autorun" if (!bClinkInstalled) { int iLen = lstrlen(gszClinkCmdLine); _wcscpy_c(pszCmd, cchMax, gszClinkCmdLine); _wcscpy_c(pszCmd+iLen, cchMax-iLen, L" & "); // conveyer next command indifferent to %errorlevel% cbSize = cbMax - (iLen + 3)*sizeof(*pszCmd); if (F(RegQueryValueExW)(hKey, lpValueName, NULL, NULL, (LPBYTE)(pszCmd + iLen + 3), &cbSize) || (pszCmd[iLen+3] == 0)) { pszCmd[iLen] = 0; // There is no self value in registry } cbSize = (lstrlen(pszCmd)+1)*sizeof(*pszCmd); // Return lRc = 0; if (lpData && lpcbData) { if (*lpcbData < cbSize) lRc = ERROR_MORE_DATA; else _wcscpy_c((wchar_t*)lpData, (*lpcbData)/2, pszCmd); } if (lpcbData) *lpcbData = cbSize; free(pszCmd); FreeLibrary(hAdvApi); goto wrap; } free(pszCmd); } } FreeLibrary(hAdvApi); } } } } } if (F(RegQueryValueExW)) lRc = F(RegQueryValueExW)(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); wrap: return lRc; }
void CSetPgDebug::debugLogInfo(CESERVER_REQ_PEEKREADINFO* pInfo) { CSetPgDebug* pDbgPg = (CSetPgDebug*)gpSetCls->GetPageObj(thi_Debug); if (!pDbgPg) goto wrap; if (pDbgPg->GetActivityLoggingType() != glt_Input) goto wrap; for (UINT nIdx = 0; nIdx < pInfo->nCount; nIdx++) { const INPUT_RECORD *pr = pInfo->Buffer+nIdx; SYSTEMTIME st; GetLocalTime(&st); wchar_t szTime[255]; _wsprintf(szTime, SKIPLEN(countof(szTime)) L"%02i:%02i:%02i.%03i", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); HWND hList = GetDlgItem(pDbgPg->Dlg(), lbActivityLog); LVITEM lvi = {LVIF_TEXT|LVIF_STATE}; lvi.state = lvi.stateMask = LVIS_SELECTED|LVIS_FOCUSED; lvi.pszText = szTime; static INPUT_RECORD LastLogEvent1; static char LastLogEventType1; static UINT LastLogEventDup1; static INPUT_RECORD LastLogEvent2; static char LastLogEventType2; static UINT LastLogEventDup2; if (LastLogEventType1 == pInfo->cPeekRead && memcmp(&LastLogEvent1, pr, sizeof(LastLogEvent1)) == 0) { LastLogEventDup1 ++; _wsprintf(szTime, SKIPLEN(countof(szTime)) L"%u", LastLogEventDup1); ListView_SetItemText(hList, 0, lic_Dup, szTime); // верхний //free(pr); continue; // дубли - не показывать? только если прошло время? } if (LastLogEventType2 == pInfo->cPeekRead && memcmp(&LastLogEvent2, pr, sizeof(LastLogEvent2)) == 0) { LastLogEventDup2 ++; _wsprintf(szTime, SKIPLEN(countof(szTime)) L"%u", LastLogEventDup2); ListView_SetItemText(hList, 1, lic_Dup, szTime); // верхний //free(pr); continue; // дубли - не показывать? только если прошло время? } int nItem = ListView_InsertItem(hList, &lvi); if (LastLogEventType1 && LastLogEventType1 != pInfo->cPeekRead) { LastLogEvent2 = LastLogEvent1; LastLogEventType2 = LastLogEventType1; LastLogEventDup2 = LastLogEventDup1; } LastLogEventType1 = pInfo->cPeekRead; memmove(&LastLogEvent1, pr, sizeof(LastLogEvent1)); LastLogEventDup1 = 1; _wcscpy_c(szTime, countof(szTime), L"1"); ListView_SetItemText(hList, nItem, lic_Dup, szTime); // szTime[0] = (wchar_t)pInfo->cPeekRead; szTime[1] = L'.'; szTime[2] = 0; if (pr->EventType == MOUSE_EVENT) { wcscat_c(szTime, L"Mouse"); ListView_SetItemText(hList, nItem, lic_Type, szTime); const MOUSE_EVENT_RECORD *rec = &pr->Event.MouseEvent; _wsprintf(szTime, SKIPLEN(countof(szTime)) L"[%d,%d], Btn=0x%08X (%c%c%c%c%c), Ctrl=0x%08X (%c%c%c%c%c - %c%c%c%c), Flgs=0x%08X (%s)", rec->dwMousePosition.X, rec->dwMousePosition.Y, rec->dwButtonState, (rec->dwButtonState&FROM_LEFT_1ST_BUTTON_PRESSED?L'L':L'l'), (rec->dwButtonState&RIGHTMOST_BUTTON_PRESSED?L'R':L'r'), (rec->dwButtonState&FROM_LEFT_2ND_BUTTON_PRESSED?L'2':L' '), (rec->dwButtonState&FROM_LEFT_3RD_BUTTON_PRESSED?L'3':L' '), (rec->dwButtonState&FROM_LEFT_4TH_BUTTON_PRESSED?L'4':L' '), rec->dwControlKeyState, (rec->dwControlKeyState&LEFT_CTRL_PRESSED?L'C':L'c'), (rec->dwControlKeyState&LEFT_ALT_PRESSED?L'A':L'a'), (rec->dwControlKeyState&SHIFT_PRESSED?L'S':L's'), (rec->dwControlKeyState&RIGHT_ALT_PRESSED?L'A':L'a'), (rec->dwControlKeyState&RIGHT_CTRL_PRESSED?L'C':L'c'), (rec->dwControlKeyState&ENHANCED_KEY?L'E':L'e'), (rec->dwControlKeyState&CAPSLOCK_ON?L'C':L'c'), (rec->dwControlKeyState&NUMLOCK_ON?L'N':L'n'), (rec->dwControlKeyState&SCROLLLOCK_ON?L'S':L's'), rec->dwEventFlags, (rec->dwEventFlags==0?L"(Click)": (rec->dwEventFlags==DOUBLE_CLICK?L"(DblClick)": (rec->dwEventFlags==MOUSE_MOVED?L"(Moved)": (rec->dwEventFlags==MOUSE_WHEELED?L"(Wheel)": (rec->dwEventFlags==0x0008/*MOUSE_HWHEELED*/?L"(HWheel)":L""))))) ); if (rec->dwEventFlags==MOUSE_WHEELED || rec->dwEventFlags==0x0008/*MOUSE_HWHEELED*/) { int nLen = _tcslen(szTime); _wsprintf(szTime+nLen, SKIPLEN(countof(szTime)-nLen) L" (Delta=%d)",HIWORD(rec->dwButtonState)); } ListView_SetItemText(hList, nItem, lic_Event, szTime); } else if (pr->EventType == KEY_EVENT) { wcscat_c(szTime, L"Key"); ListView_SetItemText(hList, nItem, lic_Type, szTime); _wsprintf(szTime, SKIPLEN(countof(szTime)) L"%c(%i) VK=%i, SC=%i, U=%c(x%04X), ST=x%08X", pr->Event.KeyEvent.bKeyDown ? L'D' : L'U', pr->Event.KeyEvent.wRepeatCount, pr->Event.KeyEvent.wVirtualKeyCode, pr->Event.KeyEvent.wVirtualScanCode, pr->Event.KeyEvent.uChar.UnicodeChar ? pr->Event.KeyEvent.uChar.UnicodeChar : L' ', pr->Event.KeyEvent.uChar.UnicodeChar, pr->Event.KeyEvent.dwControlKeyState); ListView_SetItemText(hList, nItem, lic_Event, szTime); } else if (pr->EventType == FOCUS_EVENT) { wcscat_c(szTime, L"Focus"); ListView_SetItemText(hList, nItem, lic_Type, szTime); _wsprintf(szTime, SKIPLEN(countof(szTime)) L"%u", (DWORD)pr->Event.FocusEvent.bSetFocus); ListView_SetItemText(hList, nItem, lic_Event, szTime); } else if (pr->EventType == WINDOW_BUFFER_SIZE_EVENT) { wcscat_c(szTime, L"Buffer"); ListView_SetItemText(hList, nItem, lic_Type, szTime); _wsprintf(szTime, SKIPLEN(countof(szTime)) L"%ix%i", (int)pr->Event.WindowBufferSizeEvent.dwSize.X, (int)pr->Event.WindowBufferSizeEvent.dwSize.Y); ListView_SetItemText(hList, nItem, lic_Event, szTime); } else if (pr->EventType == MENU_EVENT) { wcscat_c(szTime, L"Menu"); ListView_SetItemText(hList, nItem, lic_Type, szTime); _wsprintf(szTime, SKIPLEN(countof(szTime)) L"%u", (DWORD)pr->Event.MenuEvent.dwCommandId); ListView_SetItemText(hList, nItem, lic_Event, szTime); } else { _wsprintf(szTime+2, SKIPLEN(countof(szTime)-2) L"%u", (DWORD)pr->EventType); ListView_SetItemText(hList, nItem, lic_Type, szTime); } } wrap: free(pInfo); }
static bool InitializeClink() { if (gnCmdInitialized) return true; gnCmdInitialized = 1; // Single //if (!gnAllowClinkUsage) // return false; CESERVER_CONSOLE_MAPPING_HDR* pConMap = GetConMap(); if (!pConMap /*|| !(pConMap->Flags & CECF_UseClink_Any)*/) { //gnAllowClinkUsage = 0; gnCmdInitialized = -1; return false; } // Запомнить режим //gnAllowClinkUsage = // (pConMap->Flags & CECF_UseClink_2) ? 2 : // (pConMap->Flags & CECF_UseClink_1) ? 1 : // CECF_Empty; gbAllowClinkUsage = ((pConMap->Flags & CECF_UseClink_Any) != 0); gbAllowUncPaths = (pConMap->ComSpec.isAllowUncPaths != FALSE); if (gbAllowClinkUsage) { wchar_t szClinkBat[MAX_PATH+32]; wcscpy_c(szClinkBat, pConMap->ComSpec.ConEmuBaseDir); wcscat_c(szClinkBat, L"\\clink\\clink.bat"); if (!FileExists(szClinkBat)) { gbAllowClinkUsage = false; } else { int iLen = lstrlen(szClinkBat) + 16; gszClinkCmdLine = (wchar_t*)malloc(iLen*sizeof(*gszClinkCmdLine)); if (gszClinkCmdLine) { *gszClinkCmdLine = L'"'; _wcscpy_c(gszClinkCmdLine+1, iLen-1, szClinkBat); _wcscat_c(gszClinkCmdLine, iLen, L"\" inject"); } } } return true; //BOOL bRunRc = FALSE; //DWORD nErrCode = 0; //if (gnAllowClinkUsage == 2) //{ // // New style. TODO // wchar_t szClinkDir[MAX_PATH+32], szClinkArgs[MAX_PATH+64]; // wcscpy_c(szClinkDir, pConMap->ComSpec.ConEmuBaseDir); // wcscat_c(szClinkDir, L"\\clink"); // wcscpy_c(szClinkArgs, L"\""); // wcscat_c(szClinkArgs, szClinkDir); // wcscat_c(szClinkArgs, WIN3264TEST(L"\\clink_x86.exe",L"\\clink_x64.exe")); // wcscat_c(szClinkArgs, L"\" inject"); // STARTUPINFO si = {sizeof(si)}; // PROCESS_INFORMATION pi = {}; // bRunRc = CreateProcess(NULL, szClinkArgs, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, szClinkDir, &si, &pi); // // if (bRunRc) // { // WaitForSingleObject(pi.hProcess, INFINITE); // CloseHandle(pi.hProcess); // CloseHandle(pi.hThread); // } // else // { // nErrCode = GetLastError(); // _ASSERTEX(FALSE && "Clink loader failed"); // UNREFERENCED_PARAMETER(nErrCode); // UNREFERENCED_PARAMETER(bRunRc); // } //} //else if (gnAllowClinkUsage == 1) //{ // if (!ghClinkDll) // { // wchar_t szClinkModule[MAX_PATH+30]; // _wsprintf(szClinkModule, SKIPLEN(countof(szClinkModule)) L"%s\\clink\\%s", // pConMap->ComSpec.ConEmuBaseDir, WIN3264TEST(L"clink_dll_x86.dll",L"clink_dll_x64.dll")); // // ghClinkDll = LoadLibrary(szClinkModule); // if (!ghClinkDll) // return false; // } // if (!gpfnClinkReadLine) // { // gpfnClinkReadLine = (call_readline_t)GetProcAddress(ghClinkDll, "call_readline"); // _ASSERTEX(gpfnClinkReadLine!=NULL); // } //} //return (gpfnClinkReadLine != NULL); }
LPCWSTR GetComspecFromEnvVar(wchar_t* pszComspec, DWORD cchMax, ComSpecBits Bits/* = csb_SameOS*/) { if (!pszComspec || (cchMax < MAX_PATH)) { _ASSERTE(pszComspec && (cchMax >= MAX_PATH)); return NULL; } *pszComspec = 0; BOOL bWin64 = IsWindows64(); if (!((Bits == csb_x32) || (Bits == csb_x64))) { if (GetEnvironmentVariable(L"ComSpec", pszComspec, cchMax)) { // Не должен быть (даже случайно) ConEmuC.exe const wchar_t* pszName = PointToName(pszComspec); if (!pszName || !lstrcmpi(pszName, L"ConEmuC.exe") || !lstrcmpi(pszName, L"ConEmuC64.exe") || !FileExists(pszComspec)) // ну и существовать должен { pszComspec[0] = 0; } } } // Если не удалось определить через переменную окружения - пробуем обычный "cmd.exe" из System32 if (pszComspec[0] == 0) { int n = GetWindowsDirectory(pszComspec, cchMax - 20); if (n > 0 && (((DWORD)n) < (cchMax - 20))) { // Добавить \System32\cmd.exe // Warning! 'c:\Windows\SysNative\cmd.exe' не прокатит, т.к. доступен // только для 32битных приложений. А нам нужно в общем виде. // Если из 32битного нужно запустить 64битный cmd.exe - нужно выключать редиректор. if (!bWin64 || (Bits != csb_x32)) { _wcscat_c(pszComspec, cchMax, (pszComspec[n-1] == L'\\') ? L"System32\\cmd.exe" : L"\\System32\\cmd.exe"); } else { _wcscat_c(pszComspec, cchMax, (pszComspec[n-1] == L'\\') ? L"SysWOW64\\cmd.exe" : L"\\SysWOW64\\cmd.exe"); } } } if (pszComspec[0] && !FileExists(pszComspec)) { _ASSERTE("Comspec not found! File not exists!"); pszComspec[0] = 0; } // Last chance if (pszComspec[0] == 0) { _ASSERTE(pszComspec[0] != 0); // Уже должен был быть определен //lstrcpyn(pszComspec, L"cmd.exe", cchMax); wchar_t *psFilePart; DWORD n = SearchPathW(NULL, L"cmd.exe", NULL, cchMax, pszComspec, &psFilePart); if (!n || (n >= cchMax)) _wcscpy_c(pszComspec, cchMax, L"cmd.exe"); } return pszComspec; }
// В 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; }
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; }
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; }
wchar_t* ExpandMacroValues(LPCWSTR pszFormat, LPCWSTR* pszValues, size_t nValCount) { wchar_t* pszCommand = NULL; size_t cchCmdMax = 0; // Замена %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; for (LPCWSTR pSrc = pszFormat; *pSrc; pSrc++) { LPCWSTR pszMacro = NULL; switch (*pSrc) { case L'%': pSrc++; if (*pSrc == L'%') { pszMacro = L"%"; } else if ((*pSrc >= L'1') && (*pSrc <= L'9')) { size_t n = (size_t)(int)(*pSrc - L'1'); if (nValCount > n) { pszMacro = pszValues[n]; } } else { // Недопустимый управляющий символ, это может быть переменная окружения pszMacro = NULL; pSrc--; if (s) *(pDst++) = L'%'; else cchCmdMax++; } if (pszMacro) { size_t cchLen = lstrlenW(pszMacro); if (s) { _wcscpy_c(pDst, cchLen+1, pszMacro); pDst += cchLen; } else { cchCmdMax += cchLen; } } break; // end of '%' default: if (s) *(pDst++) = *pSrc; else cchCmdMax++; } } if (s) *pDst = 0; } wrap: return pszCommand; }
CESERVER_REQ* ExecuteNewCmdOnCreate(CESERVER_CONSOLE_MAPPING_HDR* pSrvMap, HWND hConWnd, enum CmdOnCreateType aCmd, LPCWSTR asAction, LPCWSTR asFile, LPCWSTR asParam, DWORD* anShellFlags, DWORD* anCreateFlags, DWORD* anStartFlags, DWORD* anShowCmd, int mn_ImageBits, int mn_ImageSubsystem, HANDLE hStdIn, HANDLE hStdOut, HANDLE hStdErr) { bool bEnabled = false; if (!pSrvMap) { static bool bWasEnabled = false; static DWORD nLastWasEnabledTick = 0; // Чтобы проверки слишком часто не делать if (!nLastWasEnabledTick || ((GetTickCount() - nLastWasEnabledTick) > 1000)) { CESERVER_CONSOLE_MAPPING_HDR *Info = (CESERVER_CONSOLE_MAPPING_HDR*)calloc(1,sizeof(*Info)); if (Info) { if (::LoadSrvMapping(hConWnd, *Info)) { bEnabled = (Info->nLoggingType == glt_Processes); } free(Info); } nLastWasEnabledTick = GetTickCount(); } bWasEnabled = bEnabled; } else { bEnabled = (pSrvMap->nLoggingType == glt_Processes); } // Если логирование не просили if (!bEnabled) { return NULL; } //szBaseDir[0] = 0; //// Проверим, а надо ли? //MFileMapping<CESERVER_CONSOLE_MAPPING_HDR> ConMap; //ConMap.InitName(CECONMAPNAME, (DWORD)FarHwnd); //CESERVER_CONSOLE_MAPPING_HDR* p = ConMap.Open(); //if (p && p->hConEmuRoot && isWindow(p->hConEmuRoot)) //{ //// bDosBoxAllowed = pInfo->bDosBox; //// wcscpy_c(szBaseDir, pInfo->sConEmuBaseDir); //// wcscat_c(szBaseDir, L"\\"); //if (p->nLoggingType != glt_Processes) // return NULL; //DWORD dwGuiProcessId = 0; //if (!ghConEmuWnd || !GetWindowThreadProcessId(ghConEmuWnd, &dwGuiProcessId)) // return NULL; //MFileMapping<ConEmuGuiMapping> GuiInfoMapping; //GuiInfoMapping.InitName(CEGUIINFOMAPNAME, dwGuiProcessId); //const ConEmuGuiMapping* pInfo = GuiInfoMapping.Open(); //if (!pInfo) // return NULL; //else if (pInfo->nProtocolVersion != CESERVER_REQ_VER) // return NULL; //else //{ // bDosBoxAllowed = pInfo->bDosBox; // wcscpy_c(szBaseDir, pInfo->sConEmuBaseDir); // wcscat_c(szBaseDir, L"\\"); // if (pInfo->nLoggingType != glt_Processes) // return NULL; //} //GuiInfoMapping.CloseMap(); CESERVER_REQ *pIn = NULL; int nActionLen = (asAction ? lstrlen(asAction) : 0)+1; int nFileLen = (asFile ? lstrlen(asFile) : 0)+1; int nParamLen = (asParam ? lstrlen(asParam) : 0)+1; pIn = ExecuteNewCmd(CECMD_ONCREATEPROC, sizeof(CESERVER_REQ_HDR) +sizeof(CESERVER_REQ_ONCREATEPROCESS)+(nActionLen+nFileLen+nParamLen)*sizeof(wchar_t)); pIn->OnCreateProc.nSourceBits = WIN3264TEST(32,64); //-V112 //pIn->OnCreateProc.bUnicode = TRUE; pIn->OnCreateProc.nImageSubsystem = mn_ImageSubsystem; pIn->OnCreateProc.nImageBits = mn_ImageBits; pIn->OnCreateProc.hStdIn = (unsigned __int64)hStdIn; pIn->OnCreateProc.hStdOut = (unsigned __int64)hStdOut; pIn->OnCreateProc.hStdErr = (unsigned __int64)hStdErr; if (aCmd == eShellExecute) wcscpy_c(pIn->OnCreateProc.sFunction, L"Shell"); else if (aCmd == eCreateProcess) wcscpy_c(pIn->OnCreateProc.sFunction, L"Create"); else if (aCmd == eInjectingHooks) wcscpy_c(pIn->OnCreateProc.sFunction, L"Inject"); else if (aCmd == eHooksLoaded) wcscpy_c(pIn->OnCreateProc.sFunction, L"HkLoad"); else if (aCmd == eSrvLoaded) wcscpy_c(pIn->OnCreateProc.sFunction, L"SrLoad"); else if (aCmd == eParmsChanged) wcscpy_c(pIn->OnCreateProc.sFunction, L"Changed"); else if (aCmd == eLoadLibrary) wcscpy_c(pIn->OnCreateProc.sFunction, L"LdLib"); else if (aCmd == eFreeLibrary) wcscpy_c(pIn->OnCreateProc.sFunction, L"FrLib"); else wcscpy_c(pIn->OnCreateProc.sFunction, L"Unknown"); pIn->OnCreateProc.nShellFlags = anShellFlags ? *anShellFlags : 0; pIn->OnCreateProc.nCreateFlags = anCreateFlags ? *anCreateFlags : 0; pIn->OnCreateProc.nStartFlags = anStartFlags ? *anStartFlags : 0; pIn->OnCreateProc.nShowCmd = anShowCmd ? *anShowCmd : 0; pIn->OnCreateProc.nActionLen = nActionLen; pIn->OnCreateProc.nFileLen = nFileLen; pIn->OnCreateProc.nParamLen = nParamLen; wchar_t* psz = pIn->OnCreateProc.wsValue; if (nActionLen > 1) _wcscpy_c(psz, nActionLen, asAction); psz += nActionLen; if (nFileLen > 1) _wcscpy_c(psz, nFileLen, asFile); psz += nFileLen; if (nParamLen > 1) _wcscpy_c(psz, nParamLen, asParam); psz += nParamLen; return pIn; }
size_t CDefTermHk::GetSrvAddArgs(bool bGuiArgs, CmdArg& rsArgs, CmdArg& rsNewCon) { rsArgs.Empty(); rsNewCon.Empty(); if (!this) return 0; size_t cchMax = 64 + ((m_Opt.pszConfigName && *m_Opt.pszConfigName) ? lstrlen(m_Opt.pszConfigName) : 0); wchar_t* psz = rsArgs.GetBuffer(cchMax); size_t cchNew = 32; // "-new_console:ni" wchar_t* pszNew = rsNewCon.GetBuffer(cchNew); if (!psz || !pszNew) return 0; *psz = 0; *pszNew = 0; wchar_t szNewConSw[10] = L""; // Do not inject ConEmuHk in the target process? if (m_Opt.bNoInjects && !bGuiArgs) _wcscat_c(psz, cchMax, L" /NOINJECT"); else if (m_Opt.bNoInjects) wcscat_c(szNewConSw, L"i"); // New or existing window we shall use? if (m_Opt.bNewWindow && !bGuiArgs) _wcscat_c(psz, cchMax, L" /GHWND=NEW"); else if (m_Opt.bNewWindow) _wcscat_c(psz, cchMax, L" /NOSINGLE"); else if (bGuiArgs) _wcscat_c(psz, cchMax, L" /REUSE"); // Confirmations if (m_Opt.nDefaultTerminalConfirmClose == 1) { if (!bGuiArgs) _wcscat_c(psz, cchMax, L" /CONFIRM"); else wcscat_c(szNewConSw, L"c"); } else if (m_Opt.nDefaultTerminalConfirmClose == 2) { if (!bGuiArgs) _wcscat_c(psz, cchMax, L" /NOCONFIRM"); else wcscat_c(szNewConSw, L"n"); } // That switch must be processed in server too! if (m_Opt.pszConfigName && *m_Opt.pszConfigName) { _wcscat_c(psz, cchMax, L" /CONFIG \""); _wcscat_c(psz, cchMax, m_Opt.pszConfigName); _wcscat_c(psz, cchMax, L"\""); } if (*szNewConSw) { _wcscpy_c(pszNew, cchNew, L"-new_console:"); _wcscat_c(pszNew, cchNew, szNewConSw); _wcscat_c(pszNew, cchNew, L" "); } size_t cchLen = wcslen(psz) + wcslen(pszNew); return cchLen; }
// CIR_OK=0 - OK, CIR_AlreadyInjected=1 - Already injected, иначе - ошибка // Здесь вызывается CreateRemoteThread CINFILTRATE_EXIT_CODES InjectRemote(DWORD nRemotePID, bool abDefTermOnly /*= false */) { CINFILTRATE_EXIT_CODES iRc = CIR_GeneralError/*-1*/; bool lbWin64 = WIN3264TEST((IsWindows64()!=0),true); bool is32bit; int nBits; 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]; wchar_t szName[64]; HANDLE hEvent = NULL; HANDLE hDefTermReady = NULL; bool bAlreadyHooked = false; HANDLE hSnap = NULL; MODULEENTRY32 mi = {sizeof(mi)}; HMODULE ptrOuterKernel = NULL; if (!GetModuleFileName(NULL, szSelf, MAX_PATH)) { iRc = CIR_GetModuleFileName/*-200*/; goto wrap; } wcscpy_c(szHooks, szSelf); pszNamePtr = (wchar_t*)PointToName(szHooks); if (!pszNamePtr) { iRc = CIR_GetModuleFileName/*-200*/; goto wrap; } // Hey, may be ConEmuHk.dll is already loaded? hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, nRemotePID); if (!hSnap || (hSnap == INVALID_HANDLE_VALUE)) { iRc = CIR_SnapshotCantBeOpened/*-113*/; goto wrap; } else if (hSnap && Module32First(hSnap, &mi)) { // 130829 - Let load newer(!) ConEmuHk.dll into target process. // 141201 - Also we need to be sure in kernel32.dll address LPCWSTR pszConEmuHk = WIN3264TEST(L"conemuhk.", L"conemuhk64."); size_t nDllNameLen = lstrlen(pszConEmuHk); // Out preferred module name wchar_t szOurName[40] = {}; wchar_t szMinor[8] = L""; lstrcpyn(szMinor, _CRT_WIDE(MVV_4a), countof(szMinor)); _wsprintf(szOurName, SKIPLEN(countof(szOurName)) CEDEFTERMDLLFORMAT /*L"ConEmuHk%s.%02u%02u%02u%s.dll"*/, WIN3264TEST(L"",L"64"), MVV_1, MVV_2, MVV_3, szMinor); CharLowerBuff(szOurName, lstrlen(szOurName)); // Go to enumeration wchar_t szName[64]; do { LPCWSTR pszName = PointToName(mi.szModule); // Name of ConEmuHk*.*.dll module may be changed (copied to %APPDATA%) if (!pszName || !*pszName) continue; lstrcpyn(szName, pszName, countof(szName)); CharLowerBuff(szName, lstrlen(szName)); if (!ptrOuterKernel && (lstrcmp(szName, L"kernel32.dll") == 0)) { ptrOuterKernel = mi.hModule; } // ConEmuHk*.*.dll? if (!bAlreadyHooked && (wmemcmp(szName, pszConEmuHk, nDllNameLen) == 0) && (wmemcmp(szName+lstrlen(szName)-4, L".dll", 4) == 0)) { // Yes! ConEmuHk.dll already loaded into nRemotePID! // But what is the version? Let don't downgrade loaded version! if (lstrcmp(szName, szOurName) >= 0) { // OK, szName is newer or equal to our build bAlreadyHooked = true; } } // Stop enumeration? if (bAlreadyHooked && ptrOuterKernel) break; } while (Module32Next(hSnap, &mi)); // Check done } SafeCloseHandle(hSnap); // Already hooked? if (bAlreadyHooked) { iRc = CIR_AlreadyInjected/*1*/; goto wrap; } if (!ptrOuterKernel) { iRc = CIR_OuterKernelAddr/*-112*/; goto wrap; } // Check, if we can access that process hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, nRemotePID); if (hProc == NULL) { iRc = CIR_OpenProcess/*-201*/; goto wrap; } // Go to hook // Preparing Events _wsprintf(szName, SKIPLEN(countof(szName)) CEDEFAULTTERMHOOK, nRemotePID); if (!abDefTermOnly) { // When running in normal mode (NOT set up as default terminal) // we need full initialization procedure, not a light one when hooking explorer.exe hEvent = OpenEvent(EVENT_MODIFY_STATE|SYNCHRONIZE, FALSE, szName); if (hEvent) { ResetEvent(hEvent); CloseHandle(hEvent); } } else { hEvent = CreateEvent(LocalSecurity(), FALSE, FALSE, szName); SetEvent(hEvent); _wsprintf(szName, SKIPLEN(countof(szName)) CEDEFAULTTERMHOOKOK, nRemotePID); hDefTermReady = CreateEvent(LocalSecurity(), FALSE, FALSE, szName); ResetEvent(hDefTermReady); } // Creating as remote thread. // Resetting this event notify ConEmuHk about // 1) need to determine MainThreadId // 2) need to start pipe server _wsprintf(szName, SKIPLEN(countof(szName)) CECONEMUROOTTHREAD, nRemotePID); hEvent = OpenEvent(EVENT_MODIFY_STATE|SYNCHRONIZE, FALSE, szName); if (hEvent) { ResetEvent(hEvent); CloseHandle(hEvent); } // Определить битность процесса, Если он 32битный, а текущий - ConEmuC64.exe // Перезапустить 32битную версию ConEmuC.exe nBits = GetProcessBits(nRemotePID, hProc); if (nBits == 0) { // Do not even expected, ConEmu GUI must run ConEmuC elevated if required. iRc = CIR_GetProcessBits/*-204*/; goto wrap; } is32bit = (nBits == 32); 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(szHooks, szArgs, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { iRc = CIR_CreateProcess/*-202*/; goto wrap; } nWrapperWait = WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &nWrapperResult); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); if ((nWrapperResult != CERR_HOOKS_WAS_SET) && (nWrapperResult != CERR_HOOKS_WAS_ALREADY_SET)) { iRc = CIR_WrapperResult/*-203*/; SetLastError(nWrapperResult); goto wrap; } // Значит всю работу сделал враппер iRc = CIR_OK/*0*/; goto wrap; } // Поехали _wcscpy_c(pszNamePtr, 16, is32bit ? L"ConEmuHk.dll" : L"ConEmuHk64.dll"); if (!FileExists(szHooks)) { iRc = CIR_ConEmuHkNotFound/*-250*/; goto wrap; } if (abDefTermOnly) { CINFILTRATE_EXIT_CODES iFRc = PrepareHookModule(szHooks); if (iFRc != 0) { iRc = iFRc; goto wrap; } } iRc = InfiltrateDll(hProc, ptrOuterKernel, szHooks); // Если создавали временную копию - запланировать ее удаление if (abDefTermOnly && (lstrcmpi(szHooks, szSelf) != 0)) { MoveFileEx(szHooks, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); } wrap: if (hProc != NULL) CloseHandle(hProc); // But check the result of the operation //_ASSERTE(FALSE && "WaitForSingleObject(hDefTermReady)"); if ((iRc == 0) && hDefTermReady) { _ASSERTE(abDefTermOnly); DWORD nWaitReady = WaitForSingleObject(hDefTermReady, CEDEFAULTTERMHOOKWAIT/*==0*/); if (nWaitReady == WAIT_TIMEOUT) { iRc = CIR_DefTermWaitingFailed/*-300*/; // Failed to start hooking thread in remote process } } return iRc; }
void CToolTip::ShowTip(HWND ahOwner, HWND ahControl, LPCWSTR asText, BOOL abBalloon, POINT pt, HINSTANCE hInstance) { HideTip(); if (!asText || !*asText) return; int nTipLen = lstrlen(asText); if (!mpsz_LastTip || (nTipLen >= mn_LastTipCchMax)) { if (mpsz_LastTip) free(mpsz_LastTip); mn_LastTipCchMax = nTipLen + 1; mpsz_LastTip = (wchar_t*)malloc(mn_LastTipCchMax*sizeof(wchar_t)); } _wcscpy_c(mpsz_LastTip, mn_LastTipCchMax, asText); TOOLINFO *pti = abBalloon ? (&mti_Ball) : (&mti_Tip); if (abBalloon) { if (!mh_Ball || !IsWindow(mh_Ball)) { mh_Ball = CreateWindowEx ( WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, ahOwner, NULL, hInstance/*g_hInstance*/, NULL); SetWindowPos(mh_Ball, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); // Set up tool information. // In this case, the "tool" is the entire parent window. pti->cbSize = 44; // был sizeof(TOOLINFO); pti->uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE; pti->hwnd = ahControl; pti->hinst = hInstance; static wchar_t szAsterisk[] = L"*"; // eliminate GCC warning pti->lpszText = szAsterisk; pti->uId = (UINT_PTR)ahControl; GetClientRect(ahControl, &(pti->rect)); // Associate the ToolTip with the tool window. SendMessage(mh_Ball, TTM_ADDTOOL, 0, (LPARAM)pti); // Allow multiline SendMessage(mh_Ball, TTM_SETMAXTIPWIDTH, 0, (LPARAM)300); } } else { if (!mh_Tip || !IsWindow(mh_Tip)) { mh_Tip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, ahOwner, NULL, hInstance, NULL); SetWindowPos(mh_Tip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); SendMessage(mh_Tip, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000); } } mb_LastTipBalloon = abBalloon; HWND hTip = abBalloon ? (mh_Ball) : (mh_Tip); if (!hTip) { _ASSERTE(hTip != NULL); return; } pti->lpszText = mpsz_LastTip; SendMessage(hTip, TTM_UPDATETIPTEXT, 0, (LPARAM)pti); //RECT rcControl; GetWindowRect(GetDlgItem(hDlg, nCtrlID), &rcControl); //int ptx = rcControl.right - 10; //int pty = (rcControl.top + rcControl.bottom) / 2; SendMessage(hTip, TTM_TRACKPOSITION, 0, MAKELONG(pt.x,pt.y)); SendMessage(hTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)pti); //SetTimer(hDlg, FAILED_FONT_TIMERID, nTimeout/*FAILED_FONT_TIMEOUT*/, 0); }
INT_PTR CSetPgIntegr::PageDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { static bool bSkipCbSel = FALSE; INT_PTR iRc = 0; switch (messg) { case WM_NOTIFY: { LPNMHDR phdr = (LPNMHDR)lParam; if (phdr->code == TTN_GETDISPINFO) { return gpSetCls->ProcessTipHelp(hDlg, messg, wParam, lParam); } break; } case WM_INITDIALOG: { bSkipCbSel = true; PageDlgProc(hDlg, UM_RELOAD_HERE_LIST, UM_RELOAD_HERE_LIST, 0); //-- moved to "ComSpec" page //PageDlgProc(hDlg, UM_RELOAD_AUTORUN, UM_RELOAD_AUTORUN, 0); // Возвращает NULL, если строка пустая wchar_t* pszCurInside = GetDlgItemTextPtr(hDlg, cbInsideName); _ASSERTE((pszCurInside==NULL) || (*pszCurInside!=0)); wchar_t* pszCurHere = GetDlgItemTextPtr(hDlg, cbHereName); _ASSERTE((pszCurHere==NULL) || (*pszCurHere!=0)); wchar_t szIcon[MAX_PATH+32]; _wsprintf(szIcon, SKIPLEN(countof(szIcon)) L"%s,0", gpConEmu->ms_ConEmuExe); if (pszCurInside) { bSkipCbSel = false; PageDlgProc(hDlg, WM_COMMAND, MAKELONG(cbInsideName,CBN_SELCHANGE), 0); bSkipCbSel = true; } else { SetDlgItemText(hDlg, cbInsideName, L"ConEmu Inside"); SetDlgItemText(hDlg, tInsideConfig, L"shell"); SetDlgItemText(hDlg, tInsideShell, CONEMU_HERE_POSH); //SetDlgItemText(hDlg, tInsideIcon, szIcon); SetDlgItemText(hDlg, tInsideIcon, L"powershell.exe"); checkDlgButton(hDlg, cbInsideSyncDir, gpConEmu->mp_Inside && gpConEmu->mp_Inside->mb_InsideSynchronizeCurDir); SetDlgItemText(hDlg, tInsideSyncDir, L""); // Auto } if (pszCurHere) { bSkipCbSel = false; PageDlgProc(hDlg, WM_COMMAND, MAKELONG(cbHereName,CBN_SELCHANGE), 0); bSkipCbSel = true; } else { SetDlgItemText(hDlg, cbHereName, L"ConEmu Here"); SetDlgItemText(hDlg, tHereConfig, L""); SetDlgItemText(hDlg, tHereShell, CONEMU_HERE_CMD); SetDlgItemText(hDlg, tHereIcon, szIcon); } bSkipCbSel = false; SafeFree(pszCurInside); SafeFree(pszCurHere); } break; // WM_INITDIALOG case WM_COMMAND: switch (HIWORD(wParam)) { case BN_CLICKED: { WORD CB = LOWORD(wParam); switch (CB) { case cbInsideSyncDir: if (gpConEmu->mp_Inside) { gpConEmu->mp_Inside->mb_InsideSynchronizeCurDir = isChecked(hDlg, CB); } break; case bInsideRegister: case bInsideUnregister: ShellIntegration(hDlg, ShellIntgr_Inside, CB==bInsideRegister); PageDlgProc(hDlg, UM_RELOAD_HERE_LIST, UM_RELOAD_HERE_LIST, 0); if (CB==bInsideUnregister) PageDlgProc(hDlg, WM_COMMAND, MAKELONG(cbInsideName,CBN_SELCHANGE), 0); break; case bHereRegister: case bHereUnregister: ShellIntegration(hDlg, ShellIntgr_Here, CB==bHereRegister); PageDlgProc(hDlg, UM_RELOAD_HERE_LIST, UM_RELOAD_HERE_LIST, 0); if (CB==bHereUnregister) PageDlgProc(hDlg, WM_COMMAND, MAKELONG(cbHereName,CBN_SELCHANGE), 0); break; } } break; // BN_CLICKED case EN_CHANGE: { WORD EB = LOWORD(wParam); switch (EB) { case tInsideSyncDir: if (gpConEmu->mp_Inside) { SafeFree(gpConEmu->mp_Inside->ms_InsideSynchronizeCurDir); gpConEmu->mp_Inside->ms_InsideSynchronizeCurDir = GetDlgItemTextPtr(hDlg, tInsideSyncDir); } break; } } break; // EN_CHANGE case CBN_SELCHANGE: { WORD CB = LOWORD(wParam); switch (CB) { case cbInsideName: case cbHereName: if (!bSkipCbSel) { wchar_t *pszCfg = NULL, *pszIco = NULL, *pszFull = NULL, *pszDirSync = NULL; LPCWSTR pszCmd = NULL; INT_PTR iSel = SendDlgItemMessage(hDlg, CB, CB_GETCURSEL, 0,0); if (iSel >= 0) { INT_PTR iLen = SendDlgItemMessage(hDlg, CB, CB_GETLBTEXTLEN, iSel, 0); size_t cchMax = iLen+128; wchar_t* pszName = (wchar_t*)calloc(cchMax,sizeof(*pszName)); if ((iLen > 0) && pszName) { _wcscpy_c(pszName, cchMax, L"Directory\\shell\\"); SendDlgItemMessage(hDlg, CB, CB_GETLBTEXT, iSel, (LPARAM)(pszName+_tcslen(pszName))); HKEY hkShell = NULL; if (0 == RegOpenKeyEx(HKEY_CLASSES_ROOT, pszName, 0, KEY_READ, &hkShell)) { DWORD nType; DWORD nSize = MAX_PATH*2*sizeof(wchar_t); pszIco = (wchar_t*)calloc(nSize+2,1); if (0 != RegQueryValueEx(hkShell, L"Icon", NULL, &nType, (LPBYTE)pszIco, &nSize) || nType != REG_SZ) SafeFree(pszIco); HKEY hkCmd = NULL; if (0 == RegOpenKeyEx(hkShell, L"command", 0, KEY_READ, &hkCmd)) { DWORD nSize = MAX_PATH*8*sizeof(wchar_t); pszFull = (wchar_t*)calloc(nSize+2,1); if (0 != RegQueryValueEx(hkCmd, NULL, NULL, &nType, (LPBYTE)pszFull, &nSize) || nType != REG_SZ) { SafeFree(pszIco); } else { LPCWSTR psz = pszFull; LPCWSTR pszPrev = pszFull; CEStr szArg; while (0 == NextArg(&psz, szArg, &pszPrev)) { if (*szArg != L'/') continue; if ((lstrcmpi(szArg, L"/inside") == 0) || (lstrcmpi(szArg, L"/here") == 0) ) { // Nop } else if (lstrcmpni(szArg, L"/inside=", 8) == 0) { pszDirSync = lstrdup(szArg+8); // may be empty! } else if (lstrcmpi(szArg, L"/config") == 0) { if (0 != NextArg(&psz, szArg)) break; pszCfg = lstrdup(szArg); } else if (lstrcmpi(szArg, L"/dir") == 0) { if (0 != NextArg(&psz, szArg)) break; _ASSERTE(lstrcmpi(szArg, L"%1")==0); } else //if (lstrcmpi(szArg, L"/cmd") == 0) { if (lstrcmpi(szArg, L"/cmd") == 0) pszCmd = psz; else pszCmd = pszPrev; break; } } } RegCloseKey(hkCmd); } RegCloseKey(hkShell); } } SafeFree(pszName); } SetDlgItemText(hDlg, (CB==cbInsideName) ? tInsideConfig : tHereConfig, pszCfg ? pszCfg : L""); SetDlgItemText(hDlg, (CB==cbInsideName) ? tInsideShell : tHereShell, pszCmd ? pszCmd : L""); SetDlgItemText(hDlg, (CB==cbInsideName) ? tInsideIcon : tHereIcon, pszIco ? pszIco : L""); if (CB==cbInsideName) { SetDlgItemText(hDlg, tInsideSyncDir, pszDirSync ? pszDirSync : L""); checkDlgButton(hDlg, cbInsideSyncDir, (pszDirSync && *pszDirSync) ? BST_CHECKED : BST_UNCHECKED); } SafeFree(pszCfg); SafeFree(pszFull); SafeFree(pszIco); SafeFree(pszDirSync); } break; } } break; // CBN_SELCHANGE } // switch (HIWORD(wParam)) break; // WM_COMMAND case UM_RELOAD_HERE_LIST: if (wParam == UM_RELOAD_HERE_LIST) { HKEY hkDir = NULL; size_t cchCmdMax = 65535; wchar_t* pszCmd = (wchar_t*)calloc(cchCmdMax,sizeof(*pszCmd)); if (!pszCmd) break; // Возвращает NULL, если строка пустая wchar_t* pszCurInside = GetDlgItemTextPtr(hDlg, cbInsideName); _ASSERTE((pszCurInside==NULL) || (*pszCurInside!=0)); wchar_t* pszCurHere = GetDlgItemTextPtr(hDlg, cbHereName); _ASSERTE((pszCurHere==NULL) || (*pszCurHere!=0)); bool lbOldSkip = bSkipCbSel; bSkipCbSel = true; SendDlgItemMessage(hDlg, cbInsideName, CB_RESETCONTENT, 0, 0); SendDlgItemMessage(hDlg, cbHereName, CB_RESETCONTENT, 0, 0); if (0 == RegOpenKeyEx(HKEY_CLASSES_ROOT, L"Directory\\shell", 0, KEY_READ, &hkDir)) { for (DWORD i = 0; i < 512; i++) { wchar_t szName[MAX_PATH+32] = {}; DWORD cchMax = countof(szName) - 32; if (0 != RegEnumKeyEx(hkDir, i, szName, &cchMax, NULL, NULL, NULL, NULL)) break; wchar_t* pszSlash = szName + _tcslen(szName); wcscat_c(szName, L"\\command"); HKEY hkCmd = NULL; if (0 == RegOpenKeyEx(hkDir, szName, 0, KEY_READ, &hkCmd)) { DWORD cbMax = (cchCmdMax-2) * sizeof(*pszCmd); if (0 == RegQueryValueEx(hkCmd, NULL, NULL, NULL, (LPBYTE)pszCmd, &cbMax)) { pszCmd[cbMax>>1] = 0; *pszSlash = 0; LPCWSTR pszInside = StrStrI(pszCmd, L"/inside"); LPCWSTR pszConEmu = StrStrI(pszCmd, L"conemu"); if (pszConEmu) { SendDlgItemMessage(hDlg, pszInside ? cbInsideName : cbHereName, CB_ADDSTRING, 0, (LPARAM)szName); if ((pszInside ? pszCurInside : pszCurHere) == NULL) { if (pszInside) pszCurInside = lstrdup(szName); else pszCurHere = lstrdup(szName); } } } RegCloseKey(hkCmd); } } RegCloseKey(hkDir); }