home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 217 / DPCS0306DVD.ISO / Toolkit / Internet / FileZilla / Server / FileZilla_Server-0.9.11.exe / source / interface / MainFrm.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-11-13  |  35.6 KB  |  1,358 lines

  1. // FileZilla Server - a Windows ftp server
  2.  
  3. // Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
  4.  
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9.  
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. // MainFrm.cpp : Implementierung der Klasse CMainFrame
  20. //
  21.  
  22. #include "stdafx.h"
  23. #include "FileZilla server.h"
  24. #include "misc/led.h"
  25. #include "MainFrm.h"
  26. #include "../platform.h"
  27. #include "statusview.h"
  28. #include "usersdlg.h"
  29. #include "GroupsDlg.h"
  30. #include "options.h"
  31. #include "usersview.h"
  32. #include "userslistctrl.h"
  33. #include "misc/systemtray.h"
  34. #include "offlineaskdlg.h"
  35. #include "version.h"
  36. #include "AdminSocket.h"
  37. #include "OptionsDlg.h"
  38. #include "ConnectDialog.h"
  39. #include "mainfrm.h"
  40. #include "../defs.h"
  41.  
  42. #if defined(_DEBUG) && !defined(MMGR)
  43. #define new DEBUG_NEW
  44. #undef THIS_FILE
  45. static char THIS_FILE[] = __FILE__;
  46. #endif
  47.  
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CMainFrame
  50.  
  51. IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
  52.  
  53. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  54.     //{{AFX_MSG_MAP(CMainFrame)
  55.     ON_WM_CREATE()
  56.     ON_WM_SETFOCUS()
  57.     ON_WM_SIZE()
  58.     ON_WM_CLOSE()
  59.     ON_COMMAND(ID_EDIT_SETTINGS, OnEditSettings)
  60.     ON_COMMAND(ID_ACTIVE, OnActive)
  61.     ON_UPDATE_COMMAND_UI(ID_ACTIVE, OnUpdateActive)
  62.     ON_WM_SYSCOMMAND()
  63.     ON_COMMAND(ID_TRAY_EXIT, OnTrayExit)
  64.     ON_COMMAND(ID_TRAY_RESTORE, OnTrayRestore)
  65.     ON_COMMAND(ID_LOCK, OnLock)
  66.     ON_UPDATE_COMMAND_UI(ID_LOCK, OnUpdateLock)
  67.     ON_WM_TIMER()
  68.     ON_COMMAND(ID_USERS, OnMenuEditUsers)
  69.     ON_COMMAND(ID_GROUPS, OnMenuEditGroups)
  70.     ON_COMMAND(ID_FILE_CONNECT, OnFileConnect)
  71.     ON_COMMAND(ID_FILE_DISCONNECT, OnFileDisconnect)
  72.     ON_UPDATE_COMMAND_UI(ID_FILE_DISCONNECT, OnUpdateFileDisconnect)
  73.     ON_UPDATE_COMMAND_UI(ID_EDIT_SETTINGS, OnUpdateEditSettings)
  74.     ON_UPDATE_COMMAND_UI(ID_MENU_EDIT_USERS, OnUpdateMenuEditUsers)
  75.     ON_UPDATE_COMMAND_UI(ID_MENU_EDIT_GROUPS, OnUpdateMenuEditGroups)
  76.     ON_UPDATE_COMMAND_UI(ID_USERS, OnUpdateUsers)
  77.     ON_UPDATE_COMMAND_UI(ID_GROUPS, OnUpdateGroups)
  78.     ON_COMMAND(ID_MENU_EDIT_USERS, OnMenuEditUsers)
  79.     ON_COMMAND(ID_MENU_EDIT_GROUPS, OnMenuEditGroups)
  80.     ON_COMMAND(ID_USERLISTTOOLBAR_DISPLAYLOGICAL, OnDisplayLogicalNames)
  81.     ON_COMMAND(ID_USERLISTTOOLBAR_DISPLAYPHYSICAL, OnDisplayPhysicalNames)
  82.     ON_UPDATE_COMMAND_UI(ID_USERLISTTOOLBAR_DISPLAYLOGICAL, OnUpdateDisplayLogicalNames)
  83.     ON_UPDATE_COMMAND_UI(ID_USERLISTTOOLBAR_DISPLAYPHYSICAL, OnUpdateDisplayPhysicalNames)
  84.     ON_COMMAND(ID_USERLISTTOOLBAR_SORT, OnDisplaySortMenu)
  85.     ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarDropDown)
  86.     ON_COMMAND(ID_DISPLAY_SORTBYUSERID, OnDisplaySortByUserid)
  87.     ON_COMMAND(ID_DISPLAY_SORTBYACCOUNT, OnDisplaySortByAccount)
  88.     ON_COMMAND(ID_DISPLAY_SORTBYIP, OnDisplaySortByIP)
  89.     ON_UPDATE_COMMAND_UI(ID_DISPLAY_SORTBYUSERID, OnUpdateDisplaySortByUserid)
  90.     ON_UPDATE_COMMAND_UI(ID_DISPLAY_SORTBYACCOUNT, OnUpdateDisplaySortByAccount)
  91.     ON_UPDATE_COMMAND_UI(ID_DISPLAY_SORTBYIP, OnUpdateDisplaySortByIP)
  92.     ON_WM_DESTROY()
  93.     //}}AFX_MSG_MAP
  94.     ON_WM_ERASEBKGND()
  95. END_MESSAGE_MAP()
  96.  
  97. static UINT indicators[] =
  98. {
  99.     ID_SEPARATOR,           // Statusleistenanzeige
  100.     ID_INDICATOR_RECVCOUNT,
  101.     ID_INDICATOR_RECVRATE,
  102.     ID_INDICATOR_SENDCOUNT,
  103.     ID_INDICATOR_SENDRATE,
  104.     ID_INDICATOR_RECVLED,
  105.     ID_INDICATOR_SENDLED,
  106.     ID_SEPARATOR
  107. };
  108.  
  109. /////////////////////////////////////////////////////////////////////////////
  110. // CMainFrame Konstruktion/Zerst÷rung
  111.  
  112. CMainFrame::CMainFrame(COptions *pOptions)
  113. {
  114.     ASSERT(pOptions);
  115.     nTrayNotificationMsg_ = RegisterWindowMessage("FileZilla Server Tray Notification Message");    
  116.     m_bQuit = FALSE;
  117.     m_nSendCount = 0;
  118.     m_nRecvCount = 0;
  119.     m_lastchecktime = GetTickCount();
  120.     m_lastreaddiff = 0;
  121.     m_lastwritediff = 0;
  122.     m_nOldRecvCount = 0;
  123.     m_nOldSendCount = 0;
  124.     m_pOptions = pOptions;
  125.     m_pAdminSocket = NULL;
  126.     m_nServerState = 0;
  127.     m_nEdit = 0;
  128.  
  129.     m_pOptionsDlg = 0;
  130.     m_pUsersDlg = 0;
  131.     m_pGroupsDlg = 0;
  132.  
  133.     m_nReconnectTimerID = 0;
  134.     m_nReconnectCount = 0;
  135. }
  136.  
  137. CMainFrame::~CMainFrame()
  138. {
  139.     delete m_pOptions;
  140.     m_pOptions = 0;
  141.     CloseAdminSocket(false);
  142. }
  143.  
  144. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  145. {
  146.     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  147.         return -1;
  148.     
  149.     SetupTrayIcon();
  150.  
  151.     if (!m_wndReBar.Create(this))
  152.         return -1;
  153.  
  154.     if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP
  155.         | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  156.         !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
  157.     {
  158.         TRACE0("Could not create Toolbar 1\n");
  159.         return -1;      // Fehler bei Erstellung
  160.     }
  161.     
  162.     if (!m_wndUserListToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_ALIGN_LEFT
  163.         | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  164.         !m_wndUserListToolBar.LoadToolBar(IDR_USERLISTTOOLBAR))
  165.     {
  166.         TRACE0("Could not create Toolbar 2\n");
  167.         return -1;      // Fehler bei Erstellung
  168.     }
  169.     m_wndUserListToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
  170.     DWORD dwStyle = m_wndUserListToolBar.GetButtonStyle(m_wndUserListToolBar.CommandToIndex(ID_USERLISTTOOLBAR_SORT));
  171.     dwStyle |= TBSTYLE_DROPDOWN;
  172.     m_wndUserListToolBar.SetButtonStyle(m_wndUserListToolBar.CommandToIndex(ID_USERLISTTOOLBAR_SORT), dwStyle);
  173.  
  174.     m_wndReBar.AddBar(&m_wndToolBar);
  175.     m_wndReBar.AddBar(&m_wndUserListToolBar);
  176.     m_wndReBar.GetReBarCtrl().MinimizeBand(0);
  177.     
  178.     if (!m_wndStatusBar.Create(this) ||
  179.         !m_wndStatusBar.SetIndicators(indicators,
  180.           sizeof(indicators)/sizeof(UINT)))
  181.     {
  182.         TRACE0("Statusleiste konnte nicht erstellt werden\n");
  183.         return -1;      // Fehler bei Erstellung
  184.     }
  185.  
  186.     // The last statusbar pane is a fake one, it has zero width.
  187.     m_wndStatusBar.SetPaneInfo(7, 0, SBPS_NOBORDERS, 0);
  188.  
  189.     CRect rect;
  190.     m_wndStatusBar.GetItemRect(m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVLED), rect);  
  191.  
  192.     //Create the first LED control
  193.     m_RecvLed.Create("",WS_VISIBLE|WS_CHILD, rect, &m_wndStatusBar, m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVLED)); 
  194.     m_RecvLed.SetLed( CLed::LED_COLOR_GREEN, CLed::LED_OFF, CLed::LED_ROUND);
  195.  
  196.     //Create the second LED control
  197.     m_SendLed.Create("",WS_VISIBLE|WS_CHILD, rect, &m_wndStatusBar, m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDLED)); 
  198.     m_SendLed.SetLed( CLed::LED_COLOR_RED, CLed::LED_OFF, CLed::LED_ROUND);
  199.  
  200.     m_wndStatusBar.GetItemRect(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDLED), &rect);
  201.     m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVLED),ID_INDICATOR_RECVLED,SBPS_NOBORDERS,6);
  202.     m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDLED),ID_INDICATOR_SENDLED,SBPS_NOBORDERS,6);
  203.  
  204.     ShowStatus(GetVersionString(), 0);
  205.     ShowStatus("Copyright 2001-2005 by Tim Kosse (Tim.Kosse@gmx.de)", 0);
  206.  
  207.     m_nTimerID=SetTimer(7777, 10000, 0);
  208.     m_nRateTimerID=SetTimer(7778, 1000, 0);
  209.  
  210.     SetStatusbarText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDCOUNT), "0 bytes sent");
  211.     SetStatusbarText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVCOUNT), "0 bytes received");
  212.     SetStatusbarText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVRATE), "0 B/s");
  213.     SetStatusbarText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDRATE), "0 B/s");
  214.  
  215.  
  216.     if (m_pOptions->GetOptionVal(IOPTION_ALWAYS))
  217.     {
  218.         m_pAdminSocket = new CAdminSocket(this);
  219.         ShowStatus("Connecting to server...", 0);
  220.         m_pAdminSocket->Create();
  221.         m_pAdminSocket->m_Password = m_pOptions->GetOption(IOPTION_LASTSERVERPASS);
  222.         if (!m_pAdminSocket->Connect(m_pOptions->GetOption(IOPTION_LASTSERVERADDRESS), (UINT)m_pOptions->GetOptionVal(IOPTION_LASTSERVERPORT)) && WSAGetLastError() != WSAEWOULDBLOCK)
  223.         {
  224.             ShowStatus(_T("Error, could not connect to server"), 1);
  225.             CloseAdminSocket();
  226.         }
  227.     }
  228.     else
  229.     {
  230.         CConnectDialog dlg(m_pOptions);
  231.         if (dlg.DoModal() == IDOK)
  232.         {
  233.             m_pAdminSocket = new CAdminSocket(this);
  234.             ShowStatus("Connecting to server...", 0);
  235.             m_pAdminSocket->m_Password = m_pOptions->GetOption(IOPTION_LASTSERVERPASS);
  236.             m_pAdminSocket->Create();
  237.             if (!m_pAdminSocket->Connect(m_pOptions->GetOption(IOPTION_LASTSERVERADDRESS), (UINT)m_pOptions->GetOptionVal(IOPTION_LASTSERVERPORT)) && WSAGetLastError()!=WSAEWOULDBLOCK)
  238.             {
  239.                 ShowStatus(_T("Error, could not connect to server"), 1);
  240.                 CloseAdminSocket();
  241.             }
  242.         }
  243.     }
  244.  
  245.     return 0;
  246. }
  247.  
  248. //////////////////
  249. // Helper function to register a new window class based on an already
  250. // existing window class, but with a different name and icon. 
  251. // Returns new name if successful; otherwise NULL.
  252. //
  253. static LPCSTR RegisterSimilarClass(LPCSTR lpszNewClassName,
  254.     LPCSTR lpszOldClassName, UINT nIDResource)
  255. {
  256.     // Get class info for old class.
  257.     //
  258.     HINSTANCE hInst = AfxGetInstanceHandle();
  259.     WNDCLASS wc;
  260.     if (!::GetClassInfo(hInst, lpszOldClassName, &wc)) {
  261.         TRACE("Can't find window class %s\n", lpszOldClassName);
  262.         return NULL;
  263.     }
  264.  
  265.     // Register new class with same info, but different name and icon.
  266.     //
  267.     wc.lpszClassName = lpszNewClassName;
  268.     wc.hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(nIDResource));
  269.     if (!AfxRegisterClass(&wc)) {
  270.         TRACE("Unable to register window class%s\n", lpszNewClassName);
  271.         return NULL;
  272.     }
  273.     return lpszNewClassName;
  274. }
  275.  
  276. // Static class member holds window class name
  277. // (NULL if not registered yet).
  278. // 
  279. LPCSTR CMainFrame::s_winClassName = NULL;
  280.  
  281. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  282. {
  283.     if( !CFrameWnd::PreCreateWindow(cs) )
  284.         return FALSE;
  285.     
  286.     // ZU ERLEDIGEN: ─ndern Sie hier die Fensterklasse oder das Erscheinungsbild, indem Sie
  287.     //  CREATESTRUCT cs modifizieren.
  288.  
  289.     cs.lpszClass = AfxRegisterWndClass(0);
  290.  
  291.     cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
  292.  
  293.     //Change the window class name
  294.     if (s_winClassName==NULL) 
  295.     {
  296.         // One-time initialization: register the class
  297.         //
  298.         s_winClassName = RegisterSimilarClass("FileZilla Server Main Window", 
  299.                         cs.lpszClass, IDR_MAINFRAME);
  300.         if (!s_winClassName)
  301.             return FALSE;
  302.     }
  303.     cs.lpszClass = s_winClassName;
  304.  
  305.     return TRUE;
  306. }
  307.  
  308. /////////////////////////////////////////////////////////////////////////////
  309. // CMainFrame Nachrichten-Handler
  310. void CMainFrame::OnSetFocus(CWnd* pOldWnd)
  311. {
  312.     // Fokus an das Ansichtfenster weitergeben
  313. }
  314.  
  315. BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  316. {
  317.     // andernfalls die Standardbehandlung durchfⁿhren
  318.     return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  319. }
  320.  
  321. BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
  322. {
  323.     CRect rect;
  324.     GetClientRect(rect);
  325.  
  326.     // Unterteiltes Fenster erstellen
  327.     if (!m_wndSplitter.CreateStatic(this, 2, 1))
  328.         return FALSE;
  329.     if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CStatusView), CSize(1, rect.Height() - 150), pContext))
  330.     {
  331.         m_wndSplitter.DestroyWindow();
  332.         return FALSE;
  333.     }
  334.     m_pStatusPane = (CStatusView*)m_wndSplitter.GetPane(0, 0);
  335.  
  336.     if (!m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CUsersView), CSize(1, 150), pContext))
  337.     {
  338.         m_wndSplitter.DestroyWindow();
  339.         return FALSE;
  340.     }
  341.     m_pUsersPane = (CUsersView*) m_wndSplitter.GetPane(1, 0);
  342.  
  343.     // Filename display option.
  344.     GetUsersPane()->m_pListCtrl->SetDisplayPhysicalNames(m_pOptions->GetOptionVal(IOPTION_FILENAMEDISPLAY) != 0);
  345.  
  346.     // Set layout options.
  347.     int sortInfo = (int)m_pOptions->GetOptionVal(IOPTION_USERSORTING);
  348.     GetUsersPane()->m_pListCtrl->SetSortColumn(sortInfo & 0x0F, sortInfo >> 4);
  349.  
  350.     return CFrameWnd::OnCreateClient(lpcs, pContext);
  351. }
  352.  
  353. CStatusView* CMainFrame::GetStatusPane()
  354. {
  355.     return m_pStatusPane;
  356. }
  357.  
  358. CUsersView* CMainFrame::GetUsersPane()
  359. {
  360.     return m_pUsersPane;
  361. }
  362.  
  363. void CMainFrame::OnSize(UINT nType, int cx, int cy) 
  364. {
  365.     if (m_wndStatusBar.GetSafeHwnd())
  366.     {
  367.         if (nType!=SIZE_MAXIMIZED)
  368.             m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDLED),ID_INDICATOR_SENDLED,SBPS_NOBORDERS,0);
  369.         else
  370.             m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDLED),ID_INDICATOR_SENDLED,SBPS_NOBORDERS,10);
  371.     }
  372.  
  373.     if (m_wndSplitter.GetSafeHwnd())
  374.     {
  375.         //Hide the queue if visible
  376.         m_wndSplitter.HideRow(1, 0);
  377.     }
  378.     //Now only the main splitter gets resized
  379.     CFrameWnd::OnSize(nType, cx, cy);
  380.     if (m_wndSplitter.GetSafeHwnd())
  381.     {
  382.         //Restore the queue
  383.         m_wndSplitter.ShowRow(1);
  384.     }
  385.     
  386.     if (m_wndStatusBar.GetSafeHwnd())
  387.     {
  388.         RECT rc;
  389.  
  390.         m_wndStatusBar.GetItemRect(m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVLED), &rc);
  391.  
  392.         // Reposition the first LED correctly!
  393.         m_RecvLed.SetWindowPos(&wndTop, rc.left, rc.top+1, rc.right - rc.left,
  394.             rc.bottom - rc.top, 0); 
  395.  
  396.         m_wndStatusBar.GetItemRect(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDLED), &rc);
  397.     
  398.         // Reposition the second LED correctly!
  399.         m_SendLed.SetWindowPos(&wndTop, rc.left, rc.top+1, rc.right - rc.left,
  400.                 rc.bottom - rc.top, 0); 
  401.     }
  402. }
  403.  
  404. void CMainFrame::OnClose() 
  405. {
  406.     CFrameWnd::OnClose();
  407. }
  408.  
  409. void CMainFrame::OnEditSettings() 
  410. {
  411.     if (m_nEdit)
  412.     {
  413.         MessageBeep(MB_OK);
  414.         return;
  415.     }
  416.     m_nEdit |= 0x04;
  417.     SendCommand(5, 0, 0);
  418.     ShowStatus(_T("Retrieving settings, please wait..."), 0);
  419. }
  420.  
  421. void CMainFrame::OnActive() 
  422. {
  423.     if (m_nServerState & STATE_ONLINE && !(m_nServerState & STATE_MASK_GOOFFLINE))
  424.     {
  425.         if (!GetUsersPane()->m_pListCtrl->GetItemCount())
  426.         {
  427.             if (AfxMessageBox("Do you really want to take the server offline?", MB_YESNO | MB_ICONQUESTION) != IDYES)
  428.                 return;
  429.             int nServerState = m_nServerState | STATE_GOOFFLINE_NOW;
  430.             unsigned char buffer[2];
  431.             buffer[0] = nServerState / 256;
  432.             buffer[1] = nServerState % 256;
  433.             SendCommand(2, buffer, 2);
  434.             ShowStatus("Server is going offline...", 0);
  435.             return;
  436.         }
  437.         else
  438.         {
  439.             COfflineAskDlg dlg;
  440.             if (dlg.DoModal() != IDOK)
  441.                 return;
  442.             if (dlg.m_nRadio == 2)
  443.             {
  444.                 int nServerState = m_nServerState | STATE_GOOFFLINE_WAITTRANSFER;
  445.                 unsigned char buffer[2];
  446.                 buffer[0] = nServerState / 256;
  447.                 buffer[1] = nServerState % 256;
  448.                 SendCommand(2, buffer, 2);
  449.                 ShowStatus("Server is going offline...", 0);
  450.                 return;
  451.             }
  452.             if (dlg.m_nRadio == 1)
  453.             {
  454.                 int nServerState = m_nServerState | STATE_GOOFFLINE_LOGOUT;
  455.                 unsigned char buffer[2];
  456.                 buffer[0] = nServerState / 256;
  457.                 buffer[1] = nServerState % 256;
  458.                 SendCommand(2, buffer, 2);
  459.                 ShowStatus("Server is going offline...", 0);                
  460.                 return;
  461.             }                
  462.             else
  463.             {
  464.                 int nServerState = m_nServerState | STATE_GOOFFLINE_NOW;
  465.                 unsigned char buffer[2];
  466.                 buffer[0] = nServerState / 256;
  467.                 buffer[1] = nServerState % 256;
  468.                 SendCommand(2, buffer, 2);
  469.                 ShowStatus("Server is going offline...", 0);
  470.                 return;
  471.             }
  472.         }
  473.     }
  474.     else
  475.     {
  476.         int nServerState = 1 + (m_nServerState & STATE_LOCKED);
  477.         unsigned char buffer[2];
  478.         buffer[0] = nServerState / 256;
  479.         buffer[1] = nServerState % 256;
  480.         SendCommand(2, buffer, 2);
  481.     }
  482. }
  483.  
  484. void CMainFrame::OnUpdateActive(CCmdUI* pCmdUI) 
  485. {
  486.     pCmdUI->Enable(m_pAdminSocket && m_pAdminSocket->IsConnected());
  487.     pCmdUI->SetCheck(m_nServerState & STATE_ONLINE && !(m_nServerState & STATE_MASK_GOOFFLINE));
  488. }
  489.  
  490. void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
  491. {
  492.     CFrameWnd::OnSysCommand(nID, lParam);
  493.     if (nID == SC_MINIMIZE)
  494.         ShowWindow(SW_HIDE);
  495.     else if (nID == SC_RESTORE)
  496.         ShowWindow(SW_SHOW);
  497. }
  498.  
  499. //// SetupTrayIcon /////////////////////////////////////////////////////
  500. // If we're minimized, create an icon in the systray.  Otherwise, remove
  501. // the icon, if one is present.
  502.  
  503. void CMainFrame::SetupTrayIcon()
  504. {
  505.     m_TrayIcon.Create(0, nTrayNotificationMsg_, "FileZilla Server",
  506.         0, IDR_SYSTRAY_MENU);
  507.     m_TrayIcon.SetIcon(IDI_UNKNOWN);
  508. }
  509.  
  510.  
  511. //// SetupTaskBarButton ////////////////////////////////////////////////
  512. // Show or hide the taskbar button for this app, depending on whether
  513. // we're minimized right now or not.
  514.  
  515. void CMainFrame::OnTrayExit() 
  516. {
  517.     if (!m_bQuit)
  518.         OnClose();    
  519. }
  520.  
  521. void CMainFrame::OnTrayRestore() 
  522. {
  523.     ShowWindow(SW_RESTORE);
  524.     ShowWindow(SW_SHOW);
  525. }
  526.  
  527. void CMainFrame::SetIcon()
  528. {
  529.     if (!m_pAdminSocket || !m_pAdminSocket->IsConnected())
  530.     {
  531.         m_TrayIcon.StopAnimation();
  532.         m_TrayIcon.SetIcon(IDI_UNKNOWN);
  533.     }
  534.     else if (!(m_nServerState & STATE_ONLINE) || m_nServerState & STATE_MASK_GOOFFLINE)
  535.     {
  536.         if (!GetUsersPane()->m_pListCtrl->GetItemCount())
  537.         {    
  538.             m_TrayIcon.StopAnimation();
  539.             m_TrayIcon.SetIcon(IDI_RED);
  540.         }
  541.         else
  542.         {
  543.             m_TrayIcon.SetIconList(IDI_GREEN, IDI_RED);
  544.             m_TrayIcon.Animate(500);
  545.         }
  546.     }
  547.     else if (m_nServerState & STATE_LOCKED)
  548.     {
  549.         if (GetUsersPane()->m_pListCtrl->GetItemCount())
  550.         {    
  551.             m_TrayIcon.SetIconList(IDI_GREEN, IDI_YELLOW);
  552.             m_TrayIcon.Animate(300);
  553.         }
  554.         else
  555.         {
  556.             m_TrayIcon.SetIconList(IDI_YELLOW, IDI_RED);
  557.             m_TrayIcon.Animate(500);
  558.         }
  559.  
  560.     }
  561.     else
  562.     {
  563.         m_TrayIcon.StopAnimation();
  564.         m_TrayIcon.SetIcon(GetUsersPane()->m_pListCtrl->GetItemCount()?IDI_GREEN:IDI_YELLOW);
  565.     }
  566.  
  567. }
  568.  
  569. void CMainFrame::OnLock() 
  570. {
  571.     if (!(m_nServerState & STATE_ONLINE) || m_nServerState & STATE_MASK_GOOFFLINE)
  572.         return;
  573.     if (m_nServerState & STATE_LOCKED)
  574.     {
  575.         int nServerState = m_nServerState & ~STATE_LOCKED;
  576.         unsigned char buffer[2];
  577.         buffer[0] = nServerState / 256;
  578.         buffer[1] = nServerState % 256;
  579.         SendCommand(2, buffer, 2);
  580.     }
  581.     else
  582.     {
  583.         if (AfxMessageBox("Do you really want to lock the server? No new connenctions will be accepted while locked.", MB_YESNO|MB_ICONQUESTION)!=IDYES)
  584.             return;
  585.         int nServerState = m_nServerState | STATE_LOCKED;
  586.         unsigned char buffer[2];
  587.         buffer[0] = nServerState / 256;
  588.         buffer[1] = nServerState % 256;
  589.         SendCommand(2, buffer, 2);
  590.         ShowStatus("Server locked", 0);    
  591.     }    
  592. }
  593.  
  594. void CMainFrame::OnUpdateLock(CCmdUI* pCmdUI) 
  595. {
  596.     pCmdUI->Enable(m_pAdminSocket && m_pAdminSocket->IsConnected() && m_nServerState & STATE_ONLINE && !(m_nServerState & STATE_MASK_GOOFFLINE));
  597.     pCmdUI->SetCheck((m_nServerState & STATE_LOCKED) ? 1 : 0);
  598.     
  599. }
  600.  
  601. void CMainFrame::OnTimer(UINT_PTR nIDEvent) 
  602. {
  603.     if (!nIDEvent)
  604.         return;
  605.     else if (nIDEvent==m_nTimerID)
  606.     {
  607.         SendCommand(8);
  608.         m_TrayIcon.RefreshIcon();
  609.     }
  610.     else if (nIDEvent==m_nRateTimerID)
  611.     {
  612.         __int64 diff=m_nSendCount-m_nOldSendCount;
  613.         if (m_lastwritediff && diff)
  614.         {
  615.             __int64 tmp=diff;
  616.             diff=(diff+m_lastwritediff)/2;
  617.             m_lastwritediff=tmp;
  618.         }
  619.         else
  620.             m_lastwritediff=diff;
  621.  
  622.         int span=GetTickCount()-m_lastchecktime;
  623.         diff=(__int64)((double)diff*1000/span);
  624.  
  625.         CString str="";
  626.         CString digit;
  627.         while (diff)
  628.         {
  629.             digit = (TCHAR)('0' + static_cast<TCHAR>(diff%10));
  630.             str=digit+str;
  631.             diff/=10;
  632.         }
  633.         if (str=="")
  634.             str="0";
  635.  
  636.         int shift=0;
  637.         while (str.GetLength()>4)
  638.         {
  639.             shift++;
  640.             str=str.Left(str.GetLength()-1);
  641.         }
  642.         if (shift%3)
  643.             str=str.Left((shift%3)+1)+","+str.Right(str.GetLength()-(shift%3)-1);
  644.         shift+=2;
  645.         shift/=3;
  646.         if (!shift)
  647.             str+=" B/s";
  648.         else if (shift==1)
  649.             str+=" KB/s";
  650.         else if (shift==2)
  651.             str+=" MB/s";
  652.         else if (shift==3)
  653.             str+=" GB/s";
  654.         else if (shift==4)
  655.             str+=" TB/s";
  656.         else
  657.             str="n/a"; //If this happens, you really have a fast connection
  658.         SetStatusbarText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDRATE),str);
  659.         m_nOldSendCount=m_nSendCount;
  660.         
  661.         diff=m_nRecvCount-m_nOldRecvCount;
  662.         if (diff)
  663.         {
  664.             int x=0;
  665.         }
  666.         if (m_lastreaddiff && diff)
  667.         {
  668.             __int64 tmp=diff;
  669.             diff=(diff+m_lastreaddiff)/2;
  670.             m_lastreaddiff=tmp;
  671.         }
  672.         else
  673.             m_lastreaddiff=diff;
  674.         
  675.         span=GetTickCount()-m_lastchecktime;
  676.         diff=(__int64)((double)diff*1000/span);
  677.  
  678.         str=""; //diff in String umwandeln
  679.         while (diff)
  680.         {
  681.             digit = (TCHAR)('0' + static_cast<TCHAR>(diff%10));
  682.             str=digit+str;
  683.             diff/=10;
  684.         }
  685.         if (str=="")
  686.             str="0";
  687.  
  688.         shift=0;
  689.         while (str.GetLength()>4)
  690.         {
  691.             shift++;
  692.             str=str.Left(str.GetLength()-1);
  693.         }
  694.         if (shift%3)
  695.             str=str.Left((shift%3)+1)+","+str.Right(str.GetLength()-(shift%3)-1);
  696.         shift+=2;
  697.         shift/=3;
  698.         if (!shift)
  699.             str+=" B/s";
  700.         else if (shift==1)
  701.             str+=" KB/s";
  702.         else if (shift==2)
  703.             str+=" MB/s";
  704.         else if (shift==3)
  705.             str+=" GB/s";
  706.         else if (shift==4)
  707.             str+=" TB/s";
  708.         else
  709.             str="n/a"; //If this happens, you really have a fast connection
  710.         SetStatusbarText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVRATE),str);
  711.         m_lastchecktime=GetTickCount();
  712.         m_nOldRecvCount=m_nRecvCount;
  713.  
  714.     }
  715.     else if (nIDEvent == m_nReconnectTimerID)
  716.     {
  717.         KillTimer(m_nReconnectTimerID);
  718.         m_nReconnectTimerID = 0;
  719.         
  720.         if (m_pAdminSocket)
  721.             return;
  722.  
  723.         m_pAdminSocket = new CAdminSocket(this);
  724.         ShowStatus("Reconnecting to server...", 0);
  725.         m_pAdminSocket->m_Password = m_pOptions->GetOption(IOPTION_LASTSERVERPASS);
  726.         m_pAdminSocket->Create();
  727.         if (!m_pAdminSocket->Connect(m_pOptions->GetOption(IOPTION_LASTSERVERADDRESS), (UINT)m_pOptions->GetOptionVal(IOPTION_LASTSERVERPORT)) && WSAGetLastError()!=WSAEWOULDBLOCK)
  728.         {
  729.             ShowStatus(_T("Error, could not connect to server"), 1);
  730.             CloseAdminSocket();
  731.         }
  732.     }
  733.  
  734.     CFrameWnd::OnTimer(nIDEvent);
  735. }
  736.  
  737. void CMainFrame::SetStatusbarText(int nIndex,CString str)
  738. {
  739.     m_wndStatusBar.GetStatusBarCtrl().SetText(str,nIndex,0);
  740.     HFONT hFont = (HFONT)m_wndStatusBar.SendMessage(WM_GETFONT);
  741.     if (str=="")
  742.     {
  743.         str.LoadString(m_wndStatusBar.GetItemID(nIndex));        
  744.     }
  745.     CClientDC dcScreen(NULL);
  746.     HGDIOBJ hOldFont = NULL;
  747.     if (hFont != NULL)
  748.     hOldFont = dcScreen.SelectObject(hFont);
  749.     int cx=dcScreen.GetTextExtent(str).cx;
  750.     int cxold;
  751.     unsigned int nID,nStyle;
  752.     m_wndStatusBar.GetPaneInfo(nIndex,nID,nStyle,cxold);
  753.     if (cx!=cxold)
  754.     {
  755.         if (cx<cxold)
  756.             cx=cxold;
  757.         m_wndStatusBar.SetPaneInfo(nIndex,nID,nStyle,cx);
  758.     
  759.     }
  760.     if (hOldFont != NULL)
  761.         dcScreen.SelectObject(hOldFont);
  762.  
  763. }
  764.  
  765. void CMainFrame::OnMenuEditUsers() 
  766. {
  767.     if (m_nEdit)
  768.     {
  769.         MessageBeep(MB_OK);
  770.         return;
  771.     }
  772.     m_nEdit |= 1;
  773.     SendCommand(6, 0, 0);
  774.     ShowStatus(_T("Retrieving account settings, please wait..."), 0);
  775. }
  776.  
  777. void CMainFrame::OnMenuEditGroups() 
  778. {
  779.     if (m_nEdit)
  780.     {
  781.         MessageBeep(MB_OK);
  782.         return;
  783.     }
  784.     m_nEdit |= 2;
  785.     SendCommand(6, 0, 0);
  786.     ShowStatus(_T("Retrieving account settings, please wait..."), 0);
  787. }
  788.  
  789. void CMainFrame::ShowStatus(CString status, int nType)
  790. {
  791.     char *pBuffer = new char[status.GetLength() + 1];
  792.     strcpy(pBuffer, status);
  793.     CStatusView *view = GetStatusPane();
  794.     view->ShowStatus(pBuffer, nType);
  795. }
  796.  
  797. void CMainFrame::ShowStatusRaw(char *status, int nType)
  798. {
  799.     CStatusView *view = GetStatusPane();
  800.     view->ShowStatus(status, nType);
  801. }
  802.  
  803. void CMainFrame::ParseReply(int nReplyID, unsigned char *pData, int nDataLength)
  804. {
  805.     switch(nReplyID)
  806.     {
  807.     case 0:
  808.         {
  809.             ShowStatus(_T("Logged on"), 0);
  810.             SendCommand(2);
  811.             unsigned char buffer = USERCONTROL_GETLIST;
  812.             SendCommand(3, &buffer, 1);
  813.         }
  814.         break;
  815.     case 1:
  816.         {
  817.             char *pBuffer = new char[nDataLength];
  818.             memcpy(pBuffer, pData+1, nDataLength-1);
  819.             pBuffer[nDataLength-1] = 0;
  820.             ShowStatusRaw(pBuffer, *pData);
  821.         }
  822.         break;
  823.     case 2:
  824.         m_nServerState = *pData*256 + pData[1];
  825.         SetIcon();
  826.         break;
  827.     case 3:
  828.         {
  829.             if (nDataLength<2)
  830.             {
  831.                 ShowStatus(_T("Protocol error: Unexpected data length"), 1);
  832.                 return;
  833.             }
  834.             else if (!GetUsersPane()->m_pListCtrl->ParseUserControlCommand(pData, nDataLength))
  835.                 ShowStatus(_T("Protocol error: Invalid data"), 1);
  836.         }
  837.         break;
  838.     case 5:
  839.         if (nDataLength == 1)
  840.         {
  841.             if (*pData == 0)
  842.                 ShowStatus(_T("Done sending settings."), 0);
  843.             else if (*pData == 1)
  844.                 ShowStatus(_T("Could not change settings"), 1);
  845.             break;
  846.         }
  847.         ShowStatus(_T("Done retrieving settings"), 0);
  848.         if (nDataLength<2)
  849.             ShowStatus(_T("Protocol error: Unexpected data length"), 1);
  850.         else
  851.         {
  852.             if ((m_nEdit & 0x1C) == 0x04)
  853.             {
  854.                 m_pOptionsDlg = new COptionsDlg(m_pOptions, m_pAdminSocket->IsLocal());
  855.                 m_nEdit |= 0x08;
  856.                 if (!m_pOptionsDlg->Init(pData, nDataLength))
  857.                 {
  858.                     ShowStatus(_T("Protocol error: Invalid data"), 1);
  859.                     delete m_pOptionsDlg;
  860.                     m_pOptionsDlg = 0;
  861.                     m_nEdit = 0;
  862.                 }
  863.                 else if (!PostMessage(WM_APP))
  864.                 {
  865.                     ShowStatus(_T("Can't send window message"), 1);
  866.                     delete m_pOptionsDlg;
  867.                     m_pOptionsDlg = 0;
  868.                     m_nEdit = 0;
  869.                 }
  870.             }
  871.         }
  872.         break;
  873.     case 6:
  874.         if (nDataLength == 1)
  875.         {
  876.             if (*pData == 0)
  877.                 ShowStatus(_T("Done sending account settings."), 0);
  878.             else if (*pData == 1)
  879.                 ShowStatus(_T("Could not change account settings"), 1);
  880.             break;
  881.         }
  882.         ShowStatus(_T("Done retrieving account settings"), 0);
  883.         if (nDataLength<2)
  884.             ShowStatus(_T("Protocol error: Unexpected data length"), 1);
  885.         else
  886.         {
  887.             if ((m_nEdit & 0x19) == 0x01)
  888.             {
  889.                 m_pUsersDlg = new CUsersDlg(this, m_pAdminSocket->IsLocal());
  890.                 m_nEdit |= 0x08;
  891.                 if (!m_pUsersDlg->Init(pData, nDataLength))
  892.                 {
  893.                     ShowStatus(_T("Protocol error: Invalid data"), 1);
  894.                     delete m_pUsersDlg;
  895.                     m_pUsersDlg = 0;
  896.                     m_nEdit = 0;
  897.                     break;
  898.                 }
  899.                 else if (!PostMessage(WM_APP))
  900.                 {
  901.                     ShowStatus(_T("Can't send window message"), 1);
  902.                     delete m_pUsersDlg;
  903.                     m_pUsersDlg = 0;
  904.                     m_nEdit = 0;
  905.                 }
  906.             }
  907.             if ((m_nEdit & 0x1A) == 0x02)
  908.             {
  909.                 m_pGroupsDlg = new CGroupsDlg(this, m_pAdminSocket->IsLocal());
  910.                 m_nEdit |= 0x08;
  911.                 if (!m_pGroupsDlg->Init(pData, nDataLength))
  912.                 {
  913.                     ShowStatus(_T("Protocol error: Invalid data"), 1);
  914.                     delete m_pGroupsDlg;
  915.                     m_pGroupsDlg = 0;
  916.                     m_nEdit = 0;
  917.                     break;
  918.                 }
  919.                 else if (!PostMessage(WM_APP))
  920.                 {
  921.                     ShowStatus(_T("Can't send window message"), 1);
  922.                     delete m_pGroupsDlg;
  923.                     m_pGroupsDlg = 0;
  924.                     m_nEdit = 0;
  925.                 }
  926.             }
  927.         }
  928.         break;
  929.     case 8:
  930.         break;
  931.     default:
  932.         {
  933.             CString str;
  934.             str.Format(_T("Protocol error: Unexpected reply id (%d)."), nReplyID);
  935.             ShowStatus(str, 1);
  936.             break;
  937.         }
  938.     }
  939. }
  940.  
  941. void CMainFrame::ParseStatus(int nStatusID, unsigned char *pData, int nDataLength)
  942. {
  943.     switch(nStatusID)
  944.     {
  945.     case 1:
  946.         {
  947.             char *pBuffer = new char[nDataLength];
  948.             memcpy(pBuffer, pData+1, nDataLength-1);
  949.             pBuffer[nDataLength-1] = 0;
  950.             ShowStatusRaw(pBuffer, *pData);
  951.         }
  952.         break;
  953.     case 2:
  954.         m_nServerState = *pData*256 + pData[1];
  955.         SetIcon();
  956.         break;
  957.     case 3:
  958.         {
  959.             if (nDataLength<2)
  960.             {
  961.                 ShowStatus(_T("Protocol error: Unexpected data length"), 1);
  962.                 return;
  963.             }
  964.             else if (!GetUsersPane()->m_pListCtrl->ParseUserControlCommand(pData, nDataLength))
  965.                 ShowStatus(_T("Protocol error: Invalid data"), 1);
  966.         }
  967.         break;
  968.     case 4:
  969.         {
  970.             char *buffer = new char[nDataLength - 9 + 160 + 1];
  971.             unsigned char *p = pData + 9;
  972.             char *q = buffer;
  973.             int pos = 0;
  974.             while (pos < (nDataLength - 9))
  975.             {
  976.                 if (*p == '-')
  977.                 {
  978.                     DWORD timeHigh = GET32(pData + 1);
  979.                     DWORD timeLow = GET32(pData + 5);
  980.  
  981.                     FILETIME fFileTime;
  982.                     fFileTime.dwHighDateTime = timeHigh;
  983.                     fFileTime.dwLowDateTime = timeLow;
  984.  
  985.                     SYSTEMTIME sFileTime;
  986.                     FileTimeToSystemTime(&fFileTime, &sFileTime);
  987.                     
  988.                     *(q++) = ' ';
  989.                     int res = GetDateFormat(
  990.                             LOCALE_USER_DEFAULT,    // locale for which date is to be formatted
  991.                             DATE_SHORTDATE,            // flags specifying function options
  992.                             &sFileTime,                // date to be formatted
  993.                             0,                        // date format string
  994.                             q,                        // buffer for storing formatted string
  995.                             80                        // size of buffer
  996.                         );
  997.  
  998.                     if (res)
  999.                     {
  1000.                         q += res - 1;
  1001.                         *(q++) = ' ';
  1002.                     }
  1003.     
  1004.                     res = GetTimeFormat(
  1005.                             LOCALE_USER_DEFAULT,    // locale for which date is to be formatted
  1006.                             TIME_FORCE24HOURFORMAT,    // flags specifying function options
  1007.                             &sFileTime,                // date to be formatted
  1008.                             0,                        // date format string
  1009.                             q,                        // buffer for storing formatted string
  1010.                             80                        // size of buffer
  1011.                         );
  1012.  
  1013.                     if (res)
  1014.                     {
  1015.                         q += res - 1;
  1016.                         *(q++) = ' ';
  1017.                     }
  1018.  
  1019.                     memcpy(q, p, nDataLength - pos - 9);
  1020.                     q += nDataLength - pos - 9;
  1021.                     break;
  1022.                 }
  1023.                 else
  1024.                     *(q++) = *(p++);
  1025.  
  1026.                 pos++;
  1027.             }
  1028.             *q = 0;
  1029.             ShowStatusRaw(buffer, *pData);
  1030.         }
  1031.         break;
  1032.     case 7:
  1033.         if (nDataLength!=5)
  1034.             ShowStatus(_T("Protocol error: Invalid data"), 1);
  1035.         else
  1036.         {
  1037.             int nType = *pData;
  1038.             int size = (int)GET32(pData + 1);
  1039.             
  1040.             if (!nType)
  1041.             {
  1042.                 m_nRecvCount += size;
  1043.                 m_RecvLed.Ping(100);
  1044.                 CString str;
  1045.                 str.Format("%I64d bytes received", m_nRecvCount);
  1046.                 SetStatusbarText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_RECVCOUNT), str);
  1047.             }
  1048.             else
  1049.             {
  1050.                 m_nSendCount += size;
  1051.                 m_SendLed.Ping(100);
  1052.                 CString str;
  1053.                 str.Format("%I64d bytes sent", m_nSendCount);
  1054.                 SetStatusbarText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_SENDCOUNT), str);
  1055.             }
  1056.  
  1057.         }
  1058.         break;
  1059.     default:
  1060.         {
  1061.             CString str;
  1062.             str.Format(_T("Protocol error: Unexpected status id (%d)."), nStatusID);
  1063.             ShowStatus(str, 1);
  1064.         }
  1065.         break;
  1066.  
  1067.     }
  1068. }
  1069.  
  1070. BOOL CMainFrame::SendCommand(int nType)
  1071. {
  1072.     if (!m_pAdminSocket)
  1073.         return FALSE;
  1074.     if (!m_pAdminSocket->SendCommand(nType))
  1075.     {
  1076.         CloseAdminSocket();
  1077.         ShowStatus("Error: Connection to server lost...", 1);
  1078.         return FALSE;
  1079.     }
  1080.     return TRUE;
  1081. }
  1082.  
  1083. BOOL CMainFrame::SendCommand(int nType, void *pData, int nDataLength)
  1084. {
  1085.     if (!m_pAdminSocket)
  1086.         return FALSE;
  1087.     if (!m_pAdminSocket->SendCommand(nType, pData, nDataLength))
  1088.     {
  1089.         CloseAdminSocket();
  1090.         ShowStatus("Error: Connection to server lost...", 1);
  1091.         return FALSE;
  1092.     }
  1093.     return TRUE;
  1094. }
  1095.  
  1096. void CMainFrame::CloseAdminSocket(bool shouldReconnect /*=true*/)
  1097. {
  1098.     if (m_pAdminSocket)
  1099.     {
  1100.         m_pAdminSocket->DoClose();
  1101.         delete m_pAdminSocket;
  1102.         m_pAdminSocket = NULL;
  1103.         SetIcon();
  1104.     }
  1105.     m_nEdit = 0;
  1106.  
  1107.     if (!shouldReconnect)
  1108.     {
  1109.         if (m_nReconnectTimerID)
  1110.         {
  1111.             KillTimer(m_nReconnectTimerID);
  1112.             m_nReconnectTimerID = 0;
  1113.         }
  1114.     }
  1115.     else
  1116.     {
  1117.         if (!m_nReconnectTimerID)
  1118.         {
  1119.             m_nReconnectCount++;
  1120.             if (m_nReconnectCount < 15)
  1121.             {
  1122.                 ShowStatus("Trying to reconnect in 5 seconds", 0);
  1123.                 m_nReconnectTimerID = SetTimer(7779, 5000, 0);
  1124.             }
  1125.             else
  1126.                 m_nReconnectCount = 0;
  1127.         }
  1128.     }
  1129. }
  1130.  
  1131. void CMainFrame::OnFileConnect() 
  1132. {
  1133.     if (m_nReconnectTimerID)
  1134.     {
  1135.         KillTimer(m_nReconnectTimerID);
  1136.         m_nReconnectTimerID = 0;
  1137.     }
  1138.     if (m_pAdminSocket)
  1139.         if (AfxMessageBox(_T("Do you really want to close the current connection?"), MB_ICONQUESTION|MB_YESNO) != IDYES)
  1140.             return;
  1141.     CConnectDialog dlg(m_pOptions);
  1142.     if (dlg.DoModal() == IDOK)
  1143.     {
  1144.         CloseAdminSocket(false);
  1145.         m_pAdminSocket = new CAdminSocket(this);
  1146.         ShowStatus("Connecting to server...", 0);
  1147.         m_pAdminSocket->m_Password = m_pOptions->GetOption(IOPTION_LASTSERVERPASS);
  1148.         m_pAdminSocket->Create();
  1149.         if (!m_pAdminSocket->Connect(m_pOptions->GetOption(IOPTION_LASTSERVERADDRESS), (UINT)m_pOptions->GetOptionVal(IOPTION_LASTSERVERPORT)) && WSAGetLastError()!=WSAEWOULDBLOCK)
  1150.         {
  1151.             ShowStatus(_T("Error, could not connect to server"), 1);
  1152.             CloseAdminSocket();
  1153.         }
  1154.     }
  1155. }
  1156.  
  1157. void CMainFrame::OnFileDisconnect() 
  1158. {
  1159.     CloseAdminSocket(false);
  1160. }
  1161.  
  1162. void CMainFrame::OnUpdateFileDisconnect(CCmdUI* pCmdUI) 
  1163. {
  1164.     pCmdUI->Enable(m_pAdminSocket?TRUE:FALSE);    
  1165. }
  1166.  
  1167. void CMainFrame::OnUpdateEditSettings(CCmdUI* pCmdUI) 
  1168. {
  1169.     pCmdUI->Enable(m_pAdminSocket && m_pAdminSocket->IsConnected());
  1170. }
  1171.  
  1172. void CMainFrame::OnUpdateMenuEditUsers(CCmdUI* pCmdUI) 
  1173. {
  1174.     pCmdUI->Enable(m_pAdminSocket && m_pAdminSocket->IsConnected());
  1175. }
  1176.  
  1177. void CMainFrame::OnUpdateMenuEditGroups(CCmdUI* pCmdUI) 
  1178. {
  1179.     pCmdUI->Enable(m_pAdminSocket && m_pAdminSocket->IsConnected());
  1180. }
  1181.  
  1182. void CMainFrame::OnUpdateUsers(CCmdUI* pCmdUI) 
  1183. {
  1184.     pCmdUI->Enable(m_pAdminSocket && m_pAdminSocket->IsConnected());
  1185. }
  1186.  
  1187. void CMainFrame::OnUpdateGroups(CCmdUI* pCmdUI) 
  1188. {
  1189.     pCmdUI->Enable(m_pAdminSocket && m_pAdminSocket->IsConnected());
  1190. }
  1191.  
  1192. // this function gets called whenever the user decides to quit the app
  1193. // (by pressing the 'x' for example
  1194. void CMainFrame::OnDestroy() 
  1195. {
  1196.     m_pOptions->SetOption(IOPTION_USERSORTING, GetUsersPane()->m_pListCtrl->GetSortColumn() + (GetUsersPane()->m_pListCtrl->GetSortDirection() << 4));
  1197.     CloseAdminSocket(false);
  1198.     CFrameWnd::OnDestroy();
  1199. }
  1200.  
  1201. BOOL CMainFrame::OnEraseBkgnd(CDC* pDC)
  1202. {
  1203.     return TRUE;
  1204. }
  1205.  
  1206. LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  1207. {
  1208.     if (message == WM_APP)
  1209.     {
  1210.         if ((m_nEdit & 0x1C) == 0x0C)
  1211.         {
  1212.             m_nEdit |= 0x10;
  1213.             if (m_pOptionsDlg->Show())
  1214.             {
  1215.                 char *pBuffer;
  1216.                 DWORD dwBufferLength;
  1217.                 if (m_pOptionsDlg->GetAsCommand(&pBuffer, &dwBufferLength))
  1218.                 {
  1219.                     SendCommand(5, pBuffer, dwBufferLength);
  1220.                     ShowStatus(_T("Sending settings, please wait..."), 0);
  1221.                     delete [] pBuffer;
  1222.                 }
  1223.             }
  1224.             delete m_pOptionsDlg;
  1225.             m_pOptionsDlg = 0;
  1226.             m_nEdit = 0;
  1227.         }
  1228.         else if ((m_nEdit & 0x19) == 0x09)
  1229.         {
  1230.             m_nEdit |= 0x10;
  1231.             if (m_pUsersDlg->DoModal() == IDOK)
  1232.             {
  1233.                 char *pBuffer;
  1234.                 DWORD dwBufferLength;
  1235.                 if (m_pUsersDlg->GetAsCommand(&pBuffer, &dwBufferLength))
  1236.                 {
  1237.                     SendCommand(6, pBuffer, dwBufferLength);
  1238.                     ShowStatus(_T("Sending account settings, please wait..."), 0);
  1239.                     delete [] pBuffer;
  1240.                 }
  1241.             }
  1242.             delete m_pUsersDlg;
  1243.             m_pUsersDlg = 0;
  1244.             m_nEdit = 0;
  1245.         }
  1246.         else if ((m_nEdit & 0x1A) == 0x0A)
  1247.         {
  1248.             m_nEdit |= 0x10;
  1249.             if (m_pGroupsDlg->DoModal() == IDOK)
  1250.             {
  1251.                 char *pBuffer;
  1252.                 DWORD dwBufferLength;
  1253.                 if (m_pGroupsDlg->GetAsCommand(&pBuffer, &dwBufferLength))
  1254.                 {
  1255.                     SendCommand(6, pBuffer, dwBufferLength);
  1256.                     ShowStatus(_T("Sending account settings, please wait..."), 0);
  1257.                     delete [] pBuffer;
  1258.                 }
  1259.             }
  1260.             delete m_pGroupsDlg;
  1261.             m_pGroupsDlg = 0;
  1262.             m_nEdit = 0;
  1263.         }
  1264.     }
  1265.     else if (message == WM_APP + 1)
  1266.         OnAdminInterfaceClosed();
  1267.     
  1268.     return CFrameWnd::DefWindowProc(message, wParam, lParam);
  1269. }
  1270.  
  1271. void CMainFrame::OnAdminInterfaceConnected()
  1272. {
  1273.     m_nReconnectCount = 0;
  1274. }
  1275.  
  1276. void CMainFrame::OnAdminInterfaceClosed()
  1277. {
  1278.     if (m_pAdminSocket && m_pAdminSocket->IsClosed())
  1279.     {
  1280.         CloseAdminSocket();
  1281.     }
  1282. }
  1283.  
  1284. void CMainFrame::OnDisplayLogicalNames()
  1285. {
  1286.     GetUsersPane()->m_pListCtrl->SetDisplayPhysicalNames(false);
  1287.     m_pOptions->SetOption(IOPTION_FILENAMEDISPLAY, 0);
  1288. }
  1289.  
  1290. void CMainFrame::OnDisplayPhysicalNames()
  1291. {
  1292.     GetUsersPane()->m_pListCtrl->SetDisplayPhysicalNames(true);
  1293.     m_pOptions->SetOption(IOPTION_FILENAMEDISPLAY, 1);
  1294. }
  1295.  
  1296. void CMainFrame::OnUpdateDisplayLogicalNames(CCmdUI* pCmdUI)
  1297. {
  1298.     pCmdUI->SetRadio(!GetUsersPane()->m_pListCtrl->GetDisplayPhysicalNames());
  1299. }
  1300.  
  1301. void CMainFrame::OnUpdateDisplayPhysicalNames(CCmdUI* pCmdUI)
  1302. {
  1303.     pCmdUI->SetRadio(GetUsersPane()->m_pListCtrl->GetDisplayPhysicalNames());
  1304. }
  1305.  
  1306. void CMainFrame::OnDisplaySortMenu()
  1307. {
  1308.     // load and display popup menu
  1309.     CMenu menu;
  1310.     menu.LoadMenu(IDR_SORTMENU);
  1311.     CMenu* pPopup = menu.GetSubMenu(0);
  1312.     ASSERT(pPopup);
  1313.  
  1314.     CRect rc;
  1315.     m_wndUserListToolBar.GetItemRect(m_wndUserListToolBar.CommandToIndex(ID_USERLISTTOOLBAR_SORT), &rc);
  1316.     m_wndUserListToolBar.ClientToScreen(&rc);
  1317.  
  1318.     pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
  1319.         rc.left, rc.bottom, this, &rc);
  1320. }
  1321.  
  1322. void CMainFrame::OnToolbarDropDown(NMHDR* pnmh, LRESULT* plRes)
  1323. {
  1324.     NMTOOLBAR* pnmtb = (NMTOOLBAR*)pnmh;
  1325.     if (pnmtb->iItem == ID_USERLISTTOOLBAR_SORT)
  1326.         OnDisplaySortMenu();
  1327. }
  1328.  
  1329. void CMainFrame::OnDisplaySortByUserid()
  1330. {
  1331.     GetUsersPane()->m_pListCtrl->SetSortColumn(0);
  1332. }
  1333.  
  1334. void CMainFrame::OnDisplaySortByAccount()
  1335. {
  1336.     GetUsersPane()->m_pListCtrl->SetSortColumn(1);
  1337. }
  1338.  
  1339. void CMainFrame::OnDisplaySortByIP()
  1340. {
  1341.     GetUsersPane()->m_pListCtrl->SetSortColumn(2);
  1342. }
  1343.  
  1344. void CMainFrame::OnUpdateDisplaySortByUserid(CCmdUI* pCmdUI)
  1345. {
  1346.     pCmdUI->SetRadio(GetUsersPane()->m_pListCtrl->GetSortColumn() == 0);
  1347. }
  1348.  
  1349. void CMainFrame::OnUpdateDisplaySortByAccount(CCmdUI* pCmdUI)
  1350. {
  1351.     pCmdUI->SetRadio(GetUsersPane()->m_pListCtrl->GetSortColumn() == 1);
  1352. }
  1353.  
  1354. void CMainFrame::OnUpdateDisplaySortByIP(CCmdUI* pCmdUI)
  1355. {
  1356.     pCmdUI->SetRadio(GetUsersPane()->m_pListCtrl->GetSortColumn() == 3);
  1357. }
  1358.