DWORD CDragDrop::DragStart(IDropSource *pDropSource, const DWORD dwAllowedEffects, DWORD& dwEffect) { DWORD dwResult = E_UNEXPECTED; wchar_t szStep[255]; _wsprintf(szStep, SKIPLEN(countof(szStep)) L"DoDragDrop(Eff=0x%X, DataObject=0x%08X, DropSource=0x%08X)", dwAllowedEffects, (DWORD)mp_DataObject, (DWORD)pDropSource); //-V205 DebugLog(szStep); SAFETRY { dwResult = DoDragDrop(mp_DataObject, pDropSource, dwAllowedEffects, &dwEffect); } SAFECATCH { dwResult = DRAGDROP_S_CANCEL; MBoxA(L"Exception in DoDragDrop\nConEmu restart is recommended"); } _wsprintf(szStep, SKIPLEN(countof(szStep)) L"DoDragDrop finished, Code=0x%08X", dwResult); switch(dwResult) { case S_OK: wcscat_c(szStep, L" (S_OK)"); break; case DRAGDROP_S_DROP: wcscat_c(szStep, L" (DRAGDROP_S_DROP)"); break; case DRAGDROP_S_CANCEL: wcscat_c(szStep, L" (DRAGDROP_S_CANCEL)"); break; //case E_UNSPEC: lstrcat(szStep, L" (E_UNSPEC)"); break; } DebugLog(szStep, (dwResult!=S_OK && dwResult!=DRAGDROP_S_CANCEL && dwResult!=DRAGDROP_S_DROP)); return dwResult; }
void CConEmuUpdate::GetVersionsFromIni(LPCWSTR pszUpdateVerLocation, wchar_t (&szServer)[100], wchar_t (&szInfo)[100]) { wchar_t szTest[64]; // Дописать stable/preview/alpha bool bDetected = false, bNewer; wcscpy_c(szInfo, ms_CurVersion); struct { LPCWSTR szSect, szPref, szName; } Vers[] = { {sectionConEmuStable, L"Stable:\t", L" stable" }, {sectionConEmuPreview, L"\nPreview:\t", L" preview"}, {sectionConEmuDevel, L"\nDevel:\t", L" devel" } }; szServer[0] = 0; for (size_t i = 0; i < countof(Vers); i++) { wcscat_c(szServer, Vers[i].szPref); if (GetPrivateProfileString(Vers[i].szSect, L"version", L"", szTest, countof(szTest), pszUpdateVerLocation)) { bNewer = (lstrcmp(szTest, ms_CurVersion) >= 0); if (!bDetected && bNewer) { bDetected = true; wcscat_c(szInfo, Vers[i].szName); } szTest[10] = 0; wcscat_c(szServer, szTest); if (bNewer) wcscat_c(szServer, (lstrcmp(szTest, ms_CurVersion) > 0) ? L" (newer)" : L" (equal)"); } else wcscat_c(szServer, L"<Not found>"); } }
bool CConEmuUpdate::CanUpdateInstallation() { if (UpdateDownloadSetup() == 1) { // Если через Setupper - то msi сам разберется и ругнется когда надо return true; } // Раз дошли сюда - значит ConEmu был просто "распакован" if (IsUserAdmin()) { // ConEmu запущен "Под администратором", проверки не нужны return true; } wchar_t szTestFile[MAX_PATH*2]; wcscpy_c(szTestFile, gpConEmu->ms_ConEmuExeDir); wcscat_c(szTestFile, L"\\ConEmuUpdate.check"); HANDLE hFile = CreateFile(szTestFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_TEMPORARY, NULL); if (hFile == INVALID_HANDLE_VALUE) { DWORD nErr = GetLastError(); wcscpy_c(szTestFile, L"Can't update installation folder!\r\n"); wcscat_c(szTestFile, gpConEmu->ms_ConEmuExeDir); DisplayLastError(szTestFile, nErr); return false; } CloseHandle(hFile); DeleteFile(szTestFile); // OK return true; }
int PrepareHookModule(wchar_t (&szModule)[MAX_PATH+16]) { int iRc = -251; wchar_t szNewPath[MAX_PATH+16] = {}, szAddName[32] = {}, szVer[2] = {}; INT_PTR nLen = 0; // Copy szModule to CSIDL_LOCAL_APPDATA and return new path HRESULT hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szNewPath); if ((hr != S_OK) || !*szNewPath) { iRc = -251; goto wrap; } szVer[0] = MVV_4a[0]; _wsprintf(szAddName, SKIPLEN(countof(szAddName)) L"\\ConEmuHk%s.%02u%02u%02u%s.dll", WIN3264TEST(L"",L"64"), MVV_1, MVV_2, MVV_3, szVer); nLen = lstrlen(szNewPath); if (szNewPath[nLen-1] != L'\\') { szNewPath[nLen++] = L'\\'; szNewPath[nLen] = 0; } if ((nLen + lstrlen(szAddName) + 8) >= countof(szNewPath)) { iRc = -252; goto wrap; } wcscat_c(szNewPath, L"ConEmu"); if (!DirectoryExists(szNewPath)) { if (!CreateDirectory(szNewPath, NULL)) { iRc = -253; goto wrap; } } wcscat_c(szNewPath, szAddName); if (FileExists(szNewPath) && FileCompare(szNewPath, szModule)) { // OK, file exists and match the required } else { if (!CopyFile(szModule, szNewPath, FALSE)) { iRc = -254; goto wrap; } } wcscpy_c(szModule, szNewPath); iRc = 0; wrap: return iRc; }
void CGestures::DumpGesture(LPCWSTR tp, const GESTUREINFO& gi) { wchar_t szDump[256]; _wsprintf(szDump, SKIPLEN(countof(szDump)) L"Gesture(x%08X {%i,%i} %s", (DWORD)gi.hwndTarget, gi.ptsLocation.x, gi.ptsLocation.y, tp); // tp - имя жеста switch (gi.dwID) { case GID_PRESSANDTAP: { DWORD h = LODWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32) L" Dist={%i,%i}", (int)(short)LOWORD(h), (int)(short)HIWORD(h)); break; } case GID_ROTATE: { DWORD h = LODWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32) L" %i", (int)LOWORD(h)); break; } } if (gi.dwFlags&GF_BEGIN) wcscat_c(szDump, L" GF_BEGIN"); if (gi.dwFlags&GF_END) wcscat_c(szDump, L" GF_END"); if (gi.dwFlags&GF_INERTIA) { wcscat_c(szDump, L" GF_INERTIA"); DWORD h = HIDWORD(gi.ullArguments); _wsprintf(szDump+_tcslen(szDump), SKIPLEN(32) L" {%i,%i}", (int)(short)LOWORD(h), (int)(short)HIWORD(h)); } if (gpSetCls->isAdvLogging >= 2) { gpConEmu->LogString(szDump); } else { #ifdef USE_DUMPGEST wcscat_c(szDump, L")\n"); DEBUGSTR(szDump); #endif } }
void MEvent::OnDebugNotify(MEventNotification Action) { wchar_t szInfo[MAX_PATH]; wcscpy_c(szInfo, L"MEvent: "); switch (Action) { case evn_Create: wcscat_c(szInfo, L"Create"); break; case evn_Open: wcscat_c(szInfo, L"Open"); break; case evn_Set: wcscat_c(szInfo, L"Set"); break; case evn_Reset: wcscat_c(szInfo, L"Reset"); break; case evn_Close: wcscat_c(szInfo, L"Close"); break; default: wcscat_c(szInfo, L"???"); } wcscat_c(szInfo, L": "); if (mb_NameIsNull) _wsprintf(szInfo + _tcslen(szInfo), SKIPLEN(countof(szInfo) - _tcslen(szInfo)) L"Handle=0x%p", mh_Event); else wcscat_c(szInfo, ms_EventName); DEBUGSTREVT(szInfo); szInfo[0] = 0; }
LPCWSTR CDataObject::GetFormatName(CLIPFORMAT cfFormat, bool bRaw) { static wchar_t szName[128]; szName[0] = bRaw ? 0 : L'\''; if (GetClipboardFormatName(cfFormat, szName+(bRaw?0:1), 80) >= 1) { if (!bRaw) { wcscat_c(szName, L"',"); } } else { szName[0] = 0; } if (!bRaw || (szName[0] == 0)) { int nLen = lstrlen(szName); _wsprintf(szName+nLen, SKIPLEN(countof(szName)-nLen) L"x%04X(%u)", cfFormat, cfFormat); } return szName; }
void CTabBarClass::PrintRecentStack() { #ifdef PRINT_RECENT_STACK if (!this) return; wchar_t szDbg[100]; DEBUGSTRRECENT(L"=== Printing recent tab stack ===\n"); for (INT_PTR i = 0; i < m_TabStack.size(); i++) { CTabID* p = m_TabStack[i]; if (p == mp_DummyTab) continue; if (!p) { _ASSERTE(p!=NULL); continue; } _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"%2u: %s", i+1, (p->Info.Status == tisPassive) ? L"<passive> " : (p->Info.Status == tisEmpty) ? L"<not_init> " : (p->Info.Status == tisInvalid) ? L"<invalid> " : L""); lstrcpyn(szDbg+lstrlen(szDbg), p->GetLabel(), 60); wcscat_c(szDbg, L"\n"); DEBUGSTRRECENT(szDbg); } DEBUGSTRRECENT(L"===== Recent tab stack done =====\n"); #endif }
// Issue 1191: ConEmu was launched instead of explorer from taskbar pinned library icon void CSetPgIntegr::UnregisterShellInvalids() { HKEY hkDir; if (0 == RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes\\LibraryFolder\\shell", 0, KEY_READ, &hkDir)) { int iOthers = 0; MArray<wchar_t*> lsNames; for (DWORD i = 0; i < 512; i++) { wchar_t szName[MAX_PATH+32] = {}; wchar_t szCmd[MAX_PATH*4]; 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 = sizeof(szCmd)-2; if (0 == RegQueryValueEx(hkCmd, NULL, NULL, NULL, (LPBYTE)szCmd, &cbMax)) { szCmd[cbMax>>1] = 0; *pszSlash = 0; //LPCWSTR pszInside = StrStrI(szCmd, L"-inside"); LPCWSTR pszConEmu = StrStrI(szCmd, L"conemu"); if (pszConEmu) lsNames.push_back(lstrdup(szName)); else iOthers++; } RegCloseKey(hkCmd); }
void ConEmuAbout::OnInfo_WhatsNew(bool bLocal) { wchar_t sFile[MAX_PATH+80]; int iExec = -1; if (bLocal) { wcscpy_c(sFile, gpConEmu->ms_ConEmuBaseDir); wcscat_c(sFile, L"\\WhatsNew-ConEmu.txt"); if (FileExists(sFile)) { iExec = (int)ShellExecute(ghWnd, L"open", sFile, NULL, NULL, SW_SHOWNORMAL); if (iExec >= 32) { return; } } } wcscpy_c(sFile, gsWhatsNew); iExec = (int)ShellExecute(ghWnd, L"open", sFile, NULL, NULL, SW_SHOWNORMAL); if (iExec >= 32) { return; } DisplayLastError(L"File 'WhatsNew-ConEmu.txt' not found, go to web page failed", iExec); }
void CSetPgBase::setHotkeyCheckbox(HWND hDlg, WORD nCtrlId, int iHotkeyId, LPCWSTR pszFrom, LPCWSTR pszTo, UINT uChecked) { wchar_t szKeyFull[128] = L""; gpSet->GetHotkeyNameById(iHotkeyId, szKeyFull, false); if (szKeyFull[0] == 0) { EnableWindow(GetDlgItem(hDlg, nCtrlId), FALSE); checkDlgButton(hDlg, nCtrlId, BST_UNCHECKED); } else { if (pszFrom) { wchar_t* ptr = (wchar_t*)wcsstr(szKeyFull, pszFrom); if (ptr) { *ptr = 0; if (pszTo) { wcscat_c(szKeyFull, pszTo); } } } CEStr lsText(GetDlgItemTextPtr(hDlg, nCtrlId)); LPCWSTR pszTail = lsText.IsEmpty() ? NULL : wcsstr(lsText, L" - "); if (pszTail) { CEStr lsNew(szKeyFull, pszTail); SetDlgItemText(hDlg, nCtrlId, lsNew); } checkDlgButton(hDlg, nCtrlId, uChecked); } }
// 1-установлено через Installer, пути совпали, 2-Installer не запускался BYTE ConEmuUpdateSettings::UpdateDownloadSetup() { if (isUpdateDownloadSetup) return isUpdateDownloadSetup; // если 0 - пока не проверялся if (isSetupDetected == 0) { HKEY hk; LONG lRc; //bool bUseSetupExe = false; wchar_t szInstallDir[MAX_PATH+2], szExeDir[MAX_PATH+2]; wcscpy_c(szExeDir, gpConEmu->ms_ConEmuExeDir); wcscat_c(szExeDir, L"\\"); for (size_t i = 0; i <= 2; i++) { DWORD dwSam = KEY_READ | ((i == 0) ? 0 : (i == 1) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); LPCWSTR pszName = ((i == 0) ? WIN3264TEST(L"InstallDir",L"InstallDir_x64") : (i == 1) ? L"InstallDir" : L"InstallDir_x64"); lRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\ConEmu", 0, dwSam, &hk); if (lRc == 0) { _ASSERTE(countof(szInstallDir)>(MAX_PATH+1)); DWORD dwSize = MAX_PATH*sizeof(*szInstallDir); if (0 == RegQueryValueEx(hk, pszName, NULL, NULL, (LPBYTE)szInstallDir, &dwSize) && *szInstallDir) { size_t nLen = _tcslen(szInstallDir); if (szInstallDir[nLen-1] != L'\\') wcscat_c(szInstallDir, L"\\"); if (lstrcmpi(szInstallDir, szExeDir) == 0) { isSetupDetected = 1; } } RegCloseKey(hk); } } if (!isSetupDetected) isSetupDetected = 2; } // Если признаки установки через "ConEmuSetup.exe" не найдены, или пути не совпали - грузим через 7z _ASSERTE(isSetupDetected!=0); return isSetupDetected ? isSetupDetected : 2; }
void _DEBUGSTR(LPCWSTR s) { MCHKHEAP; CHEKCDBGMODLABEL; SYSTEMTIME st; GetLocalTime(&st); wchar_t szDEBUGSTRTime[1040]; _wsprintf(szDEBUGSTRTime, SKIPLEN(countof(szDEBUGSTRTime)) L"%i:%02i:%02i.%03i(%s.%i.%i) ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, gszDbgModLabel, GetCurrentProcessId(), GetCurrentThreadId()); LPCWSTR psz = s; int nSLen = lstrlen(psz); if (nSLen < 999) { wcscat_c(szDEBUGSTRTime, s); if (nSLen && psz[nSLen-1]!=L'\n') wcscat_c(szDEBUGSTRTime, L"\n"); OutputDebugString(szDEBUGSTRTime); } else { OutputDebugString(szDEBUGSTRTime); OutputDebugString(psz); if (nSLen && psz[nSLen-1]!=L'\n') OutputDebugString(L"\n"); } }
void UnitExpandTest() { CmdArg szExe; wchar_t szChoc[MAX_PATH] = L"powershell -NoProfile -ExecutionPolicy unrestricted -Command \"iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))\" && SET PATH=%PATH%;%systemdrive%\\chocolatey\\bin"; wchar_t* pszExpanded = ExpandEnvStr(szChoc); int nLen = pszExpanded ? lstrlen(pszExpanded) : 0; BOOL bFound = FileExistsSearch(szChoc, szExe, false); wcscpy_c(szChoc, gpConEmu->ms_ConEmuExeDir); wcscat_c(szChoc, L"\\Tests\\Executables\\abcd"); bFound = FileExistsSearch(szChoc, szExe, false); // TakeCommand ConEmuComspec tcc = {cst_AutoTccCmd}; FindComspec(&tcc, false); }
// nPID = 0 when hooking is done (remove status bar notification) // sName is executable name or window class name bool CDefaultTerminal::NotifyHookingStatus(DWORD nPID, LPCWSTR sName) { wchar_t szInfo[200] = L""; if (nPID) { msprintf(szInfo, countof(szInfo), L"DefTerm setup: PID=%u", nPID); if (sName && *sName) { wcscat_c(szInfo, L", "); int nLen = lstrlen(szInfo); lstrcpyn(szInfo+nLen, sName, countof(szInfo)-nLen); } } gpConEmu->mp_Status->SetStatus(szInfo); // descendant must return true if status bar was changed return true; }
CTabID::~CTabID() { #ifdef _DEBUG wchar_t szDbg[120]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"~CTabID(PID=%u IDX=%u TYP=%u '", Info.nPID, Info.nFarWindowID, (UINT)Type()); int nDbgLen = lstrlen(szDbg); lstrcpyn(szDbg+nDbgLen, GetName(), countof(szDbg)-nDbgLen-5); wcscat_c(szDbg, L"')\n"); DEBUGSTRDEL(szDbg); #endif Name.Release(); Renamed.Release(); ReleaseDrawRegion(); #ifdef DEBUG_TAB_LIST gTabIdList.Del(this); #endif }
INT_PTR CRecreateDlg::OnInitDialog(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { LRESULT lbRc = FALSE; gpConEmu->OnOurDialogOpened(); // Visual SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon); SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm); // Set password style (avoid "bars" on some OS) SendDlgItemMessage(hDlg, tRunAsPassword, WM_SETFONT, (LPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), 0); // Add menu items HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); InsertMenu(hSysMenu, 0, MF_BYPOSITION, MF_SEPARATOR, 0); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED, ID_RESETCMDHISTORY, L"Clear history..."); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED | (gpSet->isSaveCmdHistory ? MF_CHECKED : 0), ID_STORECMDHISTORY, L"Store history"); //#ifdef _DEBUG //SetWindowPos(ghOpWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); //#endif RConStartArgs* pArgs = mp_Args; _ASSERTE(pArgs); // Fill command and task drop down SendMessage(hDlg, UM_FILL_CMDLIST, TRUE, 0); // Set text in command and folder fields SetDlgItemText(hDlg, IDC_RESTART_CMD, mpsz_DefCmd ? mpsz_DefCmd : pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : L""); // Current directory, startup directory, ConEmu startup directory, and may be startup directory history in the future AddDirectoryList(mpsz_DefDir ? mpsz_DefDir : pArgs->pszStartupDir); AddDirectoryList(ms_RConCurDir); AddDirectoryList(ms_RConStartDir); AddDirectoryList(gpConEmu->WorkDir()); LPCWSTR pszShowDir; if ((pArgs->aRecreate == cra_RecreateTab) && !ms_RConCurDir.IsEmpty()) pszShowDir = ms_RConCurDir; else pszShowDir = mpsz_DefDir ? mpsz_DefDir : pArgs->pszStartupDir ? pArgs->pszStartupDir : gpConEmu->WorkDir(); SetDlgItemText(hDlg, IDC_STARTUP_DIR, pszShowDir); // Split controls if (pArgs->aRecreate == cra_RecreateTab) { // Hide Split's ShowWindow(GetDlgItem(hDlg, gbRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplitNone), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Right), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Bottom), SW_HIDE); ShowWindow(GetDlgItem(hDlg, stRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, tRecreateSplit), SW_HIDE); } else { // Fill splits SetDlgItemInt(hDlg, tRecreateSplit, (1000-pArgs->nSplitValue)/10, FALSE); CheckRadioButton(hDlg, rbRecreateSplitNone, rbRecreateSplit2Bottom, rbRecreateSplitNone+pArgs->eSplit); EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); } // Спрятать флажок "New window" bool bRunInNewWindow_Hidden = (pArgs->aRecreate == cra_EditTab || pArgs->aRecreate == cra_RecreateTab); ShowWindow(GetDlgItem(hDlg, cbRunInNewWindow), bRunInNewWindow_Hidden ? SW_HIDE : SW_SHOWNORMAL); const wchar_t *pszUser = pArgs->pszUserName; const wchar_t *pszDomain = pArgs->pszDomain; bool bResticted = (pArgs->RunAsRestricted == crb_On); int nChecked = rbCurrentUser; DWORD nUserNameLen = countof(ms_CurUser); if (!GetUserName(ms_CurUser, &nUserNameLen)) ms_CurUser[0] = 0; wchar_t szRbCaption[MAX_PATH*3]; lstrcpy(szRbCaption, L"Run as current &user: "******"UPN format" остается в pszUser lstrcpyn(szOtherUser, pszUser, MAX_PATH); wcscat_c(szOtherUser, L"@"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszDomain, MAX_PATH); } else { // "Старая" нотация domain\user lstrcpyn(szOtherUser, pszDomain, MAX_PATH); wcscat_c(szOtherUser, L"\\"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszUser, MAX_PATH); } } else { lstrcpyn(szOtherUser, pszUser, countof(szOtherUser)); } SetDlgItemText(hDlg, tRunAsPassword, pArgs->szUserPassword); } } SetDlgItemText(hDlg, tRunAsUser, (nChecked == rbAnotherUser) ? szOtherUser : L""); CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, nChecked); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); if (gOSVer.dwMajorVersion < 6) { // В XP и ниже это просто RunAs - с возможностью ввода имени пользователя и пароля //apiShowWindow(GetDlgItem(hDlg, cbRunAsAdmin), SW_HIDE); SetDlgItemTextA(hDlg, cbRunAsAdmin, "&Run as..."); //GCC hack. иначе не собирается // И уменьшить длину RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, 0, 0, (rcBox.right-rcBox.left)/2, rcBox.bottom-rcBox.top, SWP_NOMOVE|SWP_NOZORDER); } else if (gpConEmu->mb_IsUacAdmin || (pArgs && (pArgs->RunAsAdministrator == crb_On))) { CheckDlgButton(hDlg, cbRunAsAdmin, BST_CHECKED); if (gpConEmu->mb_IsUacAdmin) // Только в Vista+ если GUI уже запущен под админом { EnableWindow(GetDlgItem(hDlg, cbRunAsAdmin), FALSE); } else //if (gOSVer.dwMajorVersion < 6) { RecreateDlgProc(hDlg, WM_COMMAND, cbRunAsAdmin, 0); } } //} SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon); RECT rcBtnBox = {0}; if (pArgs->aRecreate == cra_RecreateTab) { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "About to restart console"); SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_EXCLAMATION), 0); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); lbRc = TRUE; } else { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); // Если ВЫКЛЮЧЕН "Multi consoles in one window" // - Check & Disable "New window" checkbox CheckDlgButton(hDlg, cbRunInNewWindow, (pArgs->aRecreate == cra_CreateWindow || !gpSetCls->IsMulti()) ? BST_CHECKED : BST_UNCHECKED); EnableWindow(GetDlgItem(hDlg, cbRunInNewWindow), gpSetCls->IsMulti()); // SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_QUESTION), 0); POINT pt = {0,0}; MapWindowPoints(GetDlgItem(hDlg, IDC_TERMINATE), hDlg, &pt, 1); DestroyWindow(GetDlgItem(hDlg, IDC_TERMINATE)); SetWindowPos(GetDlgItem(hDlg, IDC_START), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetDlgItemText(hDlg, IDC_START, (pArgs->aRecreate == cra_EditTab) ? L"&Save" : L"&Start"); DestroyWindow(GetDlgItem(hDlg, IDC_WARNING)); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); } if (rcBtnBox.left) { // Выровнять флажок по кнопке MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtnBox, 2); RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); POINT pt; pt.x = rcBtnBox.left - (rcBox.right - rcBox.left) - 5; pt.y = rcBtnBox.top + ((rcBtnBox.bottom-rcBtnBox.top) - (rcBox.bottom-rcBox.top))/2; SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); } // Correct cbRunInNewWindow position if (!bRunInNewWindow_Hidden) { POINT pt = {}; MapWindowPoints(GetDlgItem(hDlg, cbRunAsAdmin), hDlg, &pt, 1); RECT rcBox2; GetWindowRect(GetDlgItem(hDlg, cbRunInNewWindow), &rcBox2); SetWindowPos(GetDlgItem(hDlg, cbRunInNewWindow), NULL, pt.x-(rcBox2.right-rcBox2.left), pt.y, 0,0, SWP_NOSIZE); } // Dpi aware processing at the end of sequence // because we done some manual control reposition if (mp_DpiAware) { mp_DpiAware->Attach(hDlg, ghWnd); } // Ensure, it will be "on screen" RECT rect; GetWindowRect(hDlg, &rect); RECT rcCenter = CenterInParent(rect, mh_Parent); MoveWindow(hDlg, rcCenter.left, rcCenter.top, rect.right - rect.left, rect.bottom - rect.top, false); // Была отключена обработка CConEmuMain::OnFocus (лишние телодвижения) PostMessage(hDlg, (WM_APP+1), 0,0); // Default focus control if (pArgs->aRecreate == cra_RecreateTab) SetFocus(GetDlgItem(hDlg, IDC_START)); // Win+~ (Recreate tab), Focus on "Restart" button" else if ((pArgs->pszUserName && *pArgs->pszUserName) && !*pArgs->szUserPassword) SetFocus(GetDlgItem(hDlg, tRunAsPassword)); // We need password, all other fields are ready else SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); // Set focus in command-line field return lbRc; }
int PrepareHookModule(wchar_t (&szModule)[MAX_PATH+16]) { int iRc = -251; wchar_t szNewPath[MAX_PATH+16] = {}, szAddName[32] = {}, szVer[2] = {}; INT_PTR nLen = 0; bool bAlreadyExists = false; // Copy szModule to CSIDL_LOCAL_APPDATA and return new path HRESULT hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0/*SHGFP_TYPE_CURRENT*/, szNewPath); if ((hr != S_OK) || !*szNewPath) { iRc = -251; goto wrap; } szVer[0] = MVV_4a[0]; _wsprintf(szAddName, SKIPLEN(countof(szAddName)) L"\\" CEDEFTERMDLLFORMAT /*L"ConEmuHk%s.%02u%02u%02u%s.dll"*/, WIN3264TEST(L"",L"64"), MVV_1, MVV_2, MVV_3, szVer); nLen = lstrlen(szNewPath); if (szNewPath[nLen-1] != L'\\') { szNewPath[nLen++] = L'\\'; szNewPath[nLen] = 0; } if ((nLen + lstrlen(szAddName) + 8) >= countof(szNewPath)) { iRc = -252; goto wrap; } wcscat_c(szNewPath, L"ConEmu"); if (!DirectoryExists(szNewPath)) { if (!CreateDirectory(szNewPath, NULL)) { iRc = -253; goto wrap; } } wcscat_c(szNewPath, szAddName); if ((bAlreadyExists = FileExists(szNewPath)) && FileCompare(szNewPath, szModule)) { // OK, file exists and match the required } else { if (bAlreadyExists) { _ASSERTE(FALSE && "Continue to overwrite existing ConEmuHk in AppLocal"); // Try to delete or rename old version if (!DeleteFile(szNewPath)) { //SYSTEMTIME st; GetLocalTime(&st); wchar_t szBakPath[MAX_PATH+32]; wcscpy_c(szBakPath, szNewPath); wchar_t* pszExt = (wchar_t*)PointToExt(szBakPath); msprintf(pszExt, 16, L".%u.dll", GetTickCount()); DeleteFile(szBakPath); MoveFile(szNewPath, szBakPath); } } if (!CopyFile(szModule, szNewPath, FALSE)) { iRc = -254; goto wrap; } } wcscpy_c(szModule, szNewPath); iRc = 0; wrap: return iRc; }
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; }
INT_PTR CRecreateDlg::RecreateDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { #define UM_USER_CONTROLS (WM_USER+121) #define UM_FILL_CMDLIST (WM_USER+122) CRecreateDlg* pDlg = NULL; if (messg == WM_INITDIALOG) { pDlg = (CRecreateDlg*)lParam; pDlg->mh_Dlg = hDlg; SetWindowLongPtr(hDlg, DWLP_USER, lParam); } else { pDlg = (CRecreateDlg*)GetWindowLongPtr(hDlg, DWLP_USER); } if (!pDlg) { return FALSE; } PatchMsgBoxIcon(hDlg, messg, wParam, lParam); switch (messg) { case WM_INITDIALOG: { LRESULT lbRc = FALSE; // Visual SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon); SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm); // Set password style (avoid "bars" on some OS) SendDlgItemMessage(hDlg, tRunAsPassword, WM_SETFONT, (LPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), 0); // Add menu items HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); InsertMenu(hSysMenu, 0, MF_BYPOSITION, MF_SEPARATOR, 0); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED, ID_RESETCMDHISTORY, L"Clear history..."); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED | (gpSet->isSaveCmdHistory ? MF_CHECKED : 0), ID_STORECMDHISTORY, L"Store history"); //#ifdef _DEBUG //SetWindowPos(ghOpWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); //#endif RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); // Fill command and task drop down SendMessage(hDlg, UM_FILL_CMDLIST, TRUE, 0); // Set text in command and folder fields SetDlgItemText(hDlg, IDC_RESTART_CMD, pDlg->mpsz_DefCmd ? pDlg->mpsz_DefCmd : pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : L""); SetDlgItemText(hDlg, IDC_STARTUP_DIR, pDlg->mpsz_DefDir ? pDlg->mpsz_DefDir : pArgs->pszStartupDir ? pArgs->pszStartupDir : gpConEmu->WorkDir()); // Split controls if (pArgs->aRecreate == cra_RecreateTab) { // Hide Split's ShowWindow(GetDlgItem(hDlg, gbRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplitNone), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Right), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Bottom), SW_HIDE); ShowWindow(GetDlgItem(hDlg, stRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, tRecreateSplit), SW_HIDE); } else { // Fill splits SetDlgItemInt(hDlg, tRecreateSplit, (1000-pArgs->nSplitValue)/10, FALSE); CheckRadioButton(hDlg, rbRecreateSplitNone, rbRecreateSplit2Bottom, rbRecreateSplitNone+pArgs->eSplit); EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); } // Спрятать флажок "New window" bool bRunInNewWindow_Hidden = (pArgs->aRecreate == cra_EditTab || pArgs->aRecreate == cra_RecreateTab); ShowWindow(GetDlgItem(hDlg, cbRunInNewWindow), bRunInNewWindow_Hidden ? SW_HIDE : SW_SHOWNORMAL); const wchar_t *pszUser = pArgs->pszUserName; const wchar_t *pszDomain = pArgs->pszDomain; bool bResticted = (pArgs->RunAsRestricted == crb_On); int nChecked = rbCurrentUser; DWORD nUserNameLen = countof(pDlg->ms_CurUser); if (!GetUserName(pDlg->ms_CurUser, &nUserNameLen)) pDlg->ms_CurUser[0] = 0; wchar_t szRbCaption[MAX_PATH*3]; lstrcpy(szRbCaption, L"Run as current &user: "******"UPN format" остается в pszUser lstrcpyn(szOtherUser, pszUser, MAX_PATH); wcscat_c(szOtherUser, L"@"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszDomain, MAX_PATH); } else { // "Старая" нотация domain\user lstrcpyn(szOtherUser, pszDomain, MAX_PATH); wcscat_c(szOtherUser, L"\\"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszUser, MAX_PATH); } } else { lstrcpyn(szOtherUser, pszUser, countof(szOtherUser)); } SetDlgItemText(hDlg, tRunAsPassword, pArgs->szUserPassword); } } SetDlgItemText(hDlg, tRunAsUser, (nChecked == rbAnotherUser) ? szOtherUser : L""); CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, nChecked); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); if (gOSVer.dwMajorVersion < 6) { // В XP и ниже это просто RunAs - с возможностью ввода имени пользователя и пароля //apiShowWindow(GetDlgItem(hDlg, cbRunAsAdmin), SW_HIDE); SetDlgItemTextA(hDlg, cbRunAsAdmin, "&Run as..."); //GCC hack. иначе не собирается // И уменьшить длину RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, 0, 0, (rcBox.right-rcBox.left)/2, rcBox.bottom-rcBox.top, SWP_NOMOVE|SWP_NOZORDER); } else if (gpConEmu->mb_IsUacAdmin || (pArgs && (pArgs->RunAsAdministrator == crb_On))) { CheckDlgButton(hDlg, cbRunAsAdmin, BST_CHECKED); if (gpConEmu->mb_IsUacAdmin) // Только в Vista+ если GUI уже запущен под админом { EnableWindow(GetDlgItem(hDlg, cbRunAsAdmin), FALSE); } else if (gOSVer.dwMajorVersion < 6) { RecreateDlgProc(hDlg, WM_COMMAND, cbRunAsAdmin, 0); } } //} SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon); RECT rcBtnBox = {0}; if (pArgs->aRecreate == cra_RecreateTab) { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "About to restart console"); SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_EXCLAMATION), 0); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); lbRc = TRUE; } else { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); // Если ВЫКЛЮЧЕН "Multi consoles in one window" // - Check & Disable "New window" checkbox CheckDlgButton(hDlg, cbRunInNewWindow, (pArgs->aRecreate == cra_CreateWindow || !gpSetCls->IsMulti()) ? BST_CHECKED : BST_UNCHECKED); EnableWindow(GetDlgItem(hDlg, cbRunInNewWindow), gpSetCls->IsMulti()); // SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_QUESTION), 0); POINT pt = {0,0}; MapWindowPoints(GetDlgItem(hDlg, IDC_TERMINATE), hDlg, &pt, 1); DestroyWindow(GetDlgItem(hDlg, IDC_TERMINATE)); SetWindowPos(GetDlgItem(hDlg, IDC_START), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetDlgItemText(hDlg, IDC_START, (pArgs->aRecreate == cra_EditTab) ? L"&Save" : L"&Start"); DestroyWindow(GetDlgItem(hDlg, IDC_WARNING)); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); } if (rcBtnBox.left) { // Выровнять флажок по кнопке MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtnBox, 2); RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); POINT pt; pt.x = rcBtnBox.left - (rcBox.right - rcBox.left) - 5; pt.y = rcBtnBox.top + ((rcBtnBox.bottom-rcBtnBox.top) - (rcBox.bottom-rcBox.top))/2; SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); } // Correct cbRunInNewWindow position if (!bRunInNewWindow_Hidden) { POINT pt = {}; MapWindowPoints(GetDlgItem(hDlg, cbRunAsAdmin), hDlg, &pt, 1); RECT rcBox2; GetWindowRect(GetDlgItem(hDlg, cbRunInNewWindow), &rcBox2); SetWindowPos(GetDlgItem(hDlg, cbRunInNewWindow), NULL, pt.x-(rcBox2.right-rcBox2.left), pt.y, 0,0, SWP_NOSIZE); } // Ensure, it will be "on screen" RECT rect; GetWindowRect(hDlg, &rect); RECT rcCenter = CenterInParent(rect, pDlg->mh_Parent); MoveWindow(hDlg, rcCenter.left, rcCenter.top, rect.right - rect.left, rect.bottom - rect.top, false); // Была отключена обработка CConEmuMain::OnFocus (лишние телодвижения) PostMessage(hDlg, (WM_APP+1), 0,0); // Default focus control if (pArgs->aRecreate == cra_RecreateTab) SetFocus(GetDlgItem(hDlg, IDC_START)); // Win+~ (Recreate tab), Focus on "Restart" button" else if ((pArgs->pszUserName && *pArgs->pszUserName) && !*pArgs->szUserPassword) SetFocus(GetDlgItem(hDlg, tRunAsPassword)); // We need password, all other fields are ready else SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); // Set focus in command-line field return lbRc; } case (WM_APP+1): //TODO: Не совсем корректно, не учитывается предыдущее значение флажка gpConEmu->SetSkipOnFocus(false); return FALSE; case WM_CTLCOLORSTATIC: if (GetDlgItem(hDlg, IDC_WARNING) == (HWND)lParam) { SetTextColor((HDC)wParam, 255); HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE); SetBkMode((HDC)wParam, TRANSPARENT); return (INT_PTR)hBrush; } break; //case WM_GETICON: // if (wParam==ICON_BIG) // { // /*SetWindowLong(hWnd2, DWL_MSGRESULT, (LRESULT)hClassIcon); // return 1;*/ // } // else // { // SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LRESULT)hClassIconSm); // return 1; // } // return 0; case UM_FILL_CMDLIST: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); pDlg->AddCommandList(pArgs->pszSpecialCmd); pDlg->AddCommandList(pDlg->mpsz_SysCmd, pArgs->pszSpecialCmd ? -1 : 0); pDlg->AddCommandList(pDlg->mpsz_CurCmd); pDlg->AddCommandList(pDlg->mpsz_DefCmd); // Может быть позван после очистки истории из меню, тогда нет смысла и дергаться if (wParam) { LPCWSTR pszHistory = gpSet->HistoryGet(); if (pszHistory) { while (*pszHistory) { pDlg->AddCommandList(pszHistory); pszHistory += _tcslen(pszHistory)+1; } } } // Tasks int nGroup = 0; const Settings::CommandTasks* pGrp = NULL; while ((pGrp = gpSet->CmdTaskGet(nGroup++))) { pDlg->AddCommandList(pGrp->pszName); } } return 0; case UM_USER_CONTROLS: { if (SendDlgItemMessage(hDlg, rbCurrentUser, BM_GETCHECK, 0, 0)) { EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), TRUE); //BOOL lbText = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) == 0; EnableWindow(GetDlgItem(hDlg, tRunAsUser), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), FALSE); } else { if (SendDlgItemMessage(hDlg, tRunAsUser, CB_GETCOUNT, 0, 0) == 0) { DWORD dwLevel = 3, dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0; NET_API_STATUS nStatus; USER_INFO_3 *info = NULL; nStatus = ::NetUserEnum(NULL, dwLevel, FILTER_NORMAL_ACCOUNT, (PBYTE*) & info, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nStatus == NERR_Success) { wchar_t *pszAdmin = NULL, *pszLikeAdmin = NULL, *pszOtherUser = NULL; for (DWORD i = 0; i < dwEntriesRead; ++i) { // usri3_logon_server "\\*" wchar_t * if (!(info[i].usri3_flags & UF_ACCOUNTDISABLE) && info[i].usri3_name && *info[i].usri3_name) { SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)info[i].usri3_name); if (info[i].usri3_priv == 2/*USER_PRIV_ADMIN*/) { if (!pszAdmin && (info[i].usri3_user_id == 500)) pszAdmin = lstrdup(info[i].usri3_name); else if (!pszLikeAdmin && (lstrcmpi(pDlg->ms_CurUser, info[i].usri3_name) != 0)) pszLikeAdmin = lstrdup(info[i].usri3_name); } else if (!pszOtherUser && (info[i].usri3_priv == 1/*USER_PRIV_USER*/) && (lstrcmpi(pDlg->ms_CurUser, info[i].usri3_name) != 0)) { pszOtherUser = lstrdup(info[i].usri3_name); } } } if (GetWindowTextLength(GetDlgItem(hDlg, tRunAsUser)) == 0) { // Try to suggest "Administrator" account SetDlgItemText(hDlg, tRunAsUser, pszAdmin ? pszAdmin : pszLikeAdmin ? pszLikeAdmin : pszOtherUser ? pszOtherUser : pDlg->ms_CurUser); } ::NetApiBufferFree(info); SafeFree(pszAdmin); SafeFree(pszLikeAdmin); } else { // Добавить хотя бы текущего SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)pDlg->ms_CurUser); } } EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsUser), TRUE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), TRUE); } if (wParam == rbAnotherUser) SetFocus(GetDlgItem(hDlg, tRunAsUser)); } return 0; case WM_SYSCOMMAND: switch (LOWORD(wParam)) { case ID_RESETCMDHISTORY: // Подтверждение спросит ResetCmdHistory if (gpSetCls->ResetCmdHistory(hDlg)) { wchar_t* pszCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_RESETCONTENT, 0,0); SendMessage(hDlg, UM_FILL_CMDLIST, FALSE, 0); if (pszCmd) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszCmd); free(pszCmd); } } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); return 1; case ID_STORECMDHISTORY: if (MsgBox(gpSet->isSaveCmdHistory ? L"Do you want to disable history?" : L"Do you want to enable history?", MB_YESNO|MB_ICONQUESTION, NULL, hDlg) == IDYES) { gpSetCls->SetSaveCmdHistory(!gpSet->isSaveCmdHistory); HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); CheckMenuItem(hSysMenu, ID_STORECMDHISTORY, MF_BYCOMMAND|(gpSet->isSaveCmdHistory ? MF_CHECKED : 0)); } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); return 1; } break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDC_CHOOSE: { wchar_t *pszFilePath = SelectFile(L"Choose program to run", NULL, hDlg, L"Executables (*.exe)\0*.exe\0All files (*.*)\0*.*\0\0", true, false, false); if (pszFilePath) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszFilePath); SafeFree(pszFilePath); } return 1; } case IDC_CHOOSE_DIR: { wchar_t* pszDefFolder = GetDlgItemText(hDlg, IDC_STARTUP_DIR); wchar_t* pszFolder = SelectFolder(L"Choose startup directory", pszDefFolder, hDlg, false, false); if (pszFolder) { SetDlgItemText(hDlg, IDC_STARTUP_DIR, pszFolder); SafeFree(pszFolder); } SafeFree(pszDefFolder); return 1; } case cbRunAsAdmin: { // BCM_SETSHIELD = 5644 BOOL bRunAs = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0); if (gOSVer.dwMajorVersion >= 6) { SendDlgItemMessage(hDlg, IDC_START, 5644/*BCM_SETSHIELD*/, 0, bRunAs && (pDlg->mp_Args->aRecreate != cra_EditTab)); } if (bRunAs) { CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, rbCurrentUser); CheckDlgButton(hDlg, cbRunAsRestricted, BST_UNCHECKED); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); } return 1; } case rbCurrentUser: case rbAnotherUser: case cbRunAsRestricted: { RecreateDlgProc(hDlg, UM_USER_CONTROLS, LOWORD(wParam), 0); return 1; } case rbRecreateSplitNone: case rbRecreateSplit2Right: case rbRecreateSplit2Bottom: { RConStartArgs* pArgs = pDlg->mp_Args; switch (LOWORD(wParam)) { case rbRecreateSplitNone: pArgs->eSplit = RConStartArgs::eSplitNone; break; case rbRecreateSplit2Right: pArgs->eSplit = RConStartArgs::eSplitHorz; break; case rbRecreateSplit2Bottom: pArgs->eSplit = RConStartArgs::eSplitVert; break; } EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); if (pArgs->eSplit != pArgs->eSplitNone) SetFocus(GetDlgItem(hDlg, tRecreateSplit)); return 1; } case IDC_START: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); SafeFree(pArgs->pszUserName); SafeFree(pArgs->pszDomain); //SafeFree(pArgs->pszUserPassword); if (SendDlgItemMessage(hDlg, rbAnotherUser, BM_GETCHECK, 0, 0)) { pArgs->RunAsRestricted = crb_Off; pArgs->pszUserName = GetDlgItemText(hDlg, tRunAsUser); if (pArgs->pszUserName) { //pArgs->pszUserPassword = GetDlgItemText(hDlg, tRunAsPassword); // Попытаться проверить правильность введенного пароля и возможность запуска bool bCheckPwd = pArgs->CheckUserToken(GetDlgItem(hDlg, tRunAsPassword)); DWORD nErr = bCheckPwd ? 0 : GetLastError(); if (!bCheckPwd) { DisplayLastError(L"Invalid user name or password was specified!", nErr, MB_ICONSTOP, NULL, hDlg); return 1; } } } else { pArgs->RunAsRestricted = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) ? crb_On : crb_Off; } // Vista+ (As Admin...) pArgs->RunAsAdministrator = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0) ? crb_On : crb_Off; // StartupDir (may be specified as argument) wchar_t* pszDir = GetDlgItemText(hDlg, IDC_STARTUP_DIR); wchar_t* pszExpand = (pszDir && wcschr(pszDir, L'%')) ? ExpandEnvStr(pszDir) : NULL; LPCWSTR pszDirResult = pszExpand ? pszExpand : pszDir; // Another user? We may fail with access denied. Check only for "current user" account if (!pArgs->pszUserName && pszDirResult && *pszDirResult && !DirectoryExists(pszDirResult)) { wchar_t* pszErrInfo = lstrmerge(L"Specified directory does not exists!\n", pszDirResult, L"\n" L"Do you want to choose another directory?\n\n"); DWORD nErr = GetLastError(); int iDirBtn = DisplayLastError(pszErrInfo, nErr, MB_ICONEXCLAMATION|MB_YESNO, NULL, hDlg); if (iDirBtn == IDYES) { SafeFree(pszDir); SafeFree(pszExpand); SafeFree(pszErrInfo); return 1; } // User want to run "as is". Most likely it will fail, but who knows... } SafeFree(pArgs->pszStartupDir); pArgs->pszStartupDir = pszExpand ? pszExpand : pszDir; if (pszExpand) { SafeFree(pszDir) } // Command // pszSpecialCmd мог быть передан аргументом - умолчание для строки ввода SafeFree(pArgs->pszSpecialCmd); // GetDlgItemText выделяет память через calloc pArgs->pszSpecialCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); if (pArgs->pszSpecialCmd) gpSet->HistoryAdd(pArgs->pszSpecialCmd); if ((pArgs->aRecreate != cra_RecreateTab) && (pArgs->aRecreate != cra_EditTab)) { if (SendDlgItemMessage(hDlg, cbRunInNewWindow, BM_GETCHECK, 0, 0)) pArgs->aRecreate = cra_CreateWindow; else pArgs->aRecreate = cra_CreateTab; } if (((pArgs->aRecreate == cra_CreateTab) || (pArgs->aRecreate == cra_EditTab)) && (pArgs->eSplit != RConStartArgs::eSplitNone)) { BOOL bOk = FALSE; int nPercent = GetDlgItemInt(hDlg, tRecreateSplit, &bOk, FALSE); if (bOk && (nPercent >= 1) && (nPercent <= 99)) { pArgs->nSplitValue = (100-nPercent) * 10; } //pArgs->nSplitPane = 0; Сбрасывать не будем? } pDlg->mn_DlgRc = IDC_START; EndDialog(hDlg, IDC_START); return 1; } case IDC_TERMINATE: pDlg->mn_DlgRc = IDC_TERMINATE; EndDialog(hDlg, IDC_TERMINATE); return 1; case IDCANCEL: pDlg->mn_DlgRc = IDCANCEL; EndDialog(hDlg, IDCANCEL); return 1; } } else if ((HIWORD(wParam) == EN_SETFOCUS) && lParam) { switch (LOWORD(wParam)) { case tRecreateSplit: case tRunAsPassword: PostMessage((HWND)lParam, EM_SETSEL, 0, SendMessage((HWND)lParam, WM_GETTEXTLENGTH, 0,0)); break; } } break; default: return 0; }
INT_PTR CRecreateDlg::RecreateDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { #define UM_USER_CONTROLS (WM_USER+121) #define UM_FILL_CMDLIST (WM_USER+122) CRecreateDlg* pDlg = NULL; if (messg == WM_INITDIALOG) { pDlg = (CRecreateDlg*)lParam; pDlg->mh_Dlg = hDlg; SetWindowLongPtr(hDlg, DWLP_USER, lParam); } else { pDlg = (CRecreateDlg*)GetWindowLongPtr(hDlg, DWLP_USER); } if (!pDlg) { return FALSE; } switch (messg) { case WM_INITDIALOG: { LRESULT lbRc = FALSE; SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon); SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm); HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); InsertMenu(hSysMenu, 0, MF_BYPOSITION, MF_SEPARATOR, 0); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED | ((GetWindowLong(ghOpWnd,GWL_EXSTYLE)&WS_EX_TOPMOST) ? MF_CHECKED : 0), ID_RESETCMDHISTORY, _T("Reset command history...")); SendDlgItemMessage(hDlg, tRunAsPassword, WM_SETFONT, (LPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), 0); //#ifdef _DEBUG //SetWindowPos(ghOpWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); //#endif SendMessage(hDlg, UM_FILL_CMDLIST, TRUE, 0); RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); LPCWSTR pszCmd = pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : gpConEmu->ActiveCon()->RCon()->GetCmd(); //int nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszCmd); //if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, 0, (LPARAM)pszCmd); LPCWSTR pszSystem = gpSet->GetCmd(); //if (pszSystem != pszCmd && (pszSystem && pszCmd && (lstrcmpi(pszSystem, pszCmd) != 0))) //{ // nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszSystem); // if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, pArgs->pszSpecialCmd ? -1 : 0, (LPARAM)pszSystem); //} //LPCWSTR pszHistory = gpSet->HistoryGet(); //if (pszHistory) //{ // while (*pszHistory) // { // nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszHistory); // if (nId < 0) // SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, -1, (LPARAM)pszHistory); // pszHistory += _tcslen(pszHistory)+1; // } //} ////// Обновить группы команд ////gpSet->LoadCmdTasks(NULL); //int nGroup = 0; //const Settings::CommandTasks* pGrp = NULL; //while ((pGrp = gpSet->CmdTaskGet(nGroup++))) //{ // nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pGrp->pszName); // if (nId < 0) // SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, -1, (LPARAM)pGrp->pszName); //} if (pArgs->aRecreate == cra_RecreateTab) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszCmd); SetDlgItemText(hDlg, IDC_STARTUP_DIR, gpConEmu->ActiveCon()->RCon()->GetDir()); } else { SetDlgItemText(hDlg, IDC_RESTART_CMD, pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : pszSystem); SetDlgItemText(hDlg, IDC_STARTUP_DIR, pArgs->pszStartupDir ? pArgs->pszStartupDir : L""); } //EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_DIR), FALSE); //#ifndef _DEBUG //EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_DIR), FALSE); //#endif const wchar_t *pszUser, *pszDomain; BOOL bResticted; int nChecked = rbCurrentUser; wchar_t szCurUser[MAX_PATH*2+1]; DWORD nUserNameLen = countof(szCurUser); if (!GetUserName(szCurUser, &nUserNameLen)) szCurUser[0] = 0; wchar_t szRbCaption[MAX_PATH*3]; lstrcpy(szRbCaption, L"Run as current &user: "******"UPN format" остается в pszUser lstrcpyn(szCurUser, pszUser, MAX_PATH); wcscat_c(szCurUser, L"@"); lstrcpyn(szCurUser+_tcslen(szCurUser), pszDomain, MAX_PATH); } else { // "Старая" нотация domain\user lstrcpyn(szCurUser, pszDomain, MAX_PATH); wcscat_c(szCurUser, L"\\"); lstrcpyn(szCurUser+_tcslen(szCurUser), pszUser, MAX_PATH); } } else { lstrcpyn(szCurUser, pszUser, countof(szCurUser)); } SetDlgItemText(hDlg, tRunAsPassword, L""); } } SetDlgItemText(hDlg, tRunAsUser, szCurUser); CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, nChecked); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); if (gOSVer.dwMajorVersion < 6) { // В XP и ниже это просто RunAs - с возможностью ввода имени пользователя и пароля //apiShowWindow(GetDlgItem(hDlg, cbRunAsAdmin), SW_HIDE); SetDlgItemTextA(hDlg, cbRunAsAdmin, "&Run as..."); //GCC hack. иначе не собирается // И уменьшить длину RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, 0, 0, (rcBox.right-rcBox.left)/2, rcBox.bottom-rcBox.top, SWP_NOMOVE|SWP_NOZORDER); } else if (gpConEmu->mb_IsUacAdmin || (pArgs && pArgs->bRunAsAdministrator)) { CheckDlgButton(hDlg, cbRunAsAdmin, BST_CHECKED); if (gpConEmu->mb_IsUacAdmin) // Только в Vista+ если GUI уже запущен под админом { EnableWindow(GetDlgItem(hDlg, cbRunAsAdmin), FALSE); } else if (gOSVer.dwMajorVersion < 6) { RecreateDlgProc(hDlg, WM_COMMAND, cbRunAsAdmin, 0); } } //} SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon); RECT rcBtnBox = {0}; if (pArgs->aRecreate == cra_RecreateTab) { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "About to recreate console"); SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_EXCLAMATION), 0); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); // Спрятать флажок "New window" ShowWindow(GetDlgItem(hDlg, cbRunInNewWindow), SW_HIDE); lbRc = TRUE; } else { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); CheckDlgButton(hDlg, cbRunInNewWindow, (pArgs->aRecreate == cra_CreateWindow) ? BST_CHECKED : BST_UNCHECKED); //if (pArgs->aRecreate == cra_CreateWindow) //{ // SetWindowText(hDlg, L"ConEmu - Create new window"); // //GCC hack. иначе не собирается // SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new window"); //} //else //{ // //GCC hack. иначе не собирается // SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); //} SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_QUESTION), 0); POINT pt = {0,0}; MapWindowPoints(GetDlgItem(hDlg, IDC_TERMINATE), hDlg, &pt, 1); DestroyWindow(GetDlgItem(hDlg, IDC_TERMINATE)); SetWindowPos(GetDlgItem(hDlg, IDC_START), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetDlgItemText(hDlg, IDC_START, L"&Start"); DestroyWindow(GetDlgItem(hDlg, IDC_WARNING)); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); } if (rcBtnBox.left) { // Выровнять флажок по кнопке MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtnBox, 2); RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); POINT pt; pt.x = rcBtnBox.left - (rcBox.right - rcBox.left) - 5; pt.y = rcBtnBox.top + ((rcBtnBox.bottom-rcBtnBox.top) - (rcBox.bottom-rcBox.top))/2; SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); } if (pArgs->aRecreate != cra_RecreateTab) { POINT pt = {}; MapWindowPoints(GetDlgItem(hDlg, cbRunAsAdmin), hDlg, &pt, 1); RECT rcBox2; GetWindowRect(GetDlgItem(hDlg, cbRunInNewWindow), &rcBox2); SetWindowPos(GetDlgItem(hDlg, cbRunInNewWindow), NULL, pt.x-(rcBox2.right-rcBox2.left), pt.y, 0,0, SWP_NOSIZE); } RECT rect; GetWindowRect(hDlg, &rect); RECT rcParent; GetWindowRect(ghWnd, &rcParent); MoveWindow(hDlg, (rcParent.left+rcParent.right-rect.right+rect.left)/2, (rcParent.top+rcParent.bottom-rect.bottom+rect.top)/2, rect.right - rect.left, rect.bottom - rect.top, false); PostMessage(hDlg, (WM_APP+1), 0,0); return lbRc; } case (WM_APP+1): gpConEmu->SetSkipOnFocus(FALSE); return FALSE; case WM_CTLCOLORSTATIC: if (GetDlgItem(hDlg, IDC_WARNING) == (HWND)lParam) { SetTextColor((HDC)wParam, 255); HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE); SetBkMode((HDC)wParam, TRANSPARENT); return (INT_PTR)hBrush; } break; //case WM_GETICON: // if (wParam==ICON_BIG) // { // /*SetWindowLong(hWnd2, DWL_MSGRESULT, (LRESULT)hClassIcon); // return 1;*/ // } // else // { // SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LRESULT)hClassIconSm); // return 1; // } // return 0; case UM_FILL_CMDLIST: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); LPCWSTR pszCmd = pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : gpConEmu->ActiveCon()->RCon()->GetCmd(); int nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszCmd); if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, 0, (LPARAM)pszCmd); LPCWSTR pszSystem = gpSet->GetCmd(); if (pszSystem != pszCmd && (pszSystem && pszCmd && (lstrcmpi(pszSystem, pszCmd) != 0))) { nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszSystem); if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, pArgs->pszSpecialCmd ? -1 : 0, (LPARAM)pszSystem); } if (wParam) { LPCWSTR pszHistory = gpSet->HistoryGet(); if (pszHistory) { while (*pszHistory) { nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszHistory); if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, -1, (LPARAM)pszHistory); pszHistory += _tcslen(pszHistory)+1; } } } //// Обновить группы команд //gpSet->LoadCmdTasks(NULL); int nGroup = 0; const Settings::CommandTasks* pGrp = NULL; while ((pGrp = gpSet->CmdTaskGet(nGroup++))) { nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pGrp->pszName); if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, -1, (LPARAM)pGrp->pszName); } } return 0; case UM_USER_CONTROLS: { if (SendDlgItemMessage(hDlg, rbCurrentUser, BM_GETCHECK, 0, 0)) { EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), TRUE); //BOOL lbText = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) == 0; EnableWindow(GetDlgItem(hDlg, tRunAsUser), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), FALSE); } else { if (SendDlgItemMessage(hDlg, tRunAsUser, CB_GETCOUNT, 0, 0) == 0) { DWORD dwLevel = 3, dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0; NET_API_STATUS nStatus; USER_INFO_3 *info = NULL; nStatus = ::NetUserEnum(NULL, dwLevel, FILTER_NORMAL_ACCOUNT, (PBYTE*) & info, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nStatus == NERR_Success) { for(DWORD i = 0; i < dwEntriesRead; ++i) { // usri3_logon_server "\\*" wchar_t * if ((info[i].usri3_flags & UF_ACCOUNTDISABLE) == 0) SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)info[i].usri3_name); } ::NetApiBufferFree(info); } else { // Добавить хотя бы текущего wchar_t szCurUser[MAX_PATH]; if (GetWindowText(GetDlgItem(hDlg, tRunAsUser), szCurUser, countof(szCurUser))) SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)szCurUser); } } EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsUser), TRUE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), TRUE); } if (wParam == rbAnotherUser) SetFocus(GetDlgItem(hDlg, tRunAsUser)); } return 0; case WM_SYSCOMMAND: if (LOWORD(wParam) == ID_RESETCMDHISTORY) { if (IDYES == MessageBox(hDlg, L"Clear command history?", gpConEmu->GetDefaultTitle(), MB_ICONEXCLAMATION|MB_YESNO|MB_DEFBUTTON2)) { gpSet->HistoryReset(); wchar_t* pszCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_RESETCONTENT, 0,0); SendMessage(hDlg, UM_FILL_CMDLIST, FALSE, 0); if (pszCmd) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszCmd); free(pszCmd); } } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); return 1; } break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { switch(LOWORD(wParam)) { case IDC_CHOOSE: { wchar_t *pszFilePath = NULL; int nLen = MAX_PATH*2; pszFilePath = (wchar_t*)calloc(nLen+3,2); // +2*'"'+\0 if (!pszFilePath) return 1; OPENFILENAME ofn; memset(&ofn,0,sizeof(ofn)); ofn.lStructSize=sizeof(ofn); ofn.hwndOwner = hDlg; ofn.lpstrFilter = _T("Executables (*.exe)\0*.exe\0\0"); ofn.nFilterIndex = 1; ofn.lpstrFile = pszFilePath+1; ofn.nMaxFile = nLen; ofn.lpstrTitle = _T("Choose program to run"); ofn.Flags = OFN_ENABLESIZING|OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST|OFN_EXPLORER|OFN_HIDEREADONLY|OFN_FILEMUSTEXIST; if (GetOpenFileName(&ofn)) { LPCWSTR pszNewText = pszFilePath + 1; if (wcschr(pszFilePath, L' ')) { pszFilePath[0] = L'"'; _wcscat_c(pszFilePath, nLen+3, L"\""); pszNewText = pszFilePath; } SetDlgItemText(hDlg, IDC_RESTART_CMD, pszNewText); } SafeFree(pszFilePath); return 1; } case IDC_CHOOSE_DIR: { BROWSEINFO bi = {ghWnd}; wchar_t szFolder[MAX_PATH+1] = {0}; GetDlgItemText(hDlg, IDC_STARTUP_DIR, szFolder, countof(szFolder)); bi.pszDisplayName = szFolder; wchar_t szTitle[100]; bi.lpszTitle = wcscpy(szTitle, L"Choose startup directory"); bi.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS | BIF_VALIDATE; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM)szFolder; LPITEMIDLIST pRc = SHBrowseForFolder(&bi); if (pRc) { if (SHGetPathFromIDList(pRc, szFolder)) { SetDlgItemText(hDlg, IDC_STARTUP_DIR, szFolder); } CoTaskMemFree(pRc); } return 1; } case cbRunAsAdmin: { // BCM_SETSHIELD = 5644 BOOL bRunAs = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0); if (gOSVer.dwMajorVersion >= 6) { SendDlgItemMessage(hDlg, IDC_START, 5644/*BCM_SETSHIELD*/, 0, bRunAs); } if (bRunAs) { CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, rbCurrentUser); CheckDlgButton(hDlg, cbRunAsRestricted, BST_UNCHECKED); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); } return 1; } case rbCurrentUser: case rbAnotherUser: case cbRunAsRestricted: { RecreateDlgProc(hDlg, UM_USER_CONTROLS, LOWORD(wParam), 0); return 1; } case IDC_START: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); SafeFree(pArgs->pszUserName); SafeFree(pArgs->pszDomain); //SafeFree(pArgs->pszUserPassword); if (SendDlgItemMessage(hDlg, rbAnotherUser, BM_GETCHECK, 0, 0)) { pArgs->bRunAsRestricted = FALSE; pArgs->pszUserName = GetDlgItemText(hDlg, tRunAsUser); if (pArgs->pszUserName) { //pArgs->pszUserPassword = GetDlgItemText(hDlg, tRunAsPassword); // Попытаться проверить правильность введенного пароля и возможность запуска if (!pArgs->CheckUserToken(GetDlgItem(hDlg, tRunAsPassword))) return 1; } } else { pArgs->bRunAsRestricted = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0); } // Command // pszSpecialCmd мог быть передан аргументом - умолчание для строки ввода SafeFree(pArgs->pszSpecialCmd); // GetDlgItemText выделяет память через calloc pArgs->pszSpecialCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); if (pArgs->pszSpecialCmd) gpSet->HistoryAdd(pArgs->pszSpecialCmd); // StartupDir (может быть передан аргументом) SafeFree(pArgs->pszStartupDir); wchar_t* pszDir = GetDlgItemText(hDlg, IDC_STARTUP_DIR); wchar_t* pszExpand = (pszDir && wcschr(pszDir, L'%')) ? ExpandEnvStr(pszDir) : NULL; pArgs->pszStartupDir = pszExpand ? pszExpand : pszDir; if (pszExpand) { SafeFree(pszDir) } // Vista+ (As Admin...) pArgs->bRunAsAdministrator = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0); if (pArgs->aRecreate != cra_RecreateTab) { if (SendDlgItemMessage(hDlg, cbRunInNewWindow, BM_GETCHECK, 0, 0)) pArgs->aRecreate = cra_CreateWindow; else pArgs->aRecreate = cra_CreateTab; } pDlg->mn_DlgRc = IDC_START; EndDialog(hDlg, IDC_START); return 1; } case IDC_TERMINATE: pDlg->mn_DlgRc = IDC_TERMINATE; EndDialog(hDlg, IDC_TERMINATE); return 1; case IDCANCEL: pDlg->mn_DlgRc = IDCANCEL; EndDialog(hDlg, IDCANCEL); return 1; } } break; default: return 0; } return 0; }
// Do the attach procedure for the requested process bool CAttachDlg::StartAttach(HWND ahAttachWnd, DWORD anPID, DWORD anBits, AttachProcessType anType, BOOL abAltMode) { bool lbRc = false; wchar_t szPipe[MAX_PATH]; PROCESS_INFORMATION pi = {}; STARTUPINFO si = {sizeof(si)}; SHELLEXECUTEINFO sei = {sizeof(sei)}; CESERVER_REQ *pIn = NULL, *pOut = NULL; HANDLE hPipeTest = NULL; HANDLE hPluginTest = NULL; HANDLE hProcTest = NULL; DWORD nErrCode = 0; bool lbCreate; CESERVER_CONSOLE_MAPPING_HDR srv; DWORD nWrapperWait = -1; DWORD nWrapperResult = -1; if (!ahAttachWnd || !anPID || !anBits || !anType) { MBoxAssert(ahAttachWnd && anPID && anBits && anType); goto wrap; } if (gpSetCls->isAdvLogging) { wchar_t szInfo[128]; _wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"CAttachDlg::StartAttach HWND=x%08X, PID=%u, Bits%u, Type=%u, AltMode=%u", (DWORD)(DWORD_PTR)ahAttachWnd, anPID, anBits, (UINT)anType, abAltMode); gpConEmu->LogString(szInfo); } if (LoadSrvMapping(ahAttachWnd, srv)) { pIn = ExecuteNewCmd(CECMD_ATTACH2GUI, sizeof(CESERVER_REQ_HDR)); pOut = ExecuteSrvCmd(srv.nServerPID, pIn, ghWnd); if (pOut && (pOut->hdr.cbSize >= (sizeof(CESERVER_REQ_HDR)+sizeof(DWORD))) && (pOut->dwData[0] != 0)) { // Our console server had been already started // and we successfully have completed the attach lbRc = true; goto wrap; } ExecuteFreeResult(pIn); ExecuteFreeResult(pOut); } // Is it a Far Manager with our ConEmu.dll plugin loaded? _wsprintf(szPipe, SKIPLEN(countof(szPipe)) CEPLUGINPIPENAME, L".", anPID); hPluginTest = CreateFile(szPipe, GENERIC_READ|GENERIC_WRITE, 0, LocalSecurity(), OPEN_EXISTING, 0, NULL); if (hPluginTest && hPluginTest != INVALID_HANDLE_VALUE) { CloseHandle(hPluginTest); goto DoPluginCall; } // May be there is already ConEmuHk[64].dll loaded? Either it is already in the another ConEmu VCon? _wsprintf(szPipe, SKIPLEN(countof(szPipe)) CEHOOKSPIPENAME, L".", anPID); hPipeTest = CreateFile(szPipe, GENERIC_READ|GENERIC_WRITE, 0, LocalSecurity(), OPEN_EXISTING, 0, NULL); if (hPipeTest && hPipeTest != INVALID_HANDLE_VALUE) { CloseHandle(hPipeTest); goto DoExecute; } wchar_t szSrv[MAX_PATH+64], szArgs[128]; wcscpy_c(szSrv, gpConEmu->ms_ConEmuBaseDir); wcscat_c(szSrv, (anBits==64) ? L"\\ConEmuC64.exe" : L"\\ConEmuC.exe"); if (abAltMode && (anType == apt_Console)) { _wsprintf(szArgs, SKIPLEN(countof(szArgs)) L" /ATTACH /CONPID=%u /GID=%u /GHWND=%08X", anPID, GetCurrentProcessId(), LODWORD(ghWnd)); } else { _wsprintf(szArgs, SKIPLEN(countof(szArgs)) L" /INJECT=%u", anPID); abAltMode = FALSE; } si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; if (anType == apt_Gui) { gpConEmu->CreateGuiAttachMapping(anPID); } hProcTest = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ, FALSE, anPID); // If the attaching process is running as admin (elevated) we have to run ConEmuC as admin too if (hProcTest == NULL) { nErrCode = GetLastError(); MBoxAssert(hProcTest!=NULL || nErrCode==ERROR_ACCESS_DENIED); sei.hwnd = ghWnd; sei.fMask = (abAltMode ? 0 : SEE_MASK_NO_CONSOLE)|SEE_MASK_NOCLOSEPROCESS|SEE_MASK_NOASYNC; sei.lpVerb = L"runas"; sei.lpFile = szSrv; sei.lpParameters = szArgs; sei.lpDirectory = gpConEmu->ms_ConEmuBaseDir; sei.nShow = SW_SHOWMINIMIZED; lbCreate = ShellExecuteEx(&sei); if (lbCreate) { MBoxAssert(sei.hProcess!=NULL); pi.hProcess = sei.hProcess; } } else { // Normal start DWORD dwFlags = 0 | (abAltMode ? CREATE_NO_WINDOW : CREATE_NEW_CONSOLE) | CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS; lbCreate = CreateProcess(szSrv, szArgs, NULL, NULL, FALSE, dwFlags, NULL, NULL, &si, &pi); } if (!lbCreate) { wchar_t szErrMsg[MAX_PATH+255], szTitle[128]; DWORD dwErr = GetLastError(); _wsprintf(szErrMsg, SKIPLEN(countof(szErrMsg)) L"Can't start %s server\n%s %s", abAltMode ? L"injection" : L"console", szSrv, szArgs); _wsprintf(szTitle, SKIPLEN(countof(szTitle)) L"ConEmu Attach, PID=%u, TID=%u", GetCurrentProcessId(), GetCurrentThreadId()); DisplayLastError(szErrMsg, dwErr, 0, szTitle); goto wrap; } if (abAltMode) { lbRc = true; goto wrap; } nWrapperWait = WaitForSingleObject(pi.hProcess, INFINITE); nWrapperResult = -1; GetExitCodeProcess(pi.hProcess, &nWrapperResult); CloseHandle(pi.hProcess); if (pi.hThread) CloseHandle(pi.hThread); if (((int)nWrapperResult != CERR_HOOKS_WAS_SET) && ((int)nWrapperResult != CERR_HOOKS_WAS_ALREADY_SET)) { goto wrap; } DoExecute: // Not the attaching process has our ConEmuHk[64].dll loaded // and we can request to start console server for that console or ChildGui pIn = ExecuteNewCmd(CECMD_STARTSERVER, sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_START)); pIn->NewServer.nGuiPID = GetCurrentProcessId(); pIn->NewServer.hGuiWnd = ghWnd; if (anType == apt_Gui) { _ASSERTE(ahAttachWnd && IsWindow(ahAttachWnd)); pIn->NewServer.hAppWnd = ahAttachWnd; } goto DoPipeCall; DoPluginCall: // Ask Far Manager plugin to do the attach pIn = ExecuteNewCmd(CECMD_ATTACH2GUI, sizeof(CESERVER_REQ_HDR)); goto DoPipeCall; DoPipeCall: pOut = ExecuteCmd(szPipe, pIn, 500, ghWnd); if (!pOut || (pOut->hdr.cbSize < pIn->hdr.cbSize) || (pOut->dwData[0] == 0)) { _ASSERTE(pOut && pOut->hdr.cbSize == (sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_START))); wchar_t szMsg[255], szTitle[128]; wcscpy_c(szMsg, L"Failed to start console server in the remote process"); if (hPluginTest && hPluginTest != INVALID_HANDLE_VALUE) wcscat_c(szMsg, L"\nFar ConEmu plugin was loaded"); if (hPipeTest && hPipeTest != INVALID_HANDLE_VALUE) wcscat_c(szMsg, L"\nHooks already were set"); _wsprintf(szTitle, SKIPLEN(countof(szTitle)) L"ConEmu Attach, PID=%u, TID=%u", GetCurrentProcessId(), GetCurrentThreadId()); DisplayLastError(szMsg, (pOut && (pOut->hdr.cbSize >= pIn->hdr.cbSize)) ? pOut->dwData[1] : -1, 0, szTitle); goto wrap; } lbRc = true; wrap: SafeCloseHandle(hProcTest); UNREFERENCED_PARAMETER(nErrCode); UNREFERENCED_PARAMETER(nWrapperWait); ExecuteFreeResult(pIn); ExecuteFreeResult(pOut); return lbRc; }
void MyAssertDumpToFile(const wchar_t* pszFile, int nLine, const wchar_t* pszTest) { wchar_t dmpfile[MAX_PATH+64] = L"", szVer4[8] = L"", szLine[64]; typedef HRESULT (WINAPI* SHGetFolderPath_t)(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath); HMODULE hShell = LoadLibrary(L"shell32.dll"); SHGetFolderPath_t shGetFolderPath = hShell ? (SHGetFolderPath_t)GetProcAddress(hShell, "SHGetFolderPathW") : NULL; HRESULT hrc = shGetFolderPath ? shGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0/*SHGFP_TYPE_CURRENT*/, dmpfile) : E_FAIL; if (hShell) FreeLibrary(hShell); if (FAILED(hrc)) { memset(dmpfile, 0, sizeof(dmpfile)); if (!GetTempPath(MAX_PATH, dmpfile) || !*dmpfile) { //pszError = L"CreateDumpForReport called, get desktop or temp folder failed"; return; } } wcscat_c(dmpfile, (*dmpfile && dmpfile[lstrlen(dmpfile)-1] != L'\\') ? L"\\ConEmuTrap" : L"ConEmuTrap"); CreateDirectory(dmpfile, NULL); int nLen = lstrlen(dmpfile); lstrcpyn(szVer4, _T(MVV_4a), countof(szVer4)); static LONG snAutoIndex = 0; LONG nAutoIndex = InterlockedIncrement(&snAutoIndex); msprintf(dmpfile+nLen, countof(dmpfile)-nLen, L"\\Assert-%02u%02u%02u%s-%u-%u.txt", MVV_1, MVV_2, MVV_3, szVer4, GetCurrentProcessId(), nAutoIndex); HANDLE hFile = CreateFile(dmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { //pszError = L"Failed to create dump file"; return; } DWORD nWrite; msprintf(szLine, countof(szLine), L"CEAssert PID=%u TID=%u\r\nAssertion in ", GetCurrentProcessId(), GetCurrentThreadId()); WriteFile(hFile, szLine, (nWrite = lstrlen(szLine)*2), &nWrite, NULL); if (!GetModuleFileNameW(NULL, dmpfile, countof(dmpfile)-2)) lstrcpyn(dmpfile, L"<unknown>\r\n", countof(dmpfile)); else wcscat_c(dmpfile, L"\r\n"); WriteFile(hFile, dmpfile, (nWrite = lstrlen(dmpfile)*2), &nWrite, NULL); // File.cpp: 123\r\n if (pszFile) { WriteFile(hFile, pszFile, (nWrite = lstrlen(pszFile)*2), &nWrite, NULL); msprintf(szLine, countof(szLine), L": %i\r\n\r\n", nLine); WriteFile(hFile, szLine, (nWrite = lstrlen(szLine)*2), &nWrite, NULL); } if (pszTest) { WriteFile(hFile, pszTest, (nWrite = lstrlen(pszTest)*2), &nWrite, NULL); WriteFile(hFile, L"\r\n", 4, &nWrite, NULL); } CloseHandle(hFile); }
LPCTSTR CConEmuStart::GetCmd(bool *pIsCmdList, bool bNoTask /*= false*/) { LPCWSTR pszCmd = NULL; // true - если передали "скрипт" (как бы содержимое Task вытянутое в строку) // например: "ConEmu.exe -cmdlist cmd ||| powershell ||| far" if (pIsCmdList) *pIsCmdList = false; // User've choosed default task? if (mp_ConEmu->GetStartupStage() >= CConEmuMain::ss_Started) { if ((pszCmd = GetDefaultTask()) != NULL) return pszCmd; } // Current command line, specified with "-run","-runlist" switches (or old "-cmd and "-cmdlist") if ((pszCmd = GetCurCmd(pIsCmdList)) != NULL) return pszCmd; switch (gpSet->nStartType) { case 0: if (gpSet->psStartSingleApp && *gpSet->psStartSingleApp) return gpSet->psStartSingleApp; break; case 1: if (bNoTask) return NULL; if (gpSet->psStartTasksFile && *gpSet->psStartTasksFile) return gpSet->psStartTasksFile; break; case 2: if (bNoTask) return NULL; if (gpSet->psStartTasksName && *gpSet->psStartTasksName) return gpSet->psStartTasksName; break; case 3: if (bNoTask) return NULL; return AutoStartTaskName; } // User've choosed default task? if (mp_ConEmu->GetStartupStage() < CConEmuMain::ss_Started) { if ((pszCmd = GetDefaultTask()) != NULL) return pszCmd; } wchar_t* pszNewCmd = NULL; // Хорошо бы более корректно определить версию фара, но это не всегда просто // Например x64 файл сложно обработать в x86 ConEmu. DWORD nFarSize = 0; if (lstrcmpi(GetDefaultCmd(), L"far") == 0) { // Ищем фар. (1) В папке ConEmu, (2) в текущей директории, (2) на уровень вверх от папки ConEmu wchar_t szFar[MAX_PATH*2], *pszSlash; szFar[0] = L'"'; wcscpy_add(1, szFar, gpConEmu->ms_ConEmuExeDir); // Теперь szFar содержит путь запуска программы pszSlash = szFar + _tcslen(szFar); _ASSERTE(pszSlash > szFar); BOOL lbFound = FALSE; // (1) В папке ConEmu if (!lbFound) { wcscpy_add(pszSlash, szFar, L"\\Far.exe"); if (FileExists(szFar+1, &nFarSize)) lbFound = TRUE; } // (2) в текущей директории if (!lbFound && lstrcmpi(gpConEmu->WorkDir(), gpConEmu->ms_ConEmuExeDir)) { szFar[0] = L'"'; wcscpy_add(1, szFar, gpConEmu->WorkDir()); wcscat_add(1, szFar, L"\\Far.exe"); if (FileExists(szFar+1, &nFarSize)) lbFound = TRUE; } // (3) на уровень вверх if (!lbFound) { szFar[0] = L'"'; wcscpy_add(1, szFar, gpConEmu->ms_ConEmuExeDir); pszSlash = szFar + _tcslen(szFar); *pszSlash = 0; pszSlash = wcsrchr(szFar, L'\\'); if (pszSlash) { wcscpy_add(pszSlash+1, szFar, L"Far.exe"); if (FileExists(szFar+1, &nFarSize)) lbFound = TRUE; } } if (lbFound) { // 110124 - нафиг, если пользователю надо - сам или параметр настроит, или реестр //// far чаще всего будет установлен в "Program Files", поэтому для избежания проблем - окавычиваем //// Пока тупо - если far.exe > 1200K - считаем, что это Far2 //wcscat_c(szFar, (nFarSize>1228800) ? L"\" /w" : L"\""); wcscat_c(szFar, L"\""); // Finally - Result pszNewCmd = lstrdup(szFar); } else { // Если Far.exe не найден рядом с ConEmu - запустить cmd.exe pszNewCmd = GetComspec(&gpSet->ComSpec); //wcscpy_c(szFar, L"cmd"); } } else { // Simple Copy pszNewCmd = lstrdup(GetDefaultCmd()); } SetCurCmd(pszNewCmd, false); return GetCurCmd(pIsCmdList); }
// // IDataObject::SetData // HRESULT __stdcall CDataObject::SetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease) { _ASSERTE(pMedium && pMedium->pUnkForRelease==NULL); #ifdef _DEBUG LPCWSTR pszName = GetFormatName(pFormatEtc->cfFormat, true); DWORD nData = (DWORD)-1; if (lstrcmp(pszName, L"IsShowingLayered")==0 || lstrcmp(pszName, L"IsShowingText")==0 || lstrcmp(pszName, L"DragContext")==0 || lstrcmp(pszName, L"UsingDefaultDragImage")==0 || lstrcmp(pszName, L"DragSourceHelperFlags")==0 || lstrcmp(pszName, L"DragWindow")==0 || lstrcmp(pszName, L"DisableDragText")==0 ) { LPDWORD pdw = (LPDWORD)GlobalLock(pMedium->hGlobal); if (pdw) { nData = *pdw; } GlobalUnlock(pMedium->hGlobal); } wchar_t szDbg[255]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"CDataObject::SetData {cfFormat=%s, lindex=%i, tymed=x%02X(%u)}, {tymed=x%02X}", GetFormatName(pFormatEtc->cfFormat), pFormatEtc->lindex, pFormatEtc->tymed, pFormatEtc->tymed, pMedium->tymed); if (nData != (DWORD)-1) { int nLen = lstrlen(szDbg); _wsprintf(szDbg+nLen, SKIPLEN(countof(szDbg)-nLen) L", Data=x%02X(%u)", nData, nData); } wcscat_c(szDbg, L"\n"); DEBUGSTRDATA(szDbg); #endif DEBUGTEST(bool bNew = false); LONG nIndex = LookupFormatEtc(pFormatEtc); if (nIndex >= 0) { if ((pMedium != &(m_Data[nIndex].StgMedium)) && (pMedium->hGlobal != &(m_Data[nIndex].StgMedium))) { if (m_Data[nIndex].fRelease) { ReleaseStgMedium(&m_Data[nIndex].StgMedium); } else { ZeroStruct(m_Data[nIndex].StgMedium); } } else { Assert((pMedium != &(m_Data[nIndex].StgMedium)) && (pMedium->hGlobal != &(m_Data[nIndex].StgMedium))); } } else // if (nIndex < 0) { DEBUGTEST(bNew = true); _ASSERTE(nIndex < 0); DragData newItem = {}; newItem.FormatEtc = *pFormatEtc; nIndex = m_Data.push_back(newItem); } m_Data[nIndex].fUsed = TRUE; m_Data[nIndex].fRelease = fRelease; m_Data[nIndex].StgMedium = *pMedium; return S_OK; }
// IDYES - Close All consoles // IDNO - Close active console only // IDCANCEL - As is int ConfirmCloseConsoles(const ConfirmCloseParam& Parm) { DontEnable de; wchar_t szText[512], *pszText; int nBtn = IDCANCEL; static LONG lCounter = 0; LONG l = InterlockedIncrement(&lCounter); if (l > 1) { if (l == 2) { _ASSERTE(FALSE && "Confirm stack overflow!"); } goto wrap; } if (Parm.rpLeaveConEmuOpened) *Parm.rpLeaveConEmuOpened = false; // Use TaskDialog? if (gOSVer.dwMajorVersion >= 6) { // must be already initialized: CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); wchar_t szMessage[128]; if (Parm.asSingleConsole) lstrcpyn(szMessage, Parm.asSingleConsole, countof(szMessage)); else if (Parm.bForceKill) wcscpy_c(szMessage, L"Confirm killing?"); else if (Parm.bGroup) wcscpy_c(szMessage, L"Confirm closing group?"); else wcscpy_c(szMessage, L"Confirm closing?"); wchar_t szWWW[MAX_PATH]; _wsprintf(szWWW, SKIPLEN(countof(szWWW)) L"<a href=\"%s\">%s</a>", gsHomePage, gsHomePage); wchar_t szCloseAll[MAX_PATH*2]; wchar_t *pszText; if (Parm.asSingleConsole) { wcscpy_c(szCloseAll, L"Yes\n"); pszText = szCloseAll + _tcslen(szCloseAll); lstrcpyn(pszText, Parm.asSingleTitle, min(MAX_PATH,(countof(szCloseAll)-(pszText-szCloseAll)))); pszText += _tcslen(pszText); } else { _wsprintf(szCloseAll, SKIPLEN(countof(szCloseAll)) (Parm.bGroup && (Parm.nConsoles>1)) ? ((Parm.bGroup == ConfirmCloseParam::eGroup) ? L"Close group (%u consoles)" : L"Close (%u consoles)") : (Parm.nConsoles>1) ? L"Close all %u consoles." : L"Close %u console.", Parm.nConsoles); pszText = szCloseAll + _tcslen(szCloseAll); } if ((Parm.asSingleConsole == NULL) || (Parm.nOperations || Parm.nUnsavedEditors)) { //if (nOperations) { _wsprintf(pszText, SKIPLEN(countof(szCloseAll)-(pszText-szCloseAll)) L"\nIncomplete operations: %i", Parm.nOperations); pszText += _tcslen(pszText); } //if (nUnsavedEditors) { _wsprintf(pszText, SKIPLEN(countof(szCloseAll)-(pszText-szCloseAll)) L"\nUnsaved editor windows: %i", Parm.nUnsavedEditors); pszText += _tcslen(pszText); } } wchar_t szCloseOne[MAX_PATH]; wcscpy_c(szCloseOne, L"Close active console only"); if (Parm.nConsoles > 1) { CVConGuard VCon; int iCon = gpConEmu->GetActiveVCon(&VCon); if (iCon >= 0) { pszText = szCloseOne + _tcslen(szCloseOne); _wsprintf(pszText, SKIPLEN(countof(szCloseOne)-(pszText-szCloseOne)) L"\n#%u: ", (iCon+1)); pszText += _tcslen(pszText); lstrcpyn(pszText, VCon->RCon()->GetTitle(true), countof(szCloseOne)-(pszText-szCloseOne)); } } const wchar_t* szCancel = L"Cancel\nDon't close anything"; int nButtonPressed = 0; TASKDIALOGCONFIG config = {sizeof(config)}; TASKDIALOG_BUTTON buttons[] = { { IDYES, szCloseAll }, { IDNO, szCloseOne }, { IDCANCEL, szCancel }, }; config.cButtons = countof(buttons); if (Parm.nConsoles <= 1) { buttons[1] = buttons[2]; config.cButtons--; } config.hwndParent = ghWnd; config.hInstance = NULL /*g_hInstance*/; config.dwFlags = TDF_USE_HICON_MAIN|TDF_USE_COMMAND_LINKS|TDF_ALLOW_DIALOG_CANCELLATION |TDF_ENABLE_HYPERLINKS; //|TDIF_SIZE_TO_CONTENT|TDF_CAN_BE_MINIMIZED; //config.pszMainIcon = MAKEINTRESOURCE(IDI_ICON1); config.hMainIcon = hClassIcon; config.pszWindowTitle = gpConEmu->GetDefaultTitle(); config.pszMainInstruction = szMessage; //config.pszContent = L"..."; config.pButtons = buttons; config.nDefaultButton = IDYES; config.pszFooter = szWWW; //{ // config.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED; // config.pszVerificationText = L"Text on checkbox"; //} HRESULT hr = TaskDialog(&config, &nButtonPressed, NULL, NULL); if (hr == S_OK) { switch (nButtonPressed) { case IDCANCEL: // user cancelled the dialog case IDYES: case IDNO: nBtn = nButtonPressed; goto wrap; default: _ASSERTE(nButtonPressed==IDCANCEL||nButtonPressed==IDYES||nButtonPressed==IDNO); break; // should never happen } } } // Иначе - через стандартный MessageBox if (Parm.asSingleConsole) { lstrcpyn(szText, Parm.asSingleConsole ? Parm.asSingleConsole : Parm.bForceKill ? L"Confirm killing?" : L"Confirm closing?", min(128,countof(szText))); wcscat_c(szText, L"\r\n\r\n"); int nLen = lstrlen(szText); lstrcpyn(szText+nLen, Parm.asSingleTitle, countof(szText)-nLen); } else { _wsprintf(szText, SKIPLEN(countof(szText)) L"About to close %u console%s.\r\n", Parm.nConsoles, (Parm.nConsoles>1)?L"s":L""); } pszText = szText+_tcslen(szText); if (Parm.nOperations || Parm.nUnsavedEditors) { *(pszText++) = L'\r'; *(pszText++) = L'\n'; *(pszText) = 0; if (Parm.nOperations) { _wsprintf(pszText, SKIPLEN(countof(szText)-(pszText-szText)) L"Incomplete operations: %i\r\n", Parm.nOperations); pszText += _tcslen(pszText); } if (Parm.nUnsavedEditors) { _wsprintf(pszText, SKIPLEN(countof(szText)-(pszText-szText)) L"Unsaved editor windows: %i\r\n", Parm.nUnsavedEditors); pszText += _tcslen(pszText); } } if (Parm.nConsoles > 1) { wcscat_c(szText, L"\r\nPress button <No> to close active console only\r\n" L"\r\nProceed with close ConEmu?"); } nBtn = MsgBox(szText, (/*rpPanes ? MB_OKCANCEL :*/ (Parm.nConsoles>1) ? MB_YESNOCANCEL : MB_OKCANCEL)|MB_ICONEXCLAMATION, gpConEmu->GetDefaultTitle(), ghWnd); if (nBtn == IDOK) { nBtn = IDYES; // для однозначности } wrap: InterlockedDecrement(&lCounter); return nBtn; }
bool CAttachDlg::CanAttachWindow(HWND hFind, DWORD nSkipPID, CProcessData* apProcessData, CAttachDlg::AttachWndInfo& Info) { static bool bIsWin64 = IsWindows64(); ZeroStruct(Info); DWORD_PTR nStyle = GetWindowLongPtr(hFind, GWL_STYLE); DWORD_PTR nStyleEx = GetWindowLongPtr(hFind, GWL_EXSTYLE); if (!GetWindowThreadProcessId(hFind, &Info.nPID)) Info.nPID = 0; if (!Info.nPID) return false; bool lbCan = ((nStyle & (WS_VISIBLE/*|WS_CAPTION|WS_MAXIMIZEBOX*/)) == (WS_VISIBLE/*|WS_CAPTION|WS_MAXIMIZEBOX*/)); if (lbCan) { // Более тщательно стили проверить lbCan = ((nStyle & WS_MAXIMIZEBOX) == WS_MAXIMIZEBOX) || ((nStyle & WS_THICKFRAME) == WS_THICKFRAME); } if (lbCan && Info.nPID == GetCurrentProcessId()) lbCan = false; if (lbCan && Info.nPID == nSkipPID) lbCan = false; if (lbCan && (nStyle & WS_CHILD)) lbCan = false; if (lbCan && (nStyleEx & WS_EX_TOOLWINDOW)) lbCan = false; if (lbCan && gpConEmu->isOurConsoleWindow(hFind)) lbCan = false; if (lbCan && gpConEmu->mp_Inside && (hFind == gpConEmu->mp_Inside->mh_InsideParentRoot)) lbCan = false; GetClassName(hFind, Info.szClass, countof(Info.szClass)); GetWindowText(hFind, Info.szTitle, countof(Info.szTitle)); if (gpSetCls->isAdvLogging) { wchar_t szLogInfo[MAX_PATH*3]; _wsprintf(szLogInfo, SKIPLEN(countof(szLogInfo)) L"Attach:%s x%08X/x%08X/x%08X {%s} \"%s\"", Info.szExeName, LODWORD(hFind), nStyle, nStyleEx, Info.szClass, Info.szTitle); CVConGroup::LogString(szLogInfo); } if (!lbCan) return false; _wsprintf(Info.szPid, SKIPLEN(countof(Info.szPid)) L"%u", Info.nPID); const wchar_t sz32bit[] = L" [32]"; const wchar_t sz64bit[] = L" [64]"; HANDLE h; DEBUGTEST(DWORD nErr); bool lbExeFound = false; if (apProcessData) { lbExeFound = apProcessData->GetProcessName(Info.nPID, Info.szExeName, countof(Info.szExeName), Info.szExePathName, countof(Info.szExePathName), &Info.nImageBits); if (lbExeFound) { //ListView_SetItemText(hList, nItem, alc_File, szExeName); //ListView_SetItemText(hList, nItem, alc_Path, szExePathName); if (bIsWin64 && Info.nImageBits) { wcscat_c(Info.szPid, (Info.nImageBits == 64) ? sz64bit : sz32bit); } } } if (!lbExeFound) { Info.nImageBits = GetProcessBits(Info.nPID); if (bIsWin64 && Info.nImageBits) { wcscat_c(Info.szPid, (Info.nImageBits == 64) ? sz64bit : sz32bit); } h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Info.nPID); if (h && h != INVALID_HANDLE_VALUE) { MODULEENTRY32 mi = {sizeof(mi)}; if (Module32First(h, &mi)) { lstrcpyn(Info.szExeName, *mi.szModule ? mi.szModule : (wchar_t*)PointToName(mi.szExePath), countof(Info.szExeName)); lstrcpyn(Info.szExePathName, mi.szExePath, countof(Info.szExePathName)); lbExeFound = true; } else { if (bIsWin64) { wcscat_c(Info.szPid, sz64bit); } } CloseHandle(h); } else { #ifdef _DEBUG nErr = GetLastError(); _ASSERTE(nErr == 5 || (nErr == 299 && Info.nImageBits == 64)); #endif wcscpy_c(Info.szExeName, L"???"); } #if 0 //#ifdef _WIN64 -- no need to call TH32CS_SNAPMODULE32, simple TH32CS_SNAPMODULE will handle both if it can if (!lbExeFound) { h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32, Info.nPID); if (h && h != INVALID_HANDLE_VALUE) { MODULEENTRY32 mi = {sizeof(mi)}; if (Module32First(h, &mi)) { //ListView_SetItemText(hList, nItem, alc_File, *mi.szModule ? mi.szModule : (wchar_t*)PointToName(mi.szExePath)); lstrcpyn(Info.szExeName, *mi.szModule ? mi.szModule : (wchar_t*)PointToName(mi.szExePath), countof(Info.szExeName)); //ListView_SetItemText(hList, nItem, alc_Path, mi.szExePath); lstrcpyn(Info.szExePathName, mi.szExePath, countof(Info.szExePathName)); } CloseHandle(h); } } #endif } if (!lbExeFound) { // Так можно получить только имя файла процесса PROCESSENTRY32 pi = {sizeof(pi)}; h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (h && h != INVALID_HANDLE_VALUE) { if (Process32First(h, &pi)) { do { if (pi.th32ProcessID == Info.nPID) { lstrcpyn(Info.szExeName, pi.szExeFile, countof(Info.szExeName)); break; } } while (Process32Next(h, &pi)); } } } wcscpy_c(Info.szType, isConsoleClass(Info.szClass) ? szTypeCon : szTypeGui); return true; }
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 FindConEmuBaseDir(wchar_t (&rsConEmuBaseDir)[MAX_PATH+1], wchar_t (&rsConEmuExe)[MAX_PATH+1], HMODULE hPluginDll /*= NULL*/) { // Сначала пробуем Mapping консоли (вдруг есть?) { MFileMapping<CESERVER_CONSOLE_MAPPING_HDR> ConMap; ConMap.InitName(CECONMAPNAME, (DWORD)myGetConsoleWindow()); //-V205 CESERVER_CONSOLE_MAPPING_HDR* p = ConMap.Open(); if (p && p->ComSpec.ConEmuBaseDir[0]) { // Успешно wcscpy_c(rsConEmuBaseDir, p->ComSpec.ConEmuBaseDir); wcscpy_c(rsConEmuExe, p->sConEmuExe); return TRUE; } } // Теперь - пробуем найти существующее окно ConEmu HWND hConEmu = FindWindow(VirtualConsoleClassMain, NULL); DWORD dwGuiPID = 0; if (hConEmu) { if (GetWindowThreadProcessId(hConEmu, &dwGuiPID) && dwGuiPID) { MFileMapping<ConEmuGuiMapping> GuiMap; GuiMap.InitName(CEGUIINFOMAPNAME, dwGuiPID); ConEmuGuiMapping* p = GuiMap.Open(); if (p && p->ComSpec.ConEmuBaseDir[0]) { wcscpy_c(rsConEmuBaseDir, p->ComSpec.ConEmuBaseDir); wcscpy_c(rsConEmuExe, p->sConEmuExe); return TRUE; } } } wchar_t szExePath[MAX_PATH+1]; HKEY hkRoot[] = {NULL,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_LOCAL_MACHINE}; DWORD samDesired = KEY_QUERY_VALUE; BOOL isWin64 = WIN3264TEST(IsWindows64(),TRUE); DWORD RedirectionFlag = WIN3264TEST((isWin64 ? KEY_WOW64_64KEY : 0),KEY_WOW64_32KEY); //#ifdef _WIN64 // isWin64 = TRUE; // RedirectionFlag = KEY_WOW64_32KEY; //#else // isWin64 = IsWindows64(); // RedirectionFlag = isWin64 ? KEY_WOW64_64KEY : 0; //#endif for (size_t i = 0; i < countof(hkRoot); i++) { szExePath[0] = 0; if (i == 0) { // Запущенного ConEmu.exe нет, можно поискать в каталоге текущего приложения if (!GetModuleFileName(NULL, szExePath, countof(szExePath)-20)) continue; wchar_t* pszName = wcsrchr(szExePath, L'\\'); if (!pszName) continue; *(pszName+1) = 0; // Проверяем наличие файлов // LPCWSTR szGuiExe[2] = {L"ConEmu64.exe", L"ConEmu.exe"}; if (!IsConEmuExeExist(szExePath, rsConEmuExe) && hPluginDll) { // Попробовать найти наш exe-шник от пути плагина? if (!GetModuleFileName(hPluginDll, szExePath, countof(szExePath)-1)) continue; wchar_t* pszName = wcsrchr(szExePath, L'\\'); if (!pszName) continue; *(pszName+1) = 0; int nLen = lstrlen(szExePath); LPCWSTR pszCompare = L"\\Plugins\\ConEmu\\"; if (nLen <= lstrlen(pszCompare)) continue; nLen = lstrlen(pszCompare); int iCmp = lstrcmpi(pszName-nLen+1, pszCompare); if (iCmp != 0) continue; *(pszName-nLen+2) = 0; } } else { // Остался последний шанс - если ConEmu установлен через MSI, то путь указан в реестре // [HKEY_LOCAL_MACHINE\SOFTWARE\ConEmu] // "InstallDir"="C:\\Utils\\Far180\\" if (i == (countof(hkRoot)-1)) { if (RedirectionFlag) samDesired |= RedirectionFlag; else break; } HKEY hKey; if (RegOpenKeyEx(hkRoot[i], L"Software\\ConEmu", 0, samDesired, &hKey) != ERROR_SUCCESS) continue; memset(szExePath, 0, countof(szExePath)); DWORD nType = 0, nSize = sizeof(szExePath)-20*sizeof(wchar_t); int RegResult = RegQueryValueEx(hKey, L"", NULL, &nType, (LPBYTE)szExePath, &nSize); RegCloseKey(hKey); if (RegResult != ERROR_SUCCESS) continue; } if (szExePath[0]) { // Хоть и задано в реестре - файлов может не быть. Проверяем if (szExePath[lstrlen(szExePath)-1] != L'\\') wcscat_c(szExePath, L"\\"); // Проверяем наличие файлов // LPCWSTR szGuiExe[2] = {L"ConEmu64.exe", L"ConEmu.exe"}; BOOL lbExeFound = IsConEmuExeExist(szExePath, rsConEmuExe); // Если GUI-exe найден - ищем "base" if (lbExeFound) { wchar_t* pszName = szExePath+lstrlen(szExePath); LPCWSTR szSrvExe[4] = {L"ConEmuC64.exe", L"ConEmu\\ConEmuC64.exe", L"ConEmuC.exe", L"ConEmu\\ConEmuC.exe"}; for (size_t s = 0; s < countof(szSrvExe); s++) { if ((s <=1) && !isWin64) continue; wcscpy_add(pszName, szExePath, szSrvExe[s]); if (FileExists(szExePath)) { pszName = wcsrchr(szExePath, L'\\'); if (pszName) { *pszName = 0; // БЕЗ слеша на конце! wcscpy_c(rsConEmuBaseDir, szExePath); return TRUE; } } } } } } // Не удалось return FALSE; }
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; }