Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1005 lines
31 KiB

  1. // watcherView.cpp : implementation of the View class
  2. //
  3. #include "stdafx.h"
  4. #include "watcher.h"
  5. #include "watcherDoc.h"
  6. #include "watcherView.h"
  7. #include "WatcherTelnetClient.h"
  8. #include "WatcherTCClient.h"
  9. #include "tcsrvc.h"
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. #include <wbemidl.h>
  16. #include "wbemDCpl.h"
  17. #define CHECKERROR(HRES) if(FAILED(hres)) {_stprintf(buffer,_T("0x%x"),hres);\
  18. AfxFormatString1(rString, CREATE_WMI_OBJECT_FAILURE, buffer);\
  19. MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION);\
  20. delete [] messageBuffer;\
  21. return -1;\
  22. }
  23. UINT
  24. GenerateWMIEvent(LPTSTR messageBuffer
  25. )
  26. {
  27. TCHAR buffer[MAX_BUFFER_SIZE];
  28. CString rString;
  29. HRESULT hres;
  30. hres = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  31. CHECKERROR(hres);
  32. // Load provision code
  33. IWbemDecoupledEventSink* pConnection = NULL;
  34. hres = CoCreateInstance(CLSID_PseudoSink, NULL, CLSCTX_SERVER,
  35. IID_IWbemDecoupledEventSink, (void**)&pConnection);
  36. CHECKERROR(hres);
  37. // Connect and announce provider name (as in MOF)
  38. IWbemObjectSink* pSink = NULL;
  39. IWbemServices* pNamespace = NULL;
  40. hres = pConnection->Connect(L"root\\default", L"WatcherEventProv",
  41. 0, &pSink, &pNamespace);
  42. CHECKERROR(hres);
  43. BSTR XMLData = SysAllocString(messageBuffer);
  44. IWbemObjectTextSrc *pSrc;
  45. IWbemClassObject *pInstance;
  46. if( SUCCEEDED( hres = CoCreateInstance ( CLSID_WbemObjectTextSrc, NULL,
  47. CLSCTX_INPROC_SERVER,
  48. IID_IWbemObjectTextSrc,
  49. (void**) &pSrc ) ) ) {
  50. if( SUCCEEDED( hres = pSrc->CreateFromText( 0, XMLData, WMI_OBJ_TEXT_WMI_DTD_2_0,
  51. NULL, &pInstance) ) ) {
  52. pSink->Indicate(1,&pInstance);
  53. pInstance->Release();
  54. }
  55. else{
  56. _stprintf(buffer,_T("0x%x"),hres);
  57. AfxFormatString1(rString, CREATE_WMI_OBJECT_FAILURE, buffer);
  58. MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION);
  59. pSrc->Release();
  60. }
  61. }
  62. else{
  63. _stprintf(buffer,_T("0x%x"),hres);
  64. AfxFormatString1(rString, CREATE_TEXT_SRC_FAILURE, buffer);
  65. MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION);
  66. }
  67. SysFreeString(XMLData);
  68. // Init data
  69. pConnection->Disconnect();
  70. pSink->Release();
  71. pConnection->Release();
  72. MessageBox(NULL,messageBuffer,L"",MB_OK|MB_ICONEXCLAMATION);
  73. delete [] messageBuffer;
  74. return 0;
  75. }
  76. /////////////////////////////////////////////////////////////////////////////
  77. // CWatcherView
  78. IMPLEMENT_DYNCREATE(CWatcherView, CView)
  79. BEGIN_MESSAGE_MAP(CWatcherView, CView)
  80. //{{AFX_MSG_MAP(CWatcherView)
  81. ON_WM_CHAR()
  82. ON_WM_DESTROY()
  83. ON_WM_KEYDOWN()
  84. //}}AFX_MSG_MAP
  85. // Standard printing commands
  86. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  87. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  88. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  89. END_MESSAGE_MAP()
  90. /////////////////////////////////////////////////////////////////////////////
  91. // CWatcherView construction/destruction
  92. CWatcherView::CWatcherView()
  93. :xpos(0),
  94. ypos(0),
  95. CharsInLine(0),
  96. height(0),
  97. width(0),
  98. position(0),
  99. index(0),
  100. #ifdef _UNICODE
  101. dbcsIndex(0),
  102. #endif
  103. InEscape(FALSE),
  104. Socket(NULL),
  105. cdc(NULL),
  106. background(BLACK),
  107. foreground(WHITE),
  108. indexBell(0),
  109. BellStarted(FALSE),
  110. InBell(FALSE),
  111. ScrollTop(1),
  112. ScrollBottom(MAX_TERMINAL_HEIGHT),
  113. seenM(FALSE)
  114. {
  115. // TODO: add construction code here
  116. InitializeCriticalSection(&mutex);
  117. return;
  118. }
  119. CWatcherView::~CWatcherView()
  120. {
  121. DeleteCriticalSection(&mutex);
  122. }
  123. BOOL CWatcherView::PreCreateWindow(CREATESTRUCT& cs)
  124. {
  125. // TODO: Modify the Window class or styles here by modifying
  126. // the CREATESTRUCT cs
  127. return CView::PreCreateWindow(cs);
  128. }
  129. /////////////////////////////////////////////////////////////////////////////
  130. // CWatcherView drawing
  131. void CWatcherView::OnDraw(CDC* pDC)
  132. {
  133. TCHAR *Data,Char;
  134. int i,j, Height;
  135. int CharWidth, Position;
  136. int size;
  137. BOOL ret;
  138. COLORREF *Foreground;
  139. COLORREF *Background;
  140. CWatcherDoc* pDoc = GetDocument();
  141. ASSERT_VALID(pDoc);
  142. // TODO: add draw code for native data here
  143. ret = pDoc->Lock();
  144. if (ret == FALSE) return;
  145. Data = pDoc->GetData();
  146. size = MAX_TERMINAL_WIDTH*MAX_TERMINAL_HEIGHT;
  147. Background = pDoc->GetBackground();
  148. Foreground = pDoc->GetForeground();
  149. Height = 0;
  150. for(i=0;i<size;i+=MAX_TERMINAL_WIDTH){
  151. Position = 0;
  152. for(j=0;j<MAX_TERMINAL_WIDTH;j++){
  153. Char = Data[i + j];
  154. cdc->SetTextColor(Foreground[i+j]);
  155. cdc->SetBkColor(Background[i+j]);
  156. if (!cdc->GetOutputCharWidth(Char, Char, &CharWidth)) {
  157. return;
  158. }
  159. if(Char == 0xFFFF){
  160. continue;
  161. }
  162. if(IsPrintable(Char)){
  163. cdc->FillSolidRect(Position,Height,CharWidth,
  164. height,Background[i+j]);
  165. cdc->TextOut(Position, Height,&Char, 1);
  166. Position = Position + CharWidth;
  167. }
  168. else{
  169. cdc->FillSolidRect(Position,Height,width,
  170. height,Background[i+j]);
  171. Position = Position + width;
  172. }
  173. }
  174. cdc->FillSolidRect(Position,Height, MAX_TERMINAL_WIDTH*width-Position,
  175. height,Background[i+j-1]);
  176. Height = Height + height;
  177. }
  178. ret = pDoc->Unlock();
  179. return;
  180. }
  181. /////////////////////////////////////////////////////////////////////////////
  182. // CWatcherView initial update of the document.
  183. void CWatcherView::OnInitialUpdate()
  184. {
  185. BOOL ret;
  186. TCHAR Buffer[256];
  187. CLIENT_INFO SendInfo;
  188. CFont font;
  189. UCHAR Charset;
  190. LPBYTE SocketBuffer;
  191. CString rString;
  192. ParameterDialog &Params=((CWatcherDoc *)GetDocument())->GetParameters();
  193. if(Params.DeleteValue == TRUE){
  194. ret = GetParent()->PostMessage(WM_CLOSE,0,0);
  195. return;
  196. }
  197. CString FaceName;
  198. switch(Params.language + IDS_ENGLISH){
  199. case IDS_ENGLISH:
  200. CodePage = ENGLISH;
  201. Charset = ANSI_CHARSET;
  202. FaceName = TEXT("Courier New");
  203. break;
  204. case IDS_JAPANESE:
  205. CodePage = JAPANESE;
  206. Charset = SHIFTJIS_CHARSET;
  207. // Locale = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL),
  208. // SORT_JAPANESE_UNICODE);
  209. // SetThreadLocale(Locale);
  210. FaceName = TEXT("MS Mincho");
  211. break;
  212. case IDS_EUROPEAN:
  213. CodePage = EUROPEAN;
  214. Charset = EASTEUROPE_CHARSET;
  215. FaceName = TEXT("Courier New");
  216. break;
  217. default:
  218. CodePage = ENGLISH;
  219. Charset = ANSI_CHARSET;
  220. FaceName = TEXT("Courier New");
  221. break;
  222. }
  223. VERIFY(font.CreateFont(16, // nHeight
  224. 0, // nWidth
  225. 0, // nEscapement
  226. 0, // nOrientation
  227. FW_MEDIUM, // nWeight
  228. FALSE, // bItalic
  229. FALSE, // bUnderline
  230. 0, // cStrikeOut
  231. Charset, // nCharSet
  232. OUT_DEFAULT_PRECIS, // nOutPrecision
  233. CLIP_DEFAULT_PRECIS, // nClipPrecision
  234. DEFAULT_QUALITY, // nQuality
  235. FIXED_PITCH | FF_MODERN, // nPitchAndFamily
  236. FaceName)); // lpszFacename
  237. cdc = new CClientDC(this);
  238. if(!cdc){
  239. ret = GetParent()->PostMessage(WM_CLOSE,0,0);
  240. return;
  241. }
  242. cdc->SelectObject(&font);
  243. CDocument *pDoc = GetDocument();
  244. if(pDoc){
  245. pDoc->SetTitle(Params.Session);
  246. pDoc->UpdateAllViews(NULL,0,NULL);
  247. }
  248. // Now create the socket and start the worker thread
  249. if(Params.tcclnt){
  250. // Assuming Unicode always....... (Can remove a lot of other junk)
  251. _tcscpy(SendInfo.device, (LPCTSTR) Params.Command);
  252. SendInfo.len = Params.history;
  253. int strsize = sizeof(CLIENT_INFO);
  254. SocketBuffer = new BYTE[strsize];
  255. SocketBuffer = (LPBYTE) ::memcpy(SocketBuffer,&SendInfo, strsize);
  256. Socket = new WatcherTCClient(SocketBuffer,strsize);
  257. if(!SocketBuffer || !Socket){
  258. AfxFormatString1(rString, CREATE_TC_SOCKET_FAILURE, L"");
  259. MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP);
  260. ret = GetParent()->PostMessage(WM_CLOSE,0,0);
  261. return;
  262. }
  263. }
  264. else{
  265. LPBYTE LoginBuffer;
  266. int strsize,cmdsize;
  267. CString login;
  268. CString comm;
  269. login = Params.LoginName + _TEXT("\r\n") + Params.LoginPasswd + _TEXT("\r\n");
  270. strsize = ::_tcslen((LPCTSTR) login);
  271. LoginBuffer = new BYTE [strsize*sizeof(TCHAR) + 2];
  272. strsize = WideCharToMultiByte(CodePage,0,(LPCTSTR)login,strsize,
  273. (LPSTR) LoginBuffer,strsize*sizeof(TCHAR),NULL,NULL);
  274. comm = Params.Command + _TEXT("\r\n");
  275. cmdsize = ::_tcslen((LPCTSTR) comm);
  276. SocketBuffer = new BYTE [cmdsize*sizeof(TCHAR) + 2];
  277. cmdsize = WideCharToMultiByte(CodePage,0,(LPCTSTR) comm,cmdsize,
  278. (LPSTR) SocketBuffer,cmdsize*sizeof(TCHAR),NULL,NULL);
  279. Socket = new WatcherTelnetClient(SocketBuffer,cmdsize,LoginBuffer,strsize);
  280. if(!Socket || !LoginBuffer || !SocketBuffer
  281. || !cmdsize || !strsize){
  282. AfxFormatString1(rString, CREATE_TELNET_SOCKET_FAILURE, L"");
  283. MessageBox((LPCTSTR) rString, L"Watcher",MB_OK|MB_ICONSTOP);
  284. ret = GetParent()->PostMessage(WM_CLOSE,0,0);
  285. return;
  286. }
  287. }
  288. ASSERT ( Socket != NULL );
  289. Socket->SetParentView(this);
  290. TEXTMETRIC TextProps;
  291. ret = cdc->GetOutputTextMetrics(&TextProps);
  292. if(!ret){
  293. _stprintf(Buffer, _T("%d"),GetLastError());
  294. AfxFormatString1(rString, CDC_TEXT_FAILURE, Buffer);
  295. MessageBox((LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONSTOP);
  296. ret = GetParent()->PostMessage(WM_CLOSE,0,0);
  297. return;
  298. }
  299. height = TextProps.tmHeight + 1;
  300. width = (TextProps.tmAveCharWidth);
  301. CWnd *parent = GetParent();
  302. if(!parent){
  303. // this is an orphan child window
  304. return;
  305. }
  306. CRect wrect, crect;
  307. parent->GetClientRect(&crect);
  308. parent->GetWindowRect(&wrect);
  309. wrect.SetRect(0,
  310. 0,
  311. wrect.Width() - crect.Width() + width*MAX_TERMINAL_WIDTH,
  312. wrect.Height() - crect.Height() + height*MAX_TERMINAL_HEIGHT
  313. );
  314. parent->MoveWindow(&wrect,TRUE);
  315. parent->GetClientRect(&crect);
  316. ret =Socket->Create(0,SOCK_STREAM,NULL);
  317. if(!ret){
  318. _stprintf(Buffer,_T("%d"),GetLastError());
  319. AfxFormatString1(rString, SOCKET_CREATION_FAILED, Buffer);
  320. MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP);
  321. ret = parent->PostMessage(WM_CLOSE,0,0);
  322. return;
  323. }
  324. position = 0;
  325. ret = Socket->Connect((LPCTSTR) Params.Machine,Params.Port);
  326. if (!ret){
  327. _stprintf(Buffer,_T("%d"),GetLastError());
  328. AfxFormatString1(rString, SOCKET_CONNECTION_FAILED, (LPCTSTR) Buffer);
  329. MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP);
  330. ret = parent->PostMessage(WM_CLOSE,0,0);
  331. return;
  332. }
  333. if(Params.tcclnt){
  334. ret = Socket->Send(SocketBuffer,sizeof(CLIENT_INFO),0);
  335. }
  336. CView::OnInitialUpdate();
  337. if(cdc){
  338. OnDraw(cdc);
  339. }
  340. return;
  341. }
  342. /////////////////////////////////////////////////////////////////////////////
  343. // CWatcherView diagnostics
  344. #ifdef _DEBUG
  345. void CWatcherView::AssertValid() const
  346. {
  347. CView::AssertValid();
  348. }
  349. void CWatcherView::Dump(CDumpContext& dc) const
  350. {
  351. CView::Dump(dc);
  352. }
  353. CWatcherDoc* CWatcherView::GetDocument() // non-debug version is inline
  354. {
  355. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWatcherDoc)));
  356. return (CWatcherDoc*)m_pDocument;
  357. }
  358. #endif //_DEBUG
  359. /////////////////////////////////////////////////////////////////////////////
  360. // CWatcherView message handlers
  361. void CWatcherView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  362. {
  363. // TODO: Add your message handler code here and/or call default
  364. // We will send the character across the network and that is all we do.
  365. int nRet;
  366. nRet=Socket->Send(&nChar, 1, 0);
  367. //CView::OnChar(nChar, nRepCnt, nFlags);
  368. }
  369. // REMARK - should we make this also a virtual function so that
  370. // if bell sequences are to be trapped, you just need to
  371. // extend this class ??
  372. void CWatcherView::ProcessByte(BYTE byte)
  373. {
  374. //Currently, just do a textout on the device
  375. // Store the character in the screen buffer
  376. // A boolean variable to check if we are processing an escape sequence
  377. EnterCriticalSection(&mutex);
  378. if(byte == 27){
  379. InEscape = TRUE;
  380. EscapeBuffer[0] = byte;
  381. index = 1;
  382. LeaveCriticalSection(&mutex);
  383. return;
  384. }
  385. // Escape characters are not found in the characters sent across the
  386. // wire. Similarly, when we enter the Bell protocol, no bells can
  387. // be found.
  388. if(InEscape == TRUE){
  389. if(index == MAX_TERMINAL_WIDTH){
  390. // vague escape sequence,give up processing
  391. InEscape = FALSE;
  392. index=0;
  393. LeaveCriticalSection(&mutex);
  394. return;
  395. }
  396. EscapeBuffer[index]=byte;
  397. index++;
  398. if(FinalCharacter((CHAR) byte)){
  399. ProcessEscapeSequence((PCHAR)EscapeBuffer, index);
  400. InEscape = FALSE;
  401. index=0;
  402. }
  403. LeaveCriticalSection(&mutex);
  404. return;
  405. }
  406. if(InBell == TRUE){
  407. if(indexBell > MAX_BELL_SIZE){
  408. // What a bell sequence, I give up....
  409. InBell = FALSE;
  410. // Print all that stuff onto the screen
  411. for(int i = 0; i<indexBell; i++){
  412. PrintCharacter(BellBuffer[i]);
  413. }
  414. LeaveCriticalSection(&mutex);
  415. return;
  416. }
  417. // We are processing a bell seequnce.
  418. if(indexBell < 10){
  419. BellBuffer[indexBell] = byte;
  420. indexBell ++;
  421. if(strncmp((const char *)BellBuffer,"\007\007\007<?xml>\007",indexBell) == 0){
  422. if(indexBell == 9){
  423. BellStarted = TRUE;
  424. }
  425. }else{
  426. InBell = FALSE;
  427. for(int i = 0; i<indexBell; i++){
  428. PrintCharacter(BellBuffer[i]);
  429. }
  430. }
  431. }else{
  432. BellBuffer[indexBell] = byte;
  433. indexBell++;
  434. if(BellBuffer[indexBell-1] == 0x07){
  435. // ok, end reached, go on.
  436. InBell = FALSE;
  437. BellStarted = FALSE;
  438. ProcessBellSequence((char * )BellBuffer, indexBell);
  439. indexBell = 0;
  440. }
  441. }
  442. LeaveCriticalSection(&mutex);
  443. return;
  444. }
  445. if(byte == 0x07){
  446. // We got a bell
  447. // start looking for the bell protocol
  448. InEscape = FALSE;
  449. BellStarted = FALSE;
  450. InBell = TRUE;
  451. BellBuffer[0] = byte;
  452. indexBell = 1;
  453. LeaveCriticalSection(&mutex);
  454. return;
  455. }
  456. if (byte == '\017' && seenM) {
  457. seenM=FALSE;
  458. LeaveCriticalSection(&mutex);
  459. return;
  460. }
  461. seenM=FALSE;
  462. PrintCharacter(byte);
  463. LeaveCriticalSection(&mutex);
  464. return;
  465. }
  466. void CWatcherView::PrintCharacter(BYTE byte)
  467. {
  468. TCHAR Char;
  469. int CharWidth;
  470. CWatcherDoc *pDoc;
  471. BOOL ret;
  472. LPTSTR DataLine;
  473. pDoc = (CWatcherDoc *)GetDocument();
  474. if(!pDoc){
  475. // something really fatal.
  476. return;
  477. }
  478. if(byte == 10){
  479. ypos++;
  480. if((ypos == MAX_TERMINAL_HEIGHT) || (ypos == ScrollBottom)){
  481. ret = pDoc->Lock();
  482. if (ypos == ScrollBottom) {
  483. pDoc->ScrollData(0,foreground,background,ScrollTop,ScrollBottom);
  484. }
  485. else{
  486. pDoc->ScrollData(0,foreground,background,1,MAX_TERMINAL_HEIGHT);
  487. }
  488. ypos = ypos -1;
  489. ret = pDoc->Unlock();
  490. OnDraw(cdc);
  491. }
  492. return;
  493. }
  494. if(byte == 13){
  495. xpos = 0;
  496. position = 0;
  497. return;
  498. }
  499. if (byte == 0x8) {
  500. // backspace character.
  501. ret = pDoc->Lock();
  502. if(xpos>0){
  503. xpos--;
  504. pDoc->SetData(xpos, ypos, 0,
  505. foreground, background);
  506. DataLine = pDoc->GetDataLine(ypos);
  507. position = 0;
  508. if (xpos > 0){
  509. position = GetTextWidth(DataLine, xpos);
  510. }
  511. }
  512. ret = pDoc->Unlock();
  513. OnDraw(cdc);
  514. return;
  515. }
  516. Char = byte;
  517. #ifdef _UNICODE
  518. DBCSArray[dbcsIndex] = byte;
  519. if(dbcsIndex ==0){
  520. if(IsDBCSLeadByteEx(CodePage, byte)){
  521. dbcsIndex ++;
  522. return;
  523. }
  524. }
  525. else{
  526. MultiByteToWideChar(CodePage,0,(const char *)DBCSArray,2,&Char,1);
  527. dbcsIndex = 0;
  528. }
  529. #endif
  530. if(xpos >= MAX_TERMINAL_WIDTH){
  531. //Before moving over to the next line clear to end of display
  532. // using the current background
  533. if(cdc){
  534. cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width-position,
  535. height,background);
  536. }
  537. xpos = 0;
  538. position = 0;
  539. ypos++;
  540. if((ypos == MAX_TERMINAL_HEIGHT) || (ypos == ScrollBottom)){
  541. ret = pDoc->Lock();
  542. if (ypos == ScrollBottom) {
  543. pDoc->ScrollData(0,foreground,background,ScrollTop,ScrollBottom);
  544. }
  545. else{
  546. pDoc->ScrollData(0,foreground,background,1,MAX_TERMINAL_HEIGHT);
  547. }
  548. ypos = ypos -1;
  549. ret = pDoc->Unlock();
  550. OnDraw(cdc);
  551. }
  552. }
  553. ret =cdc->GetOutputCharWidth(Char, Char, &CharWidth);
  554. if(IsPrintable(Char)){
  555. cdc->FillSolidRect(position,ypos*height,CharWidth,
  556. height,background);
  557. cdc->TextOut(position,ypos*height,&Char, 1);
  558. position = position + CharWidth;
  559. if (CharWidth >= 2*width){
  560. ret = pDoc->Lock();
  561. pDoc->SetData(xpos, ypos, 0xFFFF, foreground, background);
  562. xpos++;
  563. ret = pDoc->Unlock();
  564. }
  565. }
  566. else{
  567. cdc->FillSolidRect(position,ypos*height,width,
  568. height,background);
  569. position = position + width;
  570. }
  571. ret = pDoc->Lock();
  572. pDoc->SetData(xpos, ypos, Char,
  573. foreground, background);
  574. xpos++;
  575. ret = pDoc->Unlock();
  576. }
  577. void CWatcherView::ProcessEscapeSequence(PCHAR Buffer, int length)
  578. {
  579. ULONG charsToWrite;
  580. ULONG charsWritten;
  581. TCHAR *DataLine;
  582. CWatcherDoc *pDoc;
  583. BOOL ret;
  584. pDoc = (CWatcherDoc *) GetDocument();
  585. if(!pDoc){
  586. // something really wrong, queitly ignore this
  587. // escape sequence
  588. return;
  589. }
  590. if (length == 3) {
  591. // One of the home cursor or clear to end of display
  592. if(strncmp(Buffer,"\033[r",length)==0){
  593. ScrollTop = 1;
  594. ScrollBottom = MAX_TERMINAL_HEIGHT;
  595. return;
  596. }
  597. if (strncmp(Buffer,"\033[H",length)==0) {
  598. // Home the cursor
  599. xpos = 0;
  600. ypos = 0;
  601. position = 0;
  602. return;
  603. }
  604. if(strncmp(Buffer,"\033[J", length) == 0){
  605. // clear to end of display assuming 80 X 24 size
  606. ret = pDoc->Lock();
  607. if(cdc){
  608. cdc->FillSolidRect(0,(ypos+1)*height,MAX_TERMINAL_WIDTH*width,
  609. (MAX_TERMINAL_HEIGHT-ypos)*height,background);
  610. cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width - position,
  611. height,background);
  612. }
  613. pDoc->SetData(xpos, ypos, 0,
  614. (MAX_TERMINAL_HEIGHT - ypos)*MAX_TERMINAL_WIDTH -xpos,
  615. foreground, background);
  616. ret = pDoc->Unlock();
  617. }
  618. if(strncmp(Buffer,"\033[K", length) == 0){
  619. // clear to end of line assuming 80 X 24 size
  620. if(cdc){
  621. cdc->FillSolidRect(position,ypos*height,MAX_TERMINAL_WIDTH*width - position,
  622. height,background);
  623. }
  624. ret = pDoc->Lock();
  625. pDoc->SetData(xpos, ypos, 0,
  626. MAX_TERMINAL_WIDTH -xpos, foreground, background);
  627. ret = pDoc->Unlock();
  628. return;
  629. }
  630. if(strncmp(Buffer,"\033[m", length) == 0){
  631. // clear all attributes and set Text attributes to black on white
  632. background = BLACK;
  633. foreground = WHITE;
  634. seenM = TRUE;
  635. if(cdc){
  636. cdc->SetBkColor(background);
  637. cdc->SetTextColor(foreground);
  638. }
  639. return;
  640. }
  641. }
  642. if (length == 4) {
  643. // One of the home cursor or clear to end of display
  644. if (strncmp(Buffer,"\033[0H",length)==0) {
  645. // Home the cursor
  646. xpos = 0;
  647. ypos = 0;
  648. position = 0;
  649. return;
  650. }
  651. if(strncmp(Buffer,"\033[2J",length) == 0){
  652. xpos = 0;
  653. ypos = 0;
  654. position =0;
  655. sprintf(Buffer,"\033[0J");
  656. }
  657. if(strncmp(Buffer,"\033[0J", length) == 0){
  658. // clear to end of display assuming 80 X 24 size
  659. if (IsWindowEnabled()){
  660. cdc->FillSolidRect(0,(ypos+1)*height,MAX_TERMINAL_WIDTH*width,
  661. (MAX_TERMINAL_HEIGHT-ypos)*height,background);
  662. cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width - position,
  663. height,background);
  664. }
  665. ret = pDoc->Lock();
  666. pDoc->SetData(xpos, ypos, 0,
  667. (MAX_TERMINAL_HEIGHT - ypos)*MAX_TERMINAL_WIDTH -xpos,
  668. foreground, background);
  669. ret = pDoc->Unlock();
  670. }
  671. if((strncmp(Buffer,"\033[0K", length) == 0) ||
  672. (strncmp(Buffer,"\033[2K",length) == 0)){
  673. // clear to end of line assuming 80 X 24 size
  674. if(cdc){
  675. cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width-position,
  676. height,background);
  677. }
  678. ret = pDoc->Lock();
  679. pDoc->SetData(xpos, ypos, 0,
  680. MAX_TERMINAL_WIDTH -xpos, foreground, background);
  681. ret = pDoc->Unlock();
  682. return;
  683. }
  684. if((strncmp(Buffer,"\033[0m", length) == 0)||
  685. (strncmp(Buffer,"\033[m\017", length) == 0)){
  686. // clear all attributes and set Text attributes to black on white
  687. background = BLACK;
  688. foreground = WHITE;
  689. if(cdc){
  690. cdc->SetBkColor(background);
  691. cdc->SetTextColor(foreground);
  692. }
  693. return;
  694. }
  695. }
  696. if(Buffer[length-1] == 'm'){
  697. //set the text attributes
  698. // clear all attributes and set Text attributes to black on white
  699. ProcessTextAttributes((PCHAR) Buffer, length);
  700. return;
  701. }
  702. if(Buffer[length -1] == 'r'){
  703. if (sscanf(Buffer,"\033[%d;%dr", &charsToWrite, &charsWritten) == 2) {
  704. ScrollTop = (SHORT)charsToWrite;
  705. ScrollBottom = (SHORT)charsWritten;
  706. }
  707. return;
  708. }
  709. if(Buffer[length -1] == 'H'){
  710. if (sscanf(Buffer,"\033[%d;%dH", &charsToWrite, &charsWritten) == 2) {
  711. ypos = (SHORT)(charsToWrite -1);
  712. xpos = (SHORT)(charsWritten -1);
  713. ret = pDoc->Lock();
  714. DataLine = pDoc->GetDataLine(ypos);
  715. if (xpos >0){
  716. position = GetTextWidth(DataLine, xpos);
  717. }
  718. else{
  719. position = 0;
  720. }
  721. pDoc->Unlock();
  722. }
  723. }
  724. return;
  725. }
  726. void CWatcherView::ProcessTextAttributes(PCHAR Buffer, int length)
  727. {
  728. PCHAR CurrLoc = Buffer;
  729. ULONG Attribute;
  730. PCHAR pTemp;
  731. COLORREF temp;
  732. while(*CurrLoc != 'm'){
  733. if((*CurrLoc < '0') || (*CurrLoc >'9' )){
  734. CurrLoc ++;
  735. }else{
  736. if (sscanf(CurrLoc,"%d", &Attribute) != 1) {
  737. return;
  738. }
  739. switch(Attribute){
  740. case 7:
  741. // switch the colors. This will make this code
  742. // work for applications (written in an Unix world
  743. // for real VT100. )
  744. temp = foreground;
  745. foreground = background;
  746. background = temp;
  747. break;
  748. case 37:
  749. foreground = WHITE;
  750. break;
  751. case 47:
  752. background = WHITE;
  753. break;
  754. case 34:
  755. foreground = BLUE;
  756. break;
  757. case 44:
  758. background = BLUE;
  759. break;
  760. case 30:
  761. foreground = BLACK;
  762. break;
  763. case 40:
  764. background = BLACK;
  765. case 33:
  766. foreground = YELLOW;
  767. break;
  768. case 43:
  769. background = YELLOW;
  770. case 31:
  771. foreground = RED;
  772. break;
  773. case 41:
  774. background = RED;
  775. default:
  776. break;
  777. }
  778. pTemp = strchr(CurrLoc, ';');
  779. if(pTemp == NULL){
  780. pTemp = strchr(CurrLoc, 'm');
  781. }
  782. if(pTemp == NULL) {
  783. break;
  784. }
  785. CurrLoc = pTemp;
  786. }
  787. }
  788. cdc->SetBkColor(background);
  789. cdc->SetTextColor(foreground);
  790. return;
  791. }
  792. BOOL CWatcherView::FinalCharacter(CHAR c)
  793. {
  794. CHAR FinalCharacters[]="mHJKr";
  795. if(strchr(FinalCharacters,c)){
  796. return TRUE;
  797. }
  798. return FALSE;
  799. }
  800. BOOL CWatcherView::IsPrintable(TCHAR Char)
  801. {
  802. if (Char > 32) return TRUE;
  803. return FALSE;
  804. }
  805. void CWatcherView::OnDestroy()
  806. {
  807. if(Socket){
  808. delete Socket;
  809. }
  810. if(cdc){
  811. delete cdc;
  812. }
  813. CView::OnDestroy();
  814. // TODO: Add your message handler code here
  815. }
  816. int CWatcherView::GetTextWidth(TCHAR *Data, int number)
  817. {
  818. int textWidth=0;
  819. int CharWidth;
  820. for(int i=0;i<number;i++){
  821. // For variable width characters like Japanese, we need to
  822. // blank out the next character.
  823. if(Data[i] == 0xFFFF){
  824. continue;
  825. }
  826. if(IsPrintable(Data[i])){
  827. if (cdc->GetOutputCharWidth(Data[i], Data[i], &CharWidth)) {
  828. textWidth += CharWidth;
  829. }
  830. }
  831. else{
  832. textWidth += width;
  833. }
  834. }
  835. return textWidth;
  836. }
  837. // REMARK - Make this a virtual function so that
  838. // later writers can just extend this class and work
  839. // with the same framework. Now, the bell sequence
  840. // processing consists of nothing, but later can be
  841. // expanded to include WMI kind of processing.
  842. void CWatcherView::ProcessBellSequence(CHAR *Buffer, int len)
  843. {
  844. // Set this as the active window.
  845. // We will probably bring up a dialog box with
  846. // the bell parameters.
  847. WCHAR *messageBuffer;
  848. CHAR tempBuffer[MAX_BELL_SIZE + 1];
  849. int index =0;
  850. memset(tempBuffer,0, MAX_BELL_SIZE + 1);
  851. memcpy(tempBuffer, Buffer+16, len-24);
  852. tempBuffer[len-24] = (CHAR) 0;
  853. CWnd *parent = GetParent();
  854. CWnd *prev = parent->GetParent();
  855. if (prev && prev->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))){
  856. ((CMDIFrameWnd *) prev)->MDIActivate(parent);
  857. ((CMDIFrameWnd *) prev)->MDIRestore(parent);
  858. }
  859. else{
  860. ((CMDIChildWnd *)parent)->MDIActivate();
  861. ((CMDIChildWnd *)parent)->MDIRestore();
  862. }
  863. int convlen;
  864. messageBuffer = new WCHAR [MAX_BELL_SIZE + 1];
  865. messageBuffer[0] = 0;
  866. convlen = MultiByteToWideChar(CP_ACP,
  867. 0,
  868. tempBuffer,
  869. -1,
  870. messageBuffer,
  871. MAX_BELL_SIZE);
  872. messageBuffer[convlen] = (WCHAR) 0;
  873. CWinThread *th = ::AfxBeginThread(AFX_THREADPROC (GenerateWMIEvent),
  874. messageBuffer
  875. );
  876. return;
  877. }
  878. void CWatcherView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  879. {
  880. // TODO: Add your message handler code here and/or call default
  881. switch(nChar) {
  882. case VK_LEFT:
  883. Socket->Send("\033OC",sizeof("\033OC"),0);
  884. break;
  885. case VK_RIGHT:
  886. Socket->Send("\033OD",sizeof("\033OD"),0);
  887. break;
  888. case VK_UP:
  889. Socket->Send("\033OA",sizeof("\033OA"),0);
  890. break;
  891. case VK_DOWN:
  892. Socket->Send("\033OB",sizeof("\033OB"),0);
  893. break;
  894. case VK_F1:
  895. Socket->Send("\033""1",sizeof("\033""1"),0);
  896. break;
  897. case VK_F2:
  898. Socket->Send("\033""2",sizeof("\033""2"),0);
  899. break;
  900. case VK_F3:
  901. Socket->Send("\033""3",sizeof("\033""3"),0);
  902. break;
  903. case VK_F4:
  904. Socket->Send("\033""4",sizeof("\033""4"),0);
  905. break;
  906. case VK_F12:
  907. Socket->Send("\033@",sizeof("\033@"),0);
  908. break;
  909. default:
  910. break;
  911. }
  912. CView::OnKeyDown(nChar, nRepCnt, nFlags);
  913. }