diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /hammer/processwnd.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'hammer/processwnd.cpp')
| -rw-r--r-- | hammer/processwnd.cpp | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/hammer/processwnd.cpp b/hammer/processwnd.cpp new file mode 100644 index 0000000..e8110fe --- /dev/null +++ b/hammer/processwnd.cpp @@ -0,0 +1,313 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#include "stdafx.h" +#include <wincon.h> +#include "hammer.h" +#include "ProcessWnd.h" +#include "osver.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + + +#define IDC_PROCESSWND_EDIT 1 +#define IDC_PROCESSWND_COPYALL 2 + + +LPCTSTR GetErrorString(); + + +CProcessWnd::CProcessWnd() +{ + Font.CreatePointFont(100, "Courier New"); +} + +CProcessWnd::~CProcessWnd() +{ +} + + +BEGIN_MESSAGE_MAP(CProcessWnd, CWnd) + ON_BN_CLICKED(IDC_PROCESSWND_COPYALL, OnCopyAll) + //{{AFX_MSG_MAP(CProcessWnd) + ON_BN_CLICKED(IDC_PROCESSWND_COPYALL, OnCopyAll) + ON_WM_TIMER() + ON_WM_CREATE() + ON_WM_SIZE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CProcessWnd operations + +int CProcessWnd::Execute(LPCTSTR pszCmd, ...) +{ + CString strBuf; + + va_list vl; + va_start(vl, pszCmd); + + while(1) + { + char *p = va_arg(vl, char*); + if(!p) + break; + strBuf += p; + strBuf += " "; + } + + va_end(vl); + + return Execute(pszCmd, (LPCTSTR)strBuf); +} + +void CProcessWnd::Clear() +{ + m_EditText.Empty(); + Edit.SetWindowText(""); + Edit.RedrawWindow(); +} + +void CProcessWnd::Append(CString str) +{ + m_EditText += str; + if (getOSVersion() >= eWinNT) + { + Edit.SetWindowText(m_EditText); + } + else + { + DWORD length = m_EditText.GetLength() / sizeof(TCHAR); + + // Gracefully handle 64k edit control display on win9x (display last 64k of text) + // Copy to clipboard will work fine, as it copies the m_EditText contents + // in its entirety to the clipboard + if (length >= 0x0FFFF) + { + LPTSTR string = m_EditText.GetBuffer(length + 1); + LPTSTR offset; + offset = string + length - 0x0FFFF; + Edit.SetWindowText(offset); + m_EditText.ReleaseBuffer(); + } + else + { + Edit.SetWindowText(m_EditText); + } + } + Edit.LineScroll(Edit.GetLineCount()); + Edit.RedrawWindow(); +} + +int CProcessWnd::Execute(LPCTSTR pszCmd, LPCTSTR pszCmdLine) +{ + int rval = -1; + SECURITY_ATTRIBUTES saAttr; + HANDLE hChildStdinRd_, hChildStdinWr, hChildStdoutRd_, hChildStdoutWr, hChildStderrWr; + + // Set the bInheritHandle flag so pipe handles are inherited. + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + // Create a pipe for the child's STDOUT. + if(CreatePipe(&hChildStdoutRd_, &hChildStdoutWr, &saAttr, 0)) + { + if(CreatePipe(&hChildStdinRd_, &hChildStdinWr, &saAttr, 0)) + { + if (DuplicateHandle(GetCurrentProcess(),hChildStdoutWr, GetCurrentProcess(),&hChildStderrWr,0, TRUE,DUPLICATE_SAME_ACCESS)) + { + /* Now create the child process. */ + STARTUPINFO si; + memset(&si, 0, sizeof si); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = hChildStdinRd_; + si.hStdError = hChildStderrWr; + si.hStdOutput = hChildStdoutWr; + PROCESS_INFORMATION pi; + CString str; + str.Format("%s %s", pszCmd, pszCmdLine); + if (CreateProcess(NULL, (char*) LPCTSTR(str), NULL, NULL, TRUE, + DETACHED_PROCESS, NULL, NULL, &si, &pi)) + { + HANDLE hProcess = pi.hProcess; + +#define BUFFER_SIZE 4096 + // read from pipe.. + char buffer[BUFFER_SIZE]; + BOOL bDone = FALSE; + + while(1) + { + DWORD dwCount = 0; + DWORD dwRead = 0; + + // read from input handle + PeekNamedPipe( hChildStdoutRd_, NULL, NULL, NULL, &dwCount, NULL); + if (dwCount) + { + dwCount = min (dwCount, (DWORD)BUFFER_SIZE - 1); + ReadFile( hChildStdoutRd_, buffer, dwCount, &dwRead, NULL); + } + if(dwRead) + { + buffer[dwRead] = 0; + Append(buffer); + } + // check process termination + else if(WaitForSingleObject(hProcess, 1000) != WAIT_TIMEOUT) + { + if(bDone) + break; + bDone = TRUE; // next time we get it + } + } + rval = 0; + } + else + { + SetForegroundWindow(); + CString strTmp; + strTmp.Format("* Could not execute the command:\r\n %s\r\n", str.GetBuffer()); + Append(strTmp); + strTmp.Format("* Windows gave the error message:\r\n \"%s\"\r\n", GetErrorString()); + Append(strTmp); + } + + CloseHandle(hChildStderrWr); + } + CloseHandle(hChildStdinRd_); + CloseHandle(hChildStdinWr); + } + CloseHandle(hChildStdoutRd_); + CloseHandle(hChildStdoutWr); + } + + return rval; +} + +///////////////////////////////////////////////////////////////////////////// +// CProcessWnd message handlers + + +void CProcessWnd::OnTimer(UINT nIDEvent) +{ + CWnd::OnTimer(nIDEvent); +} + +int CProcessWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + // create big CEdit in window + CRect rctClient; + GetClientRect(rctClient); + + CRect rctEdit; + rctEdit = rctClient; + rctEdit.bottom = rctClient.bottom - 20; + + Edit.Create(WS_CHILD | WS_BORDER | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN, rctClient, this, IDC_PROCESSWND_EDIT); + Edit.SetReadOnly(TRUE); + Edit.SetFont(&Font); + + CRect rctButton; + rctButton = rctClient; + rctButton.top = rctClient.bottom - 20; + + m_btnCopyAll.Create("Copy to Clipboard", WS_CHILD | WS_VISIBLE, rctButton, this, IDC_PROCESSWND_COPYALL); + m_btnCopyAll.SetButtonStyle(BS_PUSHBUTTON); + + return 0; +} + +void CProcessWnd::OnSize(UINT nType, int cx, int cy) +{ + CWnd::OnSize(nType, cx, cy); + + // create big CEdit in window + CRect rctClient; + GetClientRect(rctClient); + + CRect rctEdit; + rctEdit = rctClient; + rctEdit.bottom = rctClient.bottom - 20; + Edit.MoveWindow(rctEdit); + + CRect rctButton; + rctButton = rctClient; + rctButton.top = rctClient.bottom - 20; + m_btnCopyAll.MoveWindow(rctButton); +} + + +//----------------------------------------------------------------------------- +// Purpose: Prepare the process window for display. If it has not been created +// yet, register the class and create it. +//----------------------------------------------------------------------------- +void CProcessWnd::GetReady(void) +{ + if (!IsWindow(m_hWnd)) + { + CString strClass = AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW), HBRUSH(GetStockObject(WHITE_BRUSH))); + CreateEx(0, strClass, "Compile Process Window", WS_OVERLAPPEDWINDOW, 50, 50, 600, 400, AfxGetMainWnd()->GetSafeHwnd(), HMENU(NULL)); + } + + ShowWindow(SW_SHOW); + SetActiveWindow(); + Clear(); +} + +BOOL CProcessWnd::PreTranslateMessage(MSG* pMsg) +{ + // The edit control won't get keyboard commands from the window without this (at least in Win2k) + // The right mouse context menu still will not work in w2k for some reason either, although + // it is getting the CONTEXTMENU message (as seen in Spy++) + ::TranslateMessage(pMsg); + ::DispatchMessage(pMsg); + return TRUE; +} + +static void CopyToClipboard(const CString& text) +{ + if (OpenClipboard(NULL)) + { + if (EmptyClipboard()) + { + HGLOBAL hglbCopy; + LPTSTR tstrCopy; + + hglbCopy = GlobalAlloc(GMEM_DDESHARE, text.GetLength() + sizeof(TCHAR) ); + + if (hglbCopy != NULL) + { + tstrCopy = (LPTSTR) GlobalLock(hglbCopy); + strcpy(tstrCopy, (LPCTSTR)text); + GlobalUnlock(hglbCopy); + + SetClipboardData(CF_TEXT, hglbCopy); + } + } + CloseClipboard(); + } +} + +void CProcessWnd::OnCopyAll() +{ + // Used to call m_Edit.SetSel(0,1); m_Edit.Copy(); m_Edit.Clear() + // but in win9x the clipboard will only receive at most 64k of text from the control + CopyToClipboard(m_EditText); +} |