1006 lines
31 KiB
C++
1006 lines
31 KiB
C++
|
|
// watcherView.cpp : implementation of the View class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "watcher.h"
|
|
#include "watcherDoc.h"
|
|
#include "watcherView.h"
|
|
#include "WatcherTelnetClient.h"
|
|
#include "WatcherTCClient.h"
|
|
#include "tcsrvc.h"
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
#include <wbemidl.h>
|
|
#include "wbemDCpl.h"
|
|
|
|
#define CHECKERROR(HRES) if(FAILED(hres)) {_stprintf(buffer,_T("0x%x"),hres);\
|
|
AfxFormatString1(rString, CREATE_WMI_OBJECT_FAILURE, buffer);\
|
|
MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION);\
|
|
delete [] messageBuffer;\
|
|
return -1;\
|
|
}
|
|
|
|
UINT
|
|
GenerateWMIEvent(LPTSTR messageBuffer
|
|
)
|
|
{
|
|
|
|
TCHAR buffer[MAX_BUFFER_SIZE];
|
|
CString rString;
|
|
HRESULT hres;
|
|
|
|
hres = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
|
|
CHECKERROR(hres);
|
|
|
|
// Load provision code
|
|
|
|
IWbemDecoupledEventSink* pConnection = NULL;
|
|
hres = CoCreateInstance(CLSID_PseudoSink, NULL, CLSCTX_SERVER,
|
|
IID_IWbemDecoupledEventSink, (void**)&pConnection);
|
|
CHECKERROR(hres);
|
|
|
|
// Connect and announce provider name (as in MOF)
|
|
|
|
IWbemObjectSink* pSink = NULL;
|
|
IWbemServices* pNamespace = NULL;
|
|
hres = pConnection->Connect(L"root\\default", L"WatcherEventProv",
|
|
0, &pSink, &pNamespace);
|
|
CHECKERROR(hres);
|
|
|
|
BSTR XMLData = SysAllocString(messageBuffer);
|
|
IWbemObjectTextSrc *pSrc;
|
|
IWbemClassObject *pInstance;
|
|
|
|
|
|
if( SUCCEEDED( hres = CoCreateInstance ( CLSID_WbemObjectTextSrc, NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWbemObjectTextSrc,
|
|
(void**) &pSrc ) ) ) {
|
|
if( SUCCEEDED( hres = pSrc->CreateFromText( 0, XMLData, WMI_OBJ_TEXT_WMI_DTD_2_0,
|
|
NULL, &pInstance) ) ) {
|
|
pSink->Indicate(1,&pInstance);
|
|
pInstance->Release();
|
|
}
|
|
else{
|
|
_stprintf(buffer,_T("0x%x"),hres);
|
|
AfxFormatString1(rString, CREATE_WMI_OBJECT_FAILURE, buffer);
|
|
MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION);
|
|
pSrc->Release();
|
|
}
|
|
}
|
|
else{
|
|
_stprintf(buffer,_T("0x%x"),hres);
|
|
AfxFormatString1(rString, CREATE_TEXT_SRC_FAILURE, buffer);
|
|
MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION);
|
|
}
|
|
SysFreeString(XMLData);
|
|
|
|
// Init data
|
|
|
|
pConnection->Disconnect();
|
|
pSink->Release();
|
|
pConnection->Release();
|
|
MessageBox(NULL,messageBuffer,L"",MB_OK|MB_ICONEXCLAMATION);
|
|
delete [] messageBuffer;
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWatcherView
|
|
|
|
IMPLEMENT_DYNCREATE(CWatcherView, CView)
|
|
|
|
BEGIN_MESSAGE_MAP(CWatcherView, CView)
|
|
//{{AFX_MSG_MAP(CWatcherView)
|
|
ON_WM_CHAR()
|
|
ON_WM_DESTROY()
|
|
ON_WM_KEYDOWN()
|
|
//}}AFX_MSG_MAP
|
|
// Standard printing commands
|
|
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
|
|
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
|
|
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWatcherView construction/destruction
|
|
|
|
CWatcherView::CWatcherView()
|
|
:xpos(0),
|
|
ypos(0),
|
|
CharsInLine(0),
|
|
height(0),
|
|
width(0),
|
|
position(0),
|
|
index(0),
|
|
#ifdef _UNICODE
|
|
dbcsIndex(0),
|
|
#endif
|
|
InEscape(FALSE),
|
|
Socket(NULL),
|
|
cdc(NULL),
|
|
background(BLACK),
|
|
foreground(WHITE),
|
|
indexBell(0),
|
|
BellStarted(FALSE),
|
|
InBell(FALSE),
|
|
ScrollTop(1),
|
|
ScrollBottom(MAX_TERMINAL_HEIGHT),
|
|
seenM(FALSE)
|
|
{
|
|
// TODO: add construction code here
|
|
InitializeCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
|
|
CWatcherView::~CWatcherView()
|
|
{
|
|
DeleteCriticalSection(&mutex);
|
|
}
|
|
|
|
BOOL CWatcherView::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
// TODO: Modify the Window class or styles here by modifying
|
|
// the CREATESTRUCT cs
|
|
|
|
return CView::PreCreateWindow(cs);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWatcherView drawing
|
|
|
|
void CWatcherView::OnDraw(CDC* pDC)
|
|
{
|
|
TCHAR *Data,Char;
|
|
int i,j, Height;
|
|
int CharWidth, Position;
|
|
int size;
|
|
BOOL ret;
|
|
COLORREF *Foreground;
|
|
COLORREF *Background;
|
|
|
|
CWatcherDoc* pDoc = GetDocument();
|
|
ASSERT_VALID(pDoc);
|
|
// TODO: add draw code for native data here
|
|
ret = pDoc->Lock();
|
|
if (ret == FALSE) return;
|
|
Data = pDoc->GetData();
|
|
size = MAX_TERMINAL_WIDTH*MAX_TERMINAL_HEIGHT;
|
|
Background = pDoc->GetBackground();
|
|
Foreground = pDoc->GetForeground();
|
|
Height = 0;
|
|
|
|
for(i=0;i<size;i+=MAX_TERMINAL_WIDTH){
|
|
Position = 0;
|
|
for(j=0;j<MAX_TERMINAL_WIDTH;j++){
|
|
Char = Data[i + j];
|
|
cdc->SetTextColor(Foreground[i+j]);
|
|
cdc->SetBkColor(Background[i+j]);
|
|
|
|
if (!cdc->GetOutputCharWidth(Char, Char, &CharWidth)) {
|
|
return;
|
|
}
|
|
|
|
if(Char == 0xFFFF){
|
|
continue;
|
|
}
|
|
if(IsPrintable(Char)){
|
|
cdc->FillSolidRect(Position,Height,CharWidth,
|
|
height,Background[i+j]);
|
|
cdc->TextOut(Position, Height,&Char, 1);
|
|
Position = Position + CharWidth;
|
|
}
|
|
else{
|
|
cdc->FillSolidRect(Position,Height,width,
|
|
height,Background[i+j]);
|
|
Position = Position + width;
|
|
}
|
|
}
|
|
cdc->FillSolidRect(Position,Height, MAX_TERMINAL_WIDTH*width-Position,
|
|
height,Background[i+j-1]);
|
|
Height = Height + height;
|
|
}
|
|
ret = pDoc->Unlock();
|
|
return;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWatcherView initial update of the document.
|
|
void CWatcherView::OnInitialUpdate()
|
|
{
|
|
BOOL ret;
|
|
TCHAR Buffer[256];
|
|
CLIENT_INFO SendInfo;
|
|
CFont font;
|
|
UCHAR Charset;
|
|
LPBYTE SocketBuffer;
|
|
CString rString;
|
|
|
|
ParameterDialog &Params=((CWatcherDoc *)GetDocument())->GetParameters();
|
|
|
|
if(Params.DeleteValue == TRUE){
|
|
ret = GetParent()->PostMessage(WM_CLOSE,0,0);
|
|
return;
|
|
}
|
|
|
|
CString FaceName;
|
|
switch(Params.language + IDS_ENGLISH){
|
|
case IDS_ENGLISH:
|
|
CodePage = ENGLISH;
|
|
Charset = ANSI_CHARSET;
|
|
FaceName = TEXT("Courier New");
|
|
break;
|
|
case IDS_JAPANESE:
|
|
CodePage = JAPANESE;
|
|
Charset = SHIFTJIS_CHARSET;
|
|
// Locale = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL),
|
|
// SORT_JAPANESE_UNICODE);
|
|
// SetThreadLocale(Locale);
|
|
FaceName = TEXT("MS Mincho");
|
|
break;
|
|
case IDS_EUROPEAN:
|
|
CodePage = EUROPEAN;
|
|
Charset = EASTEUROPE_CHARSET;
|
|
FaceName = TEXT("Courier New");
|
|
break;
|
|
default:
|
|
CodePage = ENGLISH;
|
|
Charset = ANSI_CHARSET;
|
|
FaceName = TEXT("Courier New");
|
|
break;
|
|
}
|
|
|
|
VERIFY(font.CreateFont(16, // nHeight
|
|
0, // nWidth
|
|
0, // nEscapement
|
|
0, // nOrientation
|
|
FW_MEDIUM, // nWeight
|
|
FALSE, // bItalic
|
|
FALSE, // bUnderline
|
|
0, // cStrikeOut
|
|
Charset, // nCharSet
|
|
OUT_DEFAULT_PRECIS, // nOutPrecision
|
|
CLIP_DEFAULT_PRECIS, // nClipPrecision
|
|
DEFAULT_QUALITY, // nQuality
|
|
FIXED_PITCH | FF_MODERN, // nPitchAndFamily
|
|
FaceName)); // lpszFacename
|
|
cdc = new CClientDC(this);
|
|
if(!cdc){
|
|
ret = GetParent()->PostMessage(WM_CLOSE,0,0);
|
|
return;
|
|
}
|
|
cdc->SelectObject(&font);
|
|
CDocument *pDoc = GetDocument();
|
|
if(pDoc){
|
|
pDoc->SetTitle(Params.Session);
|
|
pDoc->UpdateAllViews(NULL,0,NULL);
|
|
}
|
|
// Now create the socket and start the worker thread
|
|
if(Params.tcclnt){
|
|
// Assuming Unicode always....... (Can remove a lot of other junk)
|
|
_tcscpy(SendInfo.device, (LPCTSTR) Params.Command);
|
|
SendInfo.len = Params.history;
|
|
int strsize = sizeof(CLIENT_INFO);
|
|
SocketBuffer = new BYTE[strsize];
|
|
SocketBuffer = (LPBYTE) ::memcpy(SocketBuffer,&SendInfo, strsize);
|
|
Socket = new WatcherTCClient(SocketBuffer,strsize);
|
|
if(!SocketBuffer || !Socket){
|
|
AfxFormatString1(rString, CREATE_TC_SOCKET_FAILURE, L"");
|
|
MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP);
|
|
ret = GetParent()->PostMessage(WM_CLOSE,0,0);
|
|
return;
|
|
}
|
|
}
|
|
else{
|
|
LPBYTE LoginBuffer;
|
|
int strsize,cmdsize;
|
|
CString login;
|
|
CString comm;
|
|
login = Params.LoginName + _TEXT("\r\n") + Params.LoginPasswd + _TEXT("\r\n");
|
|
strsize = ::_tcslen((LPCTSTR) login);
|
|
LoginBuffer = new BYTE [strsize*sizeof(TCHAR) + 2];
|
|
strsize = WideCharToMultiByte(CodePage,0,(LPCTSTR)login,strsize,
|
|
(LPSTR) LoginBuffer,strsize*sizeof(TCHAR),NULL,NULL);
|
|
comm = Params.Command + _TEXT("\r\n");
|
|
cmdsize = ::_tcslen((LPCTSTR) comm);
|
|
SocketBuffer = new BYTE [cmdsize*sizeof(TCHAR) + 2];
|
|
cmdsize = WideCharToMultiByte(CodePage,0,(LPCTSTR) comm,cmdsize,
|
|
(LPSTR) SocketBuffer,cmdsize*sizeof(TCHAR),NULL,NULL);
|
|
Socket = new WatcherTelnetClient(SocketBuffer,cmdsize,LoginBuffer,strsize);
|
|
if(!Socket || !LoginBuffer || !SocketBuffer
|
|
|| !cmdsize || !strsize){
|
|
AfxFormatString1(rString, CREATE_TELNET_SOCKET_FAILURE, L"");
|
|
MessageBox((LPCTSTR) rString, L"Watcher",MB_OK|MB_ICONSTOP);
|
|
ret = GetParent()->PostMessage(WM_CLOSE,0,0);
|
|
return;
|
|
}
|
|
}
|
|
ASSERT ( Socket != NULL );
|
|
Socket->SetParentView(this);
|
|
TEXTMETRIC TextProps;
|
|
ret = cdc->GetOutputTextMetrics(&TextProps);
|
|
if(!ret){
|
|
_stprintf(Buffer, _T("%d"),GetLastError());
|
|
AfxFormatString1(rString, CDC_TEXT_FAILURE, Buffer);
|
|
MessageBox((LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONSTOP);
|
|
ret = GetParent()->PostMessage(WM_CLOSE,0,0);
|
|
return;
|
|
}
|
|
height = TextProps.tmHeight + 1;
|
|
width = (TextProps.tmAveCharWidth);
|
|
CWnd *parent = GetParent();
|
|
if(!parent){
|
|
// this is an orphan child window
|
|
return;
|
|
}
|
|
CRect wrect, crect;
|
|
parent->GetClientRect(&crect);
|
|
parent->GetWindowRect(&wrect);
|
|
wrect.SetRect(0,
|
|
0,
|
|
wrect.Width() - crect.Width() + width*MAX_TERMINAL_WIDTH,
|
|
wrect.Height() - crect.Height() + height*MAX_TERMINAL_HEIGHT
|
|
);
|
|
parent->MoveWindow(&wrect,TRUE);
|
|
parent->GetClientRect(&crect);
|
|
|
|
ret =Socket->Create(0,SOCK_STREAM,NULL);
|
|
if(!ret){
|
|
_stprintf(Buffer,_T("%d"),GetLastError());
|
|
AfxFormatString1(rString, SOCKET_CREATION_FAILED, Buffer);
|
|
MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP);
|
|
ret = parent->PostMessage(WM_CLOSE,0,0);
|
|
return;
|
|
}
|
|
position = 0;
|
|
|
|
|
|
ret = Socket->Connect((LPCTSTR) Params.Machine,Params.Port);
|
|
if (!ret){
|
|
_stprintf(Buffer,_T("%d"),GetLastError());
|
|
AfxFormatString1(rString, SOCKET_CONNECTION_FAILED, (LPCTSTR) Buffer);
|
|
MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP);
|
|
ret = parent->PostMessage(WM_CLOSE,0,0);
|
|
return;
|
|
}
|
|
if(Params.tcclnt){
|
|
ret = Socket->Send(SocketBuffer,sizeof(CLIENT_INFO),0);
|
|
}
|
|
CView::OnInitialUpdate();
|
|
|
|
if(cdc){
|
|
OnDraw(cdc);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWatcherView diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CWatcherView::AssertValid() const
|
|
{
|
|
CView::AssertValid();
|
|
}
|
|
|
|
void CWatcherView::Dump(CDumpContext& dc) const
|
|
{
|
|
CView::Dump(dc);
|
|
}
|
|
|
|
CWatcherDoc* CWatcherView::GetDocument() // non-debug version is inline
|
|
{
|
|
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWatcherDoc)));
|
|
return (CWatcherDoc*)m_pDocument;
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWatcherView message handlers
|
|
|
|
void CWatcherView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
// We will send the character across the network and that is all we do.
|
|
int nRet;
|
|
|
|
nRet=Socket->Send(&nChar, 1, 0);
|
|
//CView::OnChar(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
|
|
|
|
|
|
// REMARK - should we make this also a virtual function so that
|
|
// if bell sequences are to be trapped, you just need to
|
|
// extend this class ??
|
|
void CWatcherView::ProcessByte(BYTE byte)
|
|
{
|
|
//Currently, just do a textout on the device
|
|
// Store the character in the screen buffer
|
|
// A boolean variable to check if we are processing an escape sequence
|
|
|
|
EnterCriticalSection(&mutex);
|
|
|
|
if(byte == 27){
|
|
InEscape = TRUE;
|
|
EscapeBuffer[0] = byte;
|
|
index = 1;
|
|
LeaveCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
// Escape characters are not found in the characters sent across the
|
|
// wire. Similarly, when we enter the Bell protocol, no bells can
|
|
// be found.
|
|
if(InEscape == TRUE){
|
|
if(index == MAX_TERMINAL_WIDTH){
|
|
// vague escape sequence,give up processing
|
|
InEscape = FALSE;
|
|
index=0;
|
|
LeaveCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
EscapeBuffer[index]=byte;
|
|
index++;
|
|
if(FinalCharacter((CHAR) byte)){
|
|
ProcessEscapeSequence((PCHAR)EscapeBuffer, index);
|
|
InEscape = FALSE;
|
|
index=0;
|
|
}
|
|
LeaveCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
if(InBell == TRUE){
|
|
if(indexBell > MAX_BELL_SIZE){
|
|
// What a bell sequence, I give up....
|
|
InBell = FALSE;
|
|
// Print all that stuff onto the screen
|
|
for(int i = 0; i<indexBell; i++){
|
|
PrintCharacter(BellBuffer[i]);
|
|
}
|
|
LeaveCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
// We are processing a bell seequnce.
|
|
if(indexBell < 10){
|
|
BellBuffer[indexBell] = byte;
|
|
indexBell ++;
|
|
if(strncmp((const char *)BellBuffer,"\007\007\007<?xml>\007",indexBell) == 0){
|
|
if(indexBell == 9){
|
|
BellStarted = TRUE;
|
|
}
|
|
}else{
|
|
InBell = FALSE;
|
|
for(int i = 0; i<indexBell; i++){
|
|
PrintCharacter(BellBuffer[i]);
|
|
}
|
|
}
|
|
}else{
|
|
BellBuffer[indexBell] = byte;
|
|
indexBell++;
|
|
if(BellBuffer[indexBell-1] == 0x07){
|
|
// ok, end reached, go on.
|
|
InBell = FALSE;
|
|
BellStarted = FALSE;
|
|
ProcessBellSequence((char * )BellBuffer, indexBell);
|
|
indexBell = 0;
|
|
}
|
|
}
|
|
LeaveCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
if(byte == 0x07){
|
|
// We got a bell
|
|
// start looking for the bell protocol
|
|
InEscape = FALSE;
|
|
BellStarted = FALSE;
|
|
InBell = TRUE;
|
|
BellBuffer[0] = byte;
|
|
indexBell = 1;
|
|
LeaveCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
|
|
if (byte == '\017' && seenM) {
|
|
seenM=FALSE;
|
|
LeaveCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
seenM=FALSE;
|
|
PrintCharacter(byte);
|
|
LeaveCriticalSection(&mutex);
|
|
return;
|
|
}
|
|
|
|
void CWatcherView::PrintCharacter(BYTE byte)
|
|
{
|
|
|
|
TCHAR Char;
|
|
int CharWidth;
|
|
CWatcherDoc *pDoc;
|
|
BOOL ret;
|
|
LPTSTR DataLine;
|
|
|
|
pDoc = (CWatcherDoc *)GetDocument();
|
|
if(!pDoc){
|
|
// something really fatal.
|
|
return;
|
|
}
|
|
if(byte == 10){
|
|
ypos++;
|
|
if((ypos == MAX_TERMINAL_HEIGHT) || (ypos == ScrollBottom)){
|
|
ret = pDoc->Lock();
|
|
if (ypos == ScrollBottom) {
|
|
pDoc->ScrollData(0,foreground,background,ScrollTop,ScrollBottom);
|
|
}
|
|
else{
|
|
pDoc->ScrollData(0,foreground,background,1,MAX_TERMINAL_HEIGHT);
|
|
}
|
|
ypos = ypos -1;
|
|
ret = pDoc->Unlock();
|
|
OnDraw(cdc);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if(byte == 13){
|
|
xpos = 0;
|
|
position = 0;
|
|
return;
|
|
}
|
|
|
|
if (byte == 0x8) {
|
|
// backspace character.
|
|
ret = pDoc->Lock();
|
|
if(xpos>0){
|
|
xpos--;
|
|
pDoc->SetData(xpos, ypos, 0,
|
|
foreground, background);
|
|
DataLine = pDoc->GetDataLine(ypos);
|
|
position = 0;
|
|
if (xpos > 0){
|
|
position = GetTextWidth(DataLine, xpos);
|
|
}
|
|
}
|
|
ret = pDoc->Unlock();
|
|
OnDraw(cdc);
|
|
return;
|
|
}
|
|
|
|
Char = byte;
|
|
#ifdef _UNICODE
|
|
DBCSArray[dbcsIndex] = byte;
|
|
if(dbcsIndex ==0){
|
|
if(IsDBCSLeadByteEx(CodePage, byte)){
|
|
dbcsIndex ++;
|
|
return;
|
|
}
|
|
}
|
|
else{
|
|
MultiByteToWideChar(CodePage,0,(const char *)DBCSArray,2,&Char,1);
|
|
dbcsIndex = 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
if(xpos >= MAX_TERMINAL_WIDTH){
|
|
//Before moving over to the next line clear to end of display
|
|
// using the current background
|
|
if(cdc){
|
|
cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width-position,
|
|
height,background);
|
|
}
|
|
xpos = 0;
|
|
position = 0;
|
|
ypos++;
|
|
if((ypos == MAX_TERMINAL_HEIGHT) || (ypos == ScrollBottom)){
|
|
ret = pDoc->Lock();
|
|
if (ypos == ScrollBottom) {
|
|
pDoc->ScrollData(0,foreground,background,ScrollTop,ScrollBottom);
|
|
}
|
|
else{
|
|
pDoc->ScrollData(0,foreground,background,1,MAX_TERMINAL_HEIGHT);
|
|
}
|
|
ypos = ypos -1;
|
|
ret = pDoc->Unlock();
|
|
OnDraw(cdc);
|
|
}
|
|
}
|
|
|
|
ret =cdc->GetOutputCharWidth(Char, Char, &CharWidth);
|
|
|
|
if(IsPrintable(Char)){
|
|
cdc->FillSolidRect(position,ypos*height,CharWidth,
|
|
height,background);
|
|
cdc->TextOut(position,ypos*height,&Char, 1);
|
|
position = position + CharWidth;
|
|
if (CharWidth >= 2*width){
|
|
ret = pDoc->Lock();
|
|
pDoc->SetData(xpos, ypos, 0xFFFF, foreground, background);
|
|
xpos++;
|
|
ret = pDoc->Unlock();
|
|
}
|
|
}
|
|
else{
|
|
cdc->FillSolidRect(position,ypos*height,width,
|
|
height,background);
|
|
position = position + width;
|
|
}
|
|
ret = pDoc->Lock();
|
|
pDoc->SetData(xpos, ypos, Char,
|
|
foreground, background);
|
|
xpos++;
|
|
ret = pDoc->Unlock();
|
|
|
|
}
|
|
|
|
|
|
void CWatcherView::ProcessEscapeSequence(PCHAR Buffer, int length)
|
|
{
|
|
|
|
ULONG charsToWrite;
|
|
ULONG charsWritten;
|
|
TCHAR *DataLine;
|
|
CWatcherDoc *pDoc;
|
|
BOOL ret;
|
|
|
|
pDoc = (CWatcherDoc *) GetDocument();
|
|
if(!pDoc){
|
|
// something really wrong, queitly ignore this
|
|
// escape sequence
|
|
return;
|
|
}
|
|
|
|
if (length == 3) {
|
|
// One of the home cursor or clear to end of display
|
|
if(strncmp(Buffer,"\033[r",length)==0){
|
|
ScrollTop = 1;
|
|
ScrollBottom = MAX_TERMINAL_HEIGHT;
|
|
return;
|
|
}
|
|
if (strncmp(Buffer,"\033[H",length)==0) {
|
|
// Home the cursor
|
|
xpos = 0;
|
|
ypos = 0;
|
|
position = 0;
|
|
return;
|
|
}
|
|
if(strncmp(Buffer,"\033[J", length) == 0){
|
|
// clear to end of display assuming 80 X 24 size
|
|
ret = pDoc->Lock();
|
|
if(cdc){
|
|
cdc->FillSolidRect(0,(ypos+1)*height,MAX_TERMINAL_WIDTH*width,
|
|
(MAX_TERMINAL_HEIGHT-ypos)*height,background);
|
|
cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width - position,
|
|
height,background);
|
|
}
|
|
pDoc->SetData(xpos, ypos, 0,
|
|
(MAX_TERMINAL_HEIGHT - ypos)*MAX_TERMINAL_WIDTH -xpos,
|
|
foreground, background);
|
|
ret = pDoc->Unlock();
|
|
}
|
|
if(strncmp(Buffer,"\033[K", length) == 0){
|
|
// clear to end of line assuming 80 X 24 size
|
|
if(cdc){
|
|
cdc->FillSolidRect(position,ypos*height,MAX_TERMINAL_WIDTH*width - position,
|
|
height,background);
|
|
}
|
|
ret = pDoc->Lock();
|
|
pDoc->SetData(xpos, ypos, 0,
|
|
MAX_TERMINAL_WIDTH -xpos, foreground, background);
|
|
ret = pDoc->Unlock();
|
|
return;
|
|
}
|
|
if(strncmp(Buffer,"\033[m", length) == 0){
|
|
// clear all attributes and set Text attributes to black on white
|
|
background = BLACK;
|
|
foreground = WHITE;
|
|
seenM = TRUE;
|
|
if(cdc){
|
|
cdc->SetBkColor(background);
|
|
cdc->SetTextColor(foreground);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if (length == 4) {
|
|
// One of the home cursor or clear to end of display
|
|
if (strncmp(Buffer,"\033[0H",length)==0) {
|
|
// Home the cursor
|
|
xpos = 0;
|
|
ypos = 0;
|
|
position = 0;
|
|
return;
|
|
}
|
|
|
|
if(strncmp(Buffer,"\033[2J",length) == 0){
|
|
xpos = 0;
|
|
ypos = 0;
|
|
position =0;
|
|
sprintf(Buffer,"\033[0J");
|
|
}
|
|
|
|
if(strncmp(Buffer,"\033[0J", length) == 0){
|
|
// clear to end of display assuming 80 X 24 size
|
|
if (IsWindowEnabled()){
|
|
cdc->FillSolidRect(0,(ypos+1)*height,MAX_TERMINAL_WIDTH*width,
|
|
(MAX_TERMINAL_HEIGHT-ypos)*height,background);
|
|
cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width - position,
|
|
height,background);
|
|
}
|
|
ret = pDoc->Lock();
|
|
pDoc->SetData(xpos, ypos, 0,
|
|
(MAX_TERMINAL_HEIGHT - ypos)*MAX_TERMINAL_WIDTH -xpos,
|
|
foreground, background);
|
|
ret = pDoc->Unlock();
|
|
}
|
|
if((strncmp(Buffer,"\033[0K", length) == 0) ||
|
|
(strncmp(Buffer,"\033[2K",length) == 0)){
|
|
// clear to end of line assuming 80 X 24 size
|
|
if(cdc){
|
|
cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width-position,
|
|
height,background);
|
|
}
|
|
ret = pDoc->Lock();
|
|
pDoc->SetData(xpos, ypos, 0,
|
|
MAX_TERMINAL_WIDTH -xpos, foreground, background);
|
|
ret = pDoc->Unlock();
|
|
return;
|
|
}
|
|
if((strncmp(Buffer,"\033[0m", length) == 0)||
|
|
(strncmp(Buffer,"\033[m\017", length) == 0)){
|
|
// clear all attributes and set Text attributes to black on white
|
|
background = BLACK;
|
|
foreground = WHITE;
|
|
if(cdc){
|
|
cdc->SetBkColor(background);
|
|
cdc->SetTextColor(foreground);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if(Buffer[length-1] == 'm'){
|
|
//set the text attributes
|
|
// clear all attributes and set Text attributes to black on white
|
|
ProcessTextAttributes((PCHAR) Buffer, length);
|
|
return;
|
|
}
|
|
|
|
if(Buffer[length -1] == 'r'){
|
|
if (sscanf(Buffer,"\033[%d;%dr", &charsToWrite, &charsWritten) == 2) {
|
|
ScrollTop = (SHORT)charsToWrite;
|
|
ScrollBottom = (SHORT)charsWritten;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if(Buffer[length -1] == 'H'){
|
|
if (sscanf(Buffer,"\033[%d;%dH", &charsToWrite, &charsWritten) == 2) {
|
|
ypos = (SHORT)(charsToWrite -1);
|
|
xpos = (SHORT)(charsWritten -1);
|
|
ret = pDoc->Lock();
|
|
DataLine = pDoc->GetDataLine(ypos);
|
|
if (xpos >0){
|
|
position = GetTextWidth(DataLine, xpos);
|
|
}
|
|
else{
|
|
position = 0;
|
|
}
|
|
pDoc->Unlock();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void CWatcherView::ProcessTextAttributes(PCHAR Buffer, int length)
|
|
{
|
|
|
|
PCHAR CurrLoc = Buffer;
|
|
ULONG Attribute;
|
|
PCHAR pTemp;
|
|
COLORREF temp;
|
|
|
|
while(*CurrLoc != 'm'){
|
|
if((*CurrLoc < '0') || (*CurrLoc >'9' )){
|
|
CurrLoc ++;
|
|
}else{
|
|
if (sscanf(CurrLoc,"%d", &Attribute) != 1) {
|
|
return;
|
|
}
|
|
switch(Attribute){
|
|
case 7:
|
|
// switch the colors. This will make this code
|
|
// work for applications (written in an Unix world
|
|
// for real VT100. )
|
|
temp = foreground;
|
|
foreground = background;
|
|
background = temp;
|
|
break;
|
|
case 37:
|
|
foreground = WHITE;
|
|
break;
|
|
case 47:
|
|
background = WHITE;
|
|
break;
|
|
case 34:
|
|
foreground = BLUE;
|
|
break;
|
|
case 44:
|
|
background = BLUE;
|
|
break;
|
|
case 30:
|
|
foreground = BLACK;
|
|
break;
|
|
case 40:
|
|
background = BLACK;
|
|
case 33:
|
|
foreground = YELLOW;
|
|
break;
|
|
case 43:
|
|
background = YELLOW;
|
|
case 31:
|
|
foreground = RED;
|
|
break;
|
|
case 41:
|
|
background = RED;
|
|
default:
|
|
break;
|
|
}
|
|
pTemp = strchr(CurrLoc, ';');
|
|
if(pTemp == NULL){
|
|
pTemp = strchr(CurrLoc, 'm');
|
|
}
|
|
if(pTemp == NULL) {
|
|
break;
|
|
}
|
|
CurrLoc = pTemp;
|
|
|
|
}
|
|
}
|
|
cdc->SetBkColor(background);
|
|
cdc->SetTextColor(foreground);
|
|
return;
|
|
}
|
|
|
|
BOOL CWatcherView::FinalCharacter(CHAR c)
|
|
{
|
|
|
|
CHAR FinalCharacters[]="mHJKr";
|
|
|
|
if(strchr(FinalCharacters,c)){
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
BOOL CWatcherView::IsPrintable(TCHAR Char)
|
|
{
|
|
if (Char > 32) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void CWatcherView::OnDestroy()
|
|
{
|
|
if(Socket){
|
|
delete Socket;
|
|
}
|
|
if(cdc){
|
|
delete cdc;
|
|
}
|
|
CView::OnDestroy();
|
|
|
|
// TODO: Add your message handler code here
|
|
|
|
}
|
|
|
|
int CWatcherView::GetTextWidth(TCHAR *Data, int number)
|
|
{
|
|
int textWidth=0;
|
|
int CharWidth;
|
|
|
|
for(int i=0;i<number;i++){
|
|
// For variable width characters like Japanese, we need to
|
|
// blank out the next character.
|
|
if(Data[i] == 0xFFFF){
|
|
continue;
|
|
}
|
|
if(IsPrintable(Data[i])){
|
|
if (cdc->GetOutputCharWidth(Data[i], Data[i], &CharWidth)) {
|
|
textWidth += CharWidth;
|
|
}
|
|
}
|
|
else{
|
|
textWidth += width;
|
|
}
|
|
}
|
|
return textWidth;
|
|
|
|
}
|
|
// REMARK - Make this a virtual function so that
|
|
// later writers can just extend this class and work
|
|
// with the same framework. Now, the bell sequence
|
|
// processing consists of nothing, but later can be
|
|
// expanded to include WMI kind of processing.
|
|
void CWatcherView::ProcessBellSequence(CHAR *Buffer, int len)
|
|
{
|
|
// Set this as the active window.
|
|
// We will probably bring up a dialog box with
|
|
// the bell parameters.
|
|
|
|
WCHAR *messageBuffer;
|
|
CHAR tempBuffer[MAX_BELL_SIZE + 1];
|
|
int index =0;
|
|
|
|
memset(tempBuffer,0, MAX_BELL_SIZE + 1);
|
|
memcpy(tempBuffer, Buffer+16, len-24);
|
|
tempBuffer[len-24] = (CHAR) 0;
|
|
|
|
CWnd *parent = GetParent();
|
|
CWnd *prev = parent->GetParent();
|
|
if (prev && prev->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))){
|
|
((CMDIFrameWnd *) prev)->MDIActivate(parent);
|
|
((CMDIFrameWnd *) prev)->MDIRestore(parent);
|
|
}
|
|
else{
|
|
((CMDIChildWnd *)parent)->MDIActivate();
|
|
((CMDIChildWnd *)parent)->MDIRestore();
|
|
}
|
|
int convlen;
|
|
messageBuffer = new WCHAR [MAX_BELL_SIZE + 1];
|
|
messageBuffer[0] = 0;
|
|
convlen = MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
tempBuffer,
|
|
-1,
|
|
messageBuffer,
|
|
MAX_BELL_SIZE);
|
|
messageBuffer[convlen] = (WCHAR) 0;
|
|
CWinThread *th = ::AfxBeginThread(AFX_THREADPROC (GenerateWMIEvent),
|
|
messageBuffer
|
|
);
|
|
return;
|
|
}
|
|
|
|
void CWatcherView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
switch(nChar) {
|
|
case VK_LEFT:
|
|
Socket->Send("\033OC",sizeof("\033OC"),0);
|
|
break;
|
|
case VK_RIGHT:
|
|
Socket->Send("\033OD",sizeof("\033OD"),0);
|
|
break;
|
|
case VK_UP:
|
|
Socket->Send("\033OA",sizeof("\033OA"),0);
|
|
break;
|
|
case VK_DOWN:
|
|
Socket->Send("\033OB",sizeof("\033OB"),0);
|
|
break;
|
|
case VK_F1:
|
|
Socket->Send("\033""1",sizeof("\033""1"),0);
|
|
break;
|
|
case VK_F2:
|
|
Socket->Send("\033""2",sizeof("\033""2"),0);
|
|
break;
|
|
case VK_F3:
|
|
Socket->Send("\033""3",sizeof("\033""3"),0);
|
|
break;
|
|
case VK_F4:
|
|
Socket->Send("\033""4",sizeof("\033""4"),0);
|
|
break;
|
|
case VK_F12:
|
|
Socket->Send("\033@",sizeof("\033@"),0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
CView::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|