--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/rcons/server/win32/Server.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,335 @@
+// Server.cpp
+//
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+#include "Misc.h"
+#include "stdafx.h"
+#include "console_host.h"
+#include "Server.h"
+#include "ConsoleWindow.h"
+#include "RemoteConsole.h"
+
+const int KMajorVersion = 1;
+const int KServerInitParam = ID_RC_CLOSE - 1;
+static CServer* sServer = NULL;
+LPCTSTR KServerWindowClassName = TEXT("ServerWindowClass");
+LPCTSTR KServerConsoleName = TEXT("Server Console");
+LPCTSTR KServerSocketName = TEXT("Server Socket");
+
+
+class TCreateConsoleWindowPacket
+ {
+public:
+ void Validate() const;
+public:
+ int iMajorVersion;
+ int iMinorVersion;
+ int iWidth;
+ int iHeight;
+ int iTitleLength;
+ };
+
+void TCreateConsoleWindowPacket::Validate() const
+ {
+ if (iMajorVersion > KMajorVersion)
+ {
+ throw KExceptionInvalidClientVersion;
+ }
+ }
+
+
+CServer* CServer::New(HINSTANCE aAppHandle)
+ {
+ std::auto_ptr<CServer> self(new(EThrow) CServer(aAppHandle));
+ self->Construct();
+ return self.release();
+ }
+
+CServer::~CServer()
+ {
+ delete iSocket;
+ delete iConsole;
+ }
+
+void CServer::HandleException(TException aException)
+ {
+ switch (aException)
+ {
+ case KExceptionNoMemory:
+ iConsole->Write(TEXT("Out of memory\r\n"));
+ break;
+ case KExceptionWindowConstructFailed:
+ iConsole->Write(TEXT("Failed to construct new window\r\n"));
+ break;
+ case KExceptionConsoleWindowConstructFailed:
+ iConsole->Write(TEXT("Failed to construct new console window\r\n"));
+ break;
+ case KExceptionSocketConstructFailed:
+ iConsole->Write(TEXT("Failed to construct new socket\r\n"));
+ break;
+ case KExceptionSocketBindFailed:
+ iConsole->Write(TEXT("Failed to bind server socket. Is something else already listening on that port?\r\n"));
+ break;
+ case KExceptionSocketListenFailed:
+ iConsole->Write(TEXT("Failed to listen on server socket\r\n"));
+ break;
+ case KExceptionSocketSelectFailed:
+ iConsole->Write(TEXT("Failed to asynchronously wait on socket\r\n"));
+ break;
+ case KExceptionSocketAcceptFailed:
+ iConsole->Write(TEXT("Failed to accept to client connection\r\n"));
+ break;
+ case KExceptionSocketReadFailed:
+ iConsole->Write(TEXT("Failed to read from socket\r\n"));
+ break;
+ case KExceptionInvalidClientVersion:
+ iConsole->Write(TEXT("Invalid client version\r\n"));
+ break;
+ case KExceptionFailedToWritePrefsFile:
+ iConsole->Write(TEXT("Failed to write preferences file\r\n"));
+ break;
+ default:
+ iConsole->Write(TEXT("Unknown error\r\n"));
+ break;
+ }
+ }
+
+TPreferences& CServer::Preferences()
+ {
+ return iPreferences;
+ }
+
+const TPreferences& CServer::Preferences() const
+ {
+ return iPreferences;
+ }
+
+CServer::CServer(HINSTANCE aAppHandle) : iAppHandle(aAppHandle), iSocket(NULL), iConsole(NULL), iPort(0)
+ {
+ sServer = this;
+ }
+
+void CServer::Construct()
+ {
+ WNDCLASSEX wcex;
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = (WNDPROC)CWindow::HandleMessage;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = iAppHandle;
+ wcex.hIcon = LoadIcon(iAppHandle, (LPCTSTR)IDI_CONSOLE_HOST);
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = NULL;
+ wcex.lpszMenuName = (LPCTSTR)ID_SERVER_MENU;
+ wcex.lpszClassName = KServerWindowClassName;
+ wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
+ if (RegisterClassEx(&wcex) == 0)
+ {
+ throw KExceptionWindowClassRegistrationFailed;
+ }
+
+ iConsole = CConsoleWindow::New(iAppHandle, KServerWindowClassName, TEXT("Remote Console Server"), CW_USEDEFAULT, CW_USEDEFAULT, 40, 20, 20, this, NULL, TRUE);
+ iConsole->SetName(KServerConsoleName);
+
+ try
+ {
+ iPreferences.Read();
+ }
+ catch (...)
+ {
+ iConsole->Write(TEXT("Unable to read preferences"));
+ }
+
+ iSocket = CServerSocket::New(*iConsole);
+ iSocket->SetName(KServerSocketName);
+ PostMessage(iConsole->Handle(), WM_COMMAND, KServerInitParam, 0);
+ }
+
+void CServer::Listen()
+ {
+ if (iPort != iPreferences.ServerPort())
+ {
+ delete iSocket;
+ iSocket = CServerSocket::New(*iConsole);
+ iSocket->SetName(KServerSocketName);
+ iSocket->Listen(iPreferences.ServerPort(), 5, *this);
+ iConsole->WriteFormat(TEXT("Listening on port %d\r\n"), iPreferences.ServerPort());
+ iPort = iPreferences.ServerPort();
+ }
+ }
+
+void CServer::HandleNewClient(CClientSocket& aClientSocket)
+ {
+ CSocketCommandReader* commandReader = CSocketCommandReader::New(aClientSocket, *this);
+ commandReader->ReadCommand();
+ }
+
+void CServer::HandleSocketClosure(CSocket& aSocket)
+ {
+ ASSERT(&aSocket == iSocket);
+ PostQuitMessage(0);
+ }
+
+void CServer::HandleSocketCommand(TPacketHeader::TPacketType aCommand, const char* aPacket, int aPacketLength, CSocketCommandReader& aReader)
+ {
+ switch (aCommand)
+ {
+ case TPacketHeader::ECommandCreateConsoleWindow:
+ {
+ iConsole->Write(TEXT("Creating new console window...\r\n"));
+ const TCreateConsoleWindowPacket* createConsoleWindowPacket = new((char*)aPacket) TCreateConsoleWindowPacket;
+ LPTSTR title = (TCHAR*)((char*)aPacket + sizeof(TCreateConsoleWindowPacket));
+ try
+ {
+ createConsoleWindowPacket->Validate();
+ CRemoteConsole* remoteConsole = CRemoteConsole::New(iAppHandle, aReader, title, createConsoleWindowPacket->iWidth, createConsoleWindowPacket->iHeight, iPreferences);
+ int consoleId = remoteConsole->Id();
+ iConsole->WriteFormat(TEXT("Created window \"%s\" (%d)...\r\n"), title, consoleId);
+ aReader.SendResponse((char*)&consoleId, sizeof(int));
+ }
+ catch (TException aException)
+ {
+ int err = -2; // KErrGeneral.
+ if (aException == KExceptionInvalidClientVersion)
+ {
+ err = -21; // KErrAccessDenied.
+ }
+ aReader.SendResponse((char*)&err, sizeof(int));
+ delete &aReader;
+ throw aException;
+ }
+ catch (...)
+ {
+ delete &aReader;
+ throw KExceptionUnknown;
+ }
+ break;
+ }
+ case TPacketHeader::ECommandAttachKeyEventSocket:
+ {
+ iConsole->Write(TEXT("Attaching key event socket...\r\n"));
+ int* consoleId = new((char*)aPacket) int;
+ CRemoteConsole* remoteConsole = CRemoteConsole::Instance(*consoleId);
+ if (remoteConsole)
+ {
+ remoteConsole->AttachKeyEventSocket(aReader.ReleaseSocket());
+ iConsole->WriteFormat(TEXT("Attached key event socket to window %d...\r\n"), *consoleId);
+ }
+ delete &aReader;
+ break;
+ }
+ default:
+ {
+ iConsole->WriteFormat(TEXT("Invalid server socket command: %d\r\n"), aCommand);
+ delete &aReader;
+ break;
+ }
+ }
+ }
+
+void CServer::HandleSocketClosure(CSocketCommandReader& aReader)
+ {
+ delete &aReader;
+ }
+
+void CServer::HandleWindowClosure(CWindow& aWindow)
+ {
+ ASSERT(&aWindow == iConsole);
+ PostQuitMessage(0);
+ }
+
+LRESULT CALLBACK PrefsCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+ {
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ TCHAR string[128];
+ swprintf(string, TEXT("%u"), sServer->Preferences().ServerPort());
+ SetDlgItemText(hDlg, ID_EDIT_PORT, string);
+ swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowWidth());
+ SetDlgItemText(hDlg, ID_EDIT_WIN_WIDTH, string);
+ swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowHeight());
+ SetDlgItemText(hDlg, ID_EDIT_WIN_HEIGHT, string);
+ swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowPosX());
+ SetDlgItemText(hDlg, ID_EDIT_WIN_POS_X, string);
+ swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowPosY());
+ SetDlgItemText(hDlg, ID_EDIT_WIN_POS_Y, string);
+ EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_X), !sServer->Preferences().SystemPositionedWindows());
+ EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_Y), !sServer->Preferences().SystemPositionedWindows());
+ CheckDlgButton(hDlg, ID_CHECK_WIN_POS, sServer->Preferences().SystemPositionedWindows());
+ swprintf(string, TEXT("%u"), sServer->Preferences().NumOverflowLines());
+ SetDlgItemText(hDlg, ID_OVERFLOW_LINES, string);
+ return TRUE;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ {
+ TCHAR string[128];
+ GetDlgItemText(hDlg, ID_EDIT_PORT, string, 128);
+ unsigned int val;
+ swscanf(string, TEXT("%u"), &val);
+ sServer->Preferences().SetServerPort((unsigned short)val);
+ GetDlgItemText(hDlg, ID_EDIT_WIN_WIDTH, string, 128);
+ swscanf(string, TEXT("%u"), &val);
+ sServer->Preferences().SetDefaultWindowWidth(val);
+ GetDlgItemText(hDlg, ID_EDIT_WIN_HEIGHT, string, 128);
+ swscanf(string, TEXT("%u"), &val);
+ sServer->Preferences().SetDefaultWindowHeight(val);
+ GetDlgItemText(hDlg, ID_EDIT_WIN_POS_X, string, 128);
+ swscanf(string, TEXT("%u"), &val);
+ sServer->Preferences().SetDefaultWindowPosX(val);
+ GetDlgItemText(hDlg, ID_EDIT_WIN_POS_Y, string, 128);
+ swscanf(string, TEXT("%u"), &val);
+ sServer->Preferences().SetDefaultWindowPosY(val);
+ GetDlgItemText(hDlg, ID_OVERFLOW_LINES, string, 128);
+ swscanf(string, TEXT("%u"), &val);
+ sServer->Preferences().SetNumOverflowLines(val);
+ sServer->Preferences().SetSystemPositionedWindows((IsDlgButtonChecked(hDlg, ID_CHECK_WIN_POS) == BST_CHECKED) ? TRUE : FALSE);
+ sServer->Preferences().Write();
+ sServer->Listen();
+ } // Deliberate fall through.
+ case IDCANCEL:
+ {
+ EndDialog(hDlg, LOWORD(wParam));
+ return TRUE;
+ }
+ case ID_CHECK_WIN_POS:
+ {
+ int isChecked = IsDlgButtonChecked(hDlg, ID_CHECK_WIN_POS);
+ EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_X), !isChecked);
+ EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_Y), !isChecked);
+ break;
+ }
+ }
+ break;
+ }
+ return FALSE;
+ }
+
+LRESULT CServer::HandleWindowCommand(UINT aMessage, WPARAM aWParam, LPARAM aLParam)
+ {
+ int wmId = LOWORD(aWParam);
+ int wmEvent = HIWORD(aWParam);
+ switch (wmId)
+ {
+ case KServerInitParam:
+ Listen();
+ break;
+ case ID_PREFS:
+ DialogBox(iAppHandle, (LPCTSTR)IDD_PREFS_DIALOG, iConsole->Handle(), (DLGPROC)PrefsCallback);
+ break;
+ default:
+ return DefWindowProc(iConsole->Handle(), aMessage, aWParam, aLParam);
+ }
+ return 0;
+ }