plugins/consoles/rcons/server/win32/Server.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // Server.cpp
       
     2 // 
       
     3 // Copyright (c) 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include "Misc.h"
       
    14 #include "stdafx.h"
       
    15 #include "console_host.h"
       
    16 #include "Server.h"
       
    17 #include "ConsoleWindow.h"
       
    18 #include "RemoteConsole.h"
       
    19 
       
    20 const int KMajorVersion = 1;
       
    21 const int KServerInitParam = ID_RC_CLOSE - 1;
       
    22 static CServer* sServer = NULL;
       
    23 LPCTSTR KServerWindowClassName = TEXT("ServerWindowClass");
       
    24 LPCTSTR KServerConsoleName = TEXT("Server Console");
       
    25 LPCTSTR KServerSocketName = TEXT("Server Socket");
       
    26 
       
    27 
       
    28 class TCreateConsoleWindowPacket
       
    29 	{
       
    30 public:
       
    31 	void Validate() const;
       
    32 public:
       
    33 	int iMajorVersion;
       
    34 	int iMinorVersion;
       
    35 	int iWidth;
       
    36 	int iHeight;
       
    37 	int iTitleLength;
       
    38 	};
       
    39 
       
    40 void TCreateConsoleWindowPacket::Validate() const
       
    41 	{
       
    42 	if (iMajorVersion > KMajorVersion)
       
    43 		{
       
    44 		throw KExceptionInvalidClientVersion;
       
    45 		}
       
    46 	}
       
    47 
       
    48 
       
    49 CServer* CServer::New(HINSTANCE aAppHandle)
       
    50 	{
       
    51 	std::auto_ptr<CServer> self(new(EThrow) CServer(aAppHandle));
       
    52 	self->Construct();
       
    53 	return self.release();
       
    54 	}
       
    55 
       
    56 CServer::~CServer()
       
    57 	{
       
    58 	delete iSocket;
       
    59 	delete iConsole;
       
    60 	}
       
    61 
       
    62 void CServer::HandleException(TException aException)
       
    63 	{
       
    64 	switch (aException)
       
    65 		{
       
    66 		case KExceptionNoMemory:
       
    67 			iConsole->Write(TEXT("Out of memory\r\n"));
       
    68 			break;
       
    69 		case KExceptionWindowConstructFailed:
       
    70 			iConsole->Write(TEXT("Failed to construct new window\r\n"));
       
    71 			break;
       
    72 		case KExceptionConsoleWindowConstructFailed:
       
    73 			iConsole->Write(TEXT("Failed to construct new console window\r\n"));
       
    74 			break;
       
    75 		case KExceptionSocketConstructFailed:
       
    76 			iConsole->Write(TEXT("Failed to construct new socket\r\n"));
       
    77 			break;
       
    78 		case KExceptionSocketBindFailed:
       
    79 			iConsole->Write(TEXT("Failed to bind server socket. Is something else already listening on that port?\r\n"));
       
    80 			break;
       
    81 		case KExceptionSocketListenFailed:
       
    82 			iConsole->Write(TEXT("Failed to listen on server socket\r\n"));
       
    83 			break;
       
    84 		case KExceptionSocketSelectFailed:
       
    85 			iConsole->Write(TEXT("Failed to asynchronously wait on socket\r\n"));
       
    86 			break;
       
    87 		case KExceptionSocketAcceptFailed:
       
    88 			iConsole->Write(TEXT("Failed to accept to client connection\r\n"));
       
    89 			break;
       
    90 		case KExceptionSocketReadFailed:
       
    91 			iConsole->Write(TEXT("Failed to read from socket\r\n"));
       
    92 			break;
       
    93 		case KExceptionInvalidClientVersion:
       
    94 			iConsole->Write(TEXT("Invalid client version\r\n"));
       
    95 			break;
       
    96 		case KExceptionFailedToWritePrefsFile:
       
    97 			iConsole->Write(TEXT("Failed to write preferences file\r\n"));
       
    98 			break;
       
    99 		default:
       
   100 			iConsole->Write(TEXT("Unknown error\r\n"));
       
   101 			break;
       
   102 		}
       
   103 	}
       
   104 
       
   105 TPreferences& CServer::Preferences()
       
   106 	{
       
   107 	return iPreferences;
       
   108 	}
       
   109 
       
   110 const TPreferences& CServer::Preferences() const
       
   111 	{
       
   112 	return iPreferences;
       
   113 	}
       
   114 
       
   115 CServer::CServer(HINSTANCE aAppHandle) : iAppHandle(aAppHandle), iSocket(NULL), iConsole(NULL), iPort(0)
       
   116 	{
       
   117 	sServer = this;
       
   118 	}
       
   119 
       
   120 void CServer::Construct()
       
   121 	{
       
   122 	WNDCLASSEX wcex;
       
   123 	wcex.cbSize = sizeof(WNDCLASSEX); 
       
   124 	wcex.style			= CS_HREDRAW | CS_VREDRAW;
       
   125 	wcex.lpfnWndProc	= (WNDPROC)CWindow::HandleMessage;
       
   126 	wcex.cbClsExtra		= 0;
       
   127 	wcex.cbWndExtra		= 0;
       
   128 	wcex.hInstance		= iAppHandle;
       
   129 	wcex.hIcon			= LoadIcon(iAppHandle, (LPCTSTR)IDI_CONSOLE_HOST);
       
   130 	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
       
   131 	wcex.hbrBackground	= NULL;
       
   132 	wcex.lpszMenuName	= (LPCTSTR)ID_SERVER_MENU;
       
   133 	wcex.lpszClassName	= KServerWindowClassName;
       
   134 	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
       
   135 	if (RegisterClassEx(&wcex) == 0)
       
   136 		{
       
   137 		throw KExceptionWindowClassRegistrationFailed;
       
   138 		}
       
   139 	
       
   140 	iConsole = CConsoleWindow::New(iAppHandle, KServerWindowClassName, TEXT("Remote Console Server"), CW_USEDEFAULT, CW_USEDEFAULT, 40, 20, 20, this, NULL, TRUE);
       
   141 	iConsole->SetName(KServerConsoleName);
       
   142 
       
   143 	try
       
   144 		{
       
   145 		iPreferences.Read();
       
   146 		}
       
   147 	catch (...)
       
   148 		{
       
   149 		iConsole->Write(TEXT("Unable to read preferences"));
       
   150 		}
       
   151 
       
   152 	iSocket = CServerSocket::New(*iConsole);
       
   153 	iSocket->SetName(KServerSocketName);
       
   154 	PostMessage(iConsole->Handle(), WM_COMMAND, KServerInitParam, 0);
       
   155 	}
       
   156 
       
   157 void CServer::Listen()
       
   158 	{
       
   159 	if (iPort != iPreferences.ServerPort())
       
   160 		{
       
   161 		delete iSocket;
       
   162 		iSocket = CServerSocket::New(*iConsole);
       
   163 		iSocket->SetName(KServerSocketName);
       
   164 		iSocket->Listen(iPreferences.ServerPort(), 5, *this);
       
   165 		iConsole->WriteFormat(TEXT("Listening on port %d\r\n"), iPreferences.ServerPort());
       
   166 		iPort = iPreferences.ServerPort();
       
   167 		}
       
   168 	}
       
   169 
       
   170 void CServer::HandleNewClient(CClientSocket& aClientSocket)
       
   171 	{
       
   172 	CSocketCommandReader* commandReader = CSocketCommandReader::New(aClientSocket, *this);
       
   173 	commandReader->ReadCommand();
       
   174 	}
       
   175 
       
   176 void CServer::HandleSocketClosure(CSocket& aSocket)
       
   177 	{
       
   178 	ASSERT(&aSocket == iSocket);
       
   179 	PostQuitMessage(0);
       
   180 	}
       
   181 
       
   182 void CServer::HandleSocketCommand(TPacketHeader::TPacketType aCommand, const char* aPacket, int aPacketLength, CSocketCommandReader& aReader)
       
   183 	{
       
   184 	switch (aCommand)
       
   185 		{
       
   186 		case TPacketHeader::ECommandCreateConsoleWindow:
       
   187 			{
       
   188 			iConsole->Write(TEXT("Creating new console window...\r\n"));
       
   189 			const TCreateConsoleWindowPacket* createConsoleWindowPacket = new((char*)aPacket) TCreateConsoleWindowPacket;
       
   190 			LPTSTR title = (TCHAR*)((char*)aPacket + sizeof(TCreateConsoleWindowPacket));
       
   191 			try
       
   192 				{
       
   193 				createConsoleWindowPacket->Validate();
       
   194 				CRemoteConsole* remoteConsole = CRemoteConsole::New(iAppHandle, aReader, title, createConsoleWindowPacket->iWidth, createConsoleWindowPacket->iHeight, iPreferences);
       
   195 				int consoleId = remoteConsole->Id();
       
   196 				iConsole->WriteFormat(TEXT("Created window \"%s\" (%d)...\r\n"), title, consoleId);
       
   197 				aReader.SendResponse((char*)&consoleId, sizeof(int));
       
   198 				}
       
   199 			catch (TException aException)
       
   200 				{
       
   201 				int err = -2; // KErrGeneral.
       
   202 				if (aException == KExceptionInvalidClientVersion)
       
   203 					{
       
   204 					err = -21; // KErrAccessDenied.
       
   205 					}
       
   206 				aReader.SendResponse((char*)&err, sizeof(int));
       
   207 				delete &aReader;
       
   208 				throw aException;
       
   209 				}
       
   210 			catch (...)
       
   211 				{
       
   212 				delete &aReader;
       
   213 				throw KExceptionUnknown;
       
   214 				}
       
   215 			break;
       
   216 			}
       
   217 		case TPacketHeader::ECommandAttachKeyEventSocket:
       
   218 			{
       
   219 			iConsole->Write(TEXT("Attaching key event socket...\r\n"));
       
   220 			int* consoleId = new((char*)aPacket) int;
       
   221 			CRemoteConsole* remoteConsole = CRemoteConsole::Instance(*consoleId);
       
   222 			if (remoteConsole)
       
   223 				{
       
   224 				remoteConsole->AttachKeyEventSocket(aReader.ReleaseSocket());
       
   225 				iConsole->WriteFormat(TEXT("Attached key event socket to window %d...\r\n"), *consoleId);
       
   226 				}
       
   227 			delete &aReader;
       
   228 			break;
       
   229 			}
       
   230 		default:
       
   231 			{
       
   232 			iConsole->WriteFormat(TEXT("Invalid server socket command: %d\r\n"), aCommand);
       
   233 			delete &aReader;
       
   234 			break;
       
   235 			}
       
   236 		}
       
   237 	}
       
   238 
       
   239 void CServer::HandleSocketClosure(CSocketCommandReader& aReader)
       
   240 	{
       
   241 	delete &aReader;
       
   242 	}
       
   243 
       
   244 void CServer::HandleWindowClosure(CWindow& aWindow)
       
   245 	{
       
   246 	ASSERT(&aWindow == iConsole);
       
   247 	PostQuitMessage(0);
       
   248 	}
       
   249 
       
   250 LRESULT CALLBACK PrefsCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       
   251 	{
       
   252 	switch (message)
       
   253 		{
       
   254 		case WM_INITDIALOG:
       
   255 			TCHAR string[128];
       
   256 			swprintf(string, TEXT("%u"), sServer->Preferences().ServerPort());
       
   257 			SetDlgItemText(hDlg, ID_EDIT_PORT, string);
       
   258 			swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowWidth());
       
   259 			SetDlgItemText(hDlg, ID_EDIT_WIN_WIDTH, string);
       
   260 			swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowHeight());
       
   261 			SetDlgItemText(hDlg, ID_EDIT_WIN_HEIGHT, string);
       
   262 			swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowPosX());
       
   263 			SetDlgItemText(hDlg, ID_EDIT_WIN_POS_X, string);
       
   264 			swprintf(string, TEXT("%u"), sServer->Preferences().DefaultWindowPosY());
       
   265 			SetDlgItemText(hDlg, ID_EDIT_WIN_POS_Y, string);
       
   266 			EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_X), !sServer->Preferences().SystemPositionedWindows());
       
   267 			EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_Y), !sServer->Preferences().SystemPositionedWindows());
       
   268 			CheckDlgButton(hDlg, ID_CHECK_WIN_POS, sServer->Preferences().SystemPositionedWindows());
       
   269 			swprintf(string, TEXT("%u"), sServer->Preferences().NumOverflowLines());
       
   270 			SetDlgItemText(hDlg, ID_OVERFLOW_LINES, string);
       
   271 			return TRUE;
       
   272 		case WM_COMMAND:
       
   273 			switch (LOWORD(wParam))
       
   274 				{
       
   275 				case IDOK:
       
   276 					{
       
   277 					TCHAR string[128];
       
   278 					GetDlgItemText(hDlg, ID_EDIT_PORT, string, 128);
       
   279 					unsigned int val;
       
   280 					swscanf(string, TEXT("%u"), &val);
       
   281 					sServer->Preferences().SetServerPort((unsigned short)val);
       
   282 					GetDlgItemText(hDlg, ID_EDIT_WIN_WIDTH, string, 128);
       
   283 					swscanf(string, TEXT("%u"), &val);
       
   284 					sServer->Preferences().SetDefaultWindowWidth(val);
       
   285 					GetDlgItemText(hDlg, ID_EDIT_WIN_HEIGHT, string, 128);
       
   286 					swscanf(string, TEXT("%u"), &val);
       
   287 					sServer->Preferences().SetDefaultWindowHeight(val);
       
   288 					GetDlgItemText(hDlg, ID_EDIT_WIN_POS_X, string, 128);
       
   289 					swscanf(string, TEXT("%u"), &val);
       
   290 					sServer->Preferences().SetDefaultWindowPosX(val);
       
   291 					GetDlgItemText(hDlg, ID_EDIT_WIN_POS_Y, string, 128);
       
   292 					swscanf(string, TEXT("%u"), &val);
       
   293 					sServer->Preferences().SetDefaultWindowPosY(val);
       
   294 					GetDlgItemText(hDlg, ID_OVERFLOW_LINES, string, 128);
       
   295 					swscanf(string, TEXT("%u"), &val);
       
   296 					sServer->Preferences().SetNumOverflowLines(val);
       
   297 					sServer->Preferences().SetSystemPositionedWindows((IsDlgButtonChecked(hDlg, ID_CHECK_WIN_POS) == BST_CHECKED) ? TRUE : FALSE);
       
   298 					sServer->Preferences().Write();
       
   299 					sServer->Listen();
       
   300 					}	// Deliberate fall through.
       
   301 				case IDCANCEL:
       
   302 					{
       
   303 					EndDialog(hDlg, LOWORD(wParam));
       
   304 					return TRUE;
       
   305 					}
       
   306 				case ID_CHECK_WIN_POS:
       
   307 					{
       
   308 					int isChecked = IsDlgButtonChecked(hDlg, ID_CHECK_WIN_POS);
       
   309 					EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_X), !isChecked);
       
   310 					EnableWindow(GetDlgItem(hDlg, ID_EDIT_WIN_POS_Y), !isChecked);
       
   311 					break;
       
   312 					}
       
   313 				}
       
   314 			break;
       
   315 		}
       
   316     return FALSE;
       
   317 	}
       
   318 
       
   319 LRESULT CServer::HandleWindowCommand(UINT aMessage, WPARAM aWParam, LPARAM aLParam)
       
   320 	{
       
   321 	int wmId = LOWORD(aWParam); 
       
   322 	int wmEvent = HIWORD(aWParam); 
       
   323 	switch (wmId)
       
   324 		{
       
   325 		case KServerInitParam:
       
   326 			Listen();
       
   327 			break;
       
   328 		case ID_PREFS:
       
   329 			DialogBox(iAppHandle, (LPCTSTR)IDD_PREFS_DIALOG, iConsole->Handle(), (DLGPROC)PrefsCallback);
       
   330 			break;
       
   331 		default:
       
   332 			return DefWindowProc(iConsole->Handle(), aMessage, aWParam, aLParam);
       
   333 		}
       
   334 	return 0;
       
   335 	}