- Use the Wine spooler service as the service entry template as I was

testing on Wine. (Disabled to allow stand alone build while we wait on 
AFD fix)
- Move some stuff around to the header to prepare for later cleanups


svn path=/trunk/; revision=39429
This commit is contained in:
Steven Edwards 2009-02-06 06:45:54 +00:00
parent d0c78a0f46
commit 321bf76918
3 changed files with 184 additions and 156 deletions

View file

@ -1,86 +1,111 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/TelnetD/TelnetD.c
* PURPOSE: Printer spooler
* PROGRAMMER: Eric Kohl
* Copyright 2007 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* INCLUDES *****************************************************************/
#include "telnetd.h"
#define DPRINT printf
/* GLOBALS ******************************************************************/
#define SERVICE_NAME TEXT("TelnetD")
SERVICE_STATUS_HANDLE ServiceStatusHandle;
/* FUNCTIONS *****************************************************************/
#if 0
static DWORD WINAPI
ServiceControlHandler(DWORD dwControl,
DWORD dwEventType,
LPVOID lpEventData,
LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
return ERROR_SUCCESS;
#define WIN32_LEAN_AND_MEAN
default :
return ERROR_CALL_NOT_IMPLEMENTED;
#include <windows.h>
#define WINE_FIXME printf
#define WINE_TRACE printf
//#include "wine/debug.h"
//WINE_DEFAULT_DEBUG_CHANNEL(spoolsv);
static WCHAR telnetdW[] = {'T','e','l','n','e','t','D',0};
static SERVICE_STATUS_HANDLE service_handle;
static HANDLE stop_event;
static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
{
SERVICE_STATUS status;
status.dwServiceType = SERVICE_WIN32;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
switch(ctrl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
WINE_TRACE( "shutting down\n" );
status.dwCurrentState = SERVICE_STOP_PENDING;
status.dwControlsAccepted = 0;
SetServiceStatus( service_handle, &status );
SetEvent( stop_event );
return NO_ERROR;
default:
WINE_FIXME( "got service ctrl %x\n", ctrl );
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus( service_handle, &status );
return NO_ERROR;
}
}
static VOID CALLBACK
ServiceMain(DWORD argc, LPTSTR *argv)
static void WINAPI serv_main(DWORD argc, LPWSTR *argv)
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
SERVICE_STATUS status;
int retval;
DPRINT("ServiceMain() called\n");
WINE_TRACE( "starting service\n" );
ServiceStatusHandle = RegisterServiceCtrlHandlerExW(SERVICE_NAME,
ServiceControlHandler,
NULL);
stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
DPRINT("ServiceMain() done\n");
service_handle = RegisterServiceCtrlHandlerExW( telnetdW, service_handler, NULL );
if (!service_handle)
return;
status.dwServiceType = SERVICE_WIN32;
status.dwCurrentState = SERVICE_RUNNING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 10000;
SetServiceStatus( service_handle, &status );
/* Argument Ignored for now */
retval = kickoff_telnetd();
WaitForSingleObject( stop_event, INFINITE );
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = 0;
SetServiceStatus( service_handle, &status );
WINE_TRACE( "service stopped\n" );
}
#endif
int
main(int argc, CHAR *argv[])
int main(int argc, char **argv)
{
#if 0
SERVICE_TABLE_ENTRY ServiceTable[2] =
{
{SERVICE_NAME, ServiceMain},
static const SERVICE_TABLE_ENTRYW servtbl[] = {
{telnetdW, serv_main},
{NULL, NULL}
};
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
DPRINT("TelnetD: main() started\n");
StartServiceCtrlDispatcher(ServiceTable);
#endif
telnetd_main();
DPRINT("TelnetD: main() done\n");
ExitThread(0);
WINE_TRACE("(%d %p)\n", argc, argv);
StartServiceCtrlDispatcherW(servtbl);
return 0;
}
#endif
/* EOF */

View file

@ -1,6 +1,4 @@
/*
* File: TelnetD.c
*
* Abstract: a simple telnet 'daemon' for Windows hosts.
*
* Compiled & run successfully using MSVC 5.0 under Windows95 (requires
@ -16,100 +14,30 @@
* TODO:
* - access control
* - will/won't handshake
* - (run as) Windows NT service
* - Unify Debugging output and return StatusCodes
*/
#include <stdio.h>
#include <windows.h>
#include <windows.h>
/*
** macro definitions
*/
#define TELNET_PORT (23)
#include "telnetd.h"
#define BUFSIZE (4096)
#define USERID_SIZE (64)
#define CTRLC (3)
#define BS (8)
#define CR (13)
#define LF (10)
#define DEL (127)
#define IAC "\xff"
#define DONT "\xfe"
#define WONT "\xfc"
#define WILL "\xfb"
#define DO "\xfd"
#define SB "\xfa"
#define SE "\xf0"
#define ECHO "\x01"
#define SUPPRESS_GO_AHEAD "\x03"
#define TERMINAL_TYPE "\x18"
#define NAWS "\x1f"
#define LINEMODE "\x22"
#define NEWENVIRON "\x27"
#define MODE "\x01"
#define HANDSHAKE_TIMEOUT (3)
/*
** types
*/
typedef struct client_s
{
char userID[USERID_SIZE];
int socket;
BOOLEAN bTerminate;
BOOLEAN bReadFromPipe;
BOOLEAN bWriteToPipe;
HANDLE hProcess;
DWORD dwProcessId;
HANDLE hChildStdinWr;
HANDLE hChildStdoutRd;
} client_t;
typedef enum
{
NoEcho = 0,
Echo = 1,
Password = 2
} EchoMode;
/*
** Local data
*/
/* Local data */
static BOOLEAN bShutdown = 0;
static BOOLEAN bSocketInterfaceInitialised = 0;
static int sock;
/*
** Forward function declarations
*/
static BOOL WINAPI Cleanup(DWORD dwControlType);
static void WaitForConnect(void);
static BOOLEAN StartSocketInterface(void);
static void CreateSocket(void);
static void UserLogin(int client_socket);
static DWORD WINAPI UserLoginThread(LPVOID);
static int DoTelnetHandshake(int sock);
static int ReceiveLine(int sock, char *buffer, int len, EchoMode echo);
static void RunShell(client_t *client);
//static BOOL CreateChildProcess(const char *);
static DWORD WINAPI MonitorChildThread(LPVOID);
static DWORD WINAPI WriteToPipeThread(LPVOID);
static DWORD WINAPI ReadFromPipeThread(LPVOID);
static void TerminateShell(client_t *client);
static VOID ErrorExit(LPTSTR);
/*
** main
*/
DWORD telnetd_main()
/* In the future, some options might be passed here to handle
* authentication options in the registry or command line
* options passed to the service
*
* Once you are ready to turn on the service
* rename this function
* int kickoff_telnetd(void)
*/
int main(int argc, char **argv)
{
SetConsoleCtrlHandler(Cleanup, 1);
@ -127,9 +55,7 @@ DWORD telnetd_main()
return 0;
}
/*
** Cleanup
*/
/* Cleanup */
static BOOL WINAPI Cleanup(DWORD dwControlType)
{
if (bSocketInterfaceInitialised) {
@ -139,9 +65,7 @@ static BOOL WINAPI Cleanup(DWORD dwControlType)
return 0;
}
/*
** StartSocketInterface
*/
/* StartSocketInterface */
static BOOLEAN StartSocketInterface(void)
{
WORD wVersionRequested;

View file

@ -1,8 +1,87 @@
#ifndef __TELNETD_H
#define __TELNETD_H
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_NO_STATUS
#include <stdio.h>
#include <winsock2.h>
#include <tchar.h>
#include <time.h>
DWORD telnetd_main();
/*
** macro definitions
*/
#define TELNET_PORT (23003)
#define BUFSIZE (4096)
#define USERID_SIZE (64)
#define CTRLC (3)
#define BS (8)
#define CR (13)
#define LF (10)
#define DEL (127)
#define IAC "\xff"
#define DONT "\xfe"
#define WONT "\xfc"
#define WILL "\xfb"
#define DO "\xfd"
#define SB "\xfa"
#define SE "\xf0"
#define ECHO "\x01"
#define SUPPRESS_GO_AHEAD "\x03"
#define TERMINAL_TYPE "\x18"
#define NAWS "\x1f"
#define LINEMODE "\x22"
#define NEWENVIRON "\x27"
#define MODE "\x01"
#define HANDSHAKE_TIMEOUT (3)
/*
** types
*/
typedef struct client_s
{
char userID[USERID_SIZE];
int socket;
BOOLEAN bTerminate;
BOOLEAN bReadFromPipe;
BOOLEAN bWriteToPipe;
HANDLE hProcess;
DWORD dwProcessId;
HANDLE hChildStdinWr;
HANDLE hChildStdoutRd;
} client_t;
typedef enum
{
NoEcho = 0,
Echo = 1,
Password = 2
} EchoMode;
/*
** Forward function declarations
*/
static BOOL WINAPI Cleanup(DWORD dwControlType);
static void WaitForConnect(void);
static BOOLEAN StartSocketInterface(void);
static void CreateSocket(void);
static void UserLogin(int client_socket);
static DWORD WINAPI UserLoginThread(LPVOID);
static int DoTelnetHandshake(int sock);
static int ReceiveLine(int sock, char *buffer, int len, EchoMode echo);
static void RunShell(client_t *client);
//static BOOL CreateChildProcess(const char *);
static DWORD WINAPI MonitorChildThread(LPVOID);
static DWORD WINAPI WriteToPipeThread(LPVOID);
static DWORD WINAPI ReadFromPipeThread(LPVOID);
static void TerminateShell(client_t *client);
static VOID ErrorExit(LPTSTR);
int kickoff_telnetd(void);
#endif /* __TELNETD_H */