diff -r 000000000000 -r 7f656887cf89 plugins/consoles/rcons/server/win32/Server.cpp --- /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 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; + }