Los comentarios son medios pedorros pero es lo que pude deducir viendo la documentación, no tengo experiencia en apis de windows, estoy aprendiendo así que paciencia.
Código:
/**********************************************************
* I take no responsibility for what you or others might do
* with this knowledge.
***********************************************************/
#pragma comment(lib,"ws2_32.lib")
#include <Winsock2.h>
int main( int argc, char ** argv )
{
WSADATA WSAData;
SOCKADDR_IN sin;
SOCKET sock;
WSAStartup( MAKEWORD( 2, 0 ), &WSAData );
sock = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0 );
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl( INADDR_ANY );
sin.sin_port = htons( ( u_short )8023 );
bind( sock, ( SOCKADDR * )&sin, sizeof( SOCKADDR_IN ) );
listen( sock, SOMAXCONN );
while( true )
{
SOCKET tmp = accept( sock, 0, 0 );
STARTUPINFO si = { 0 }; //declara la estructura "si" del tipo startupinfo, que será pasada a la funcion createprocess.
PROCESS_INFORMATION pi = { 0 }; //declara la estructura "pi" del tipo process_information que será pasada a la funcion createprocess
char buff[ 2010 ]; //declara el buffer donde getenviroment variable va a guardar la ruta del cmd.
si.cb = sizeof( si ); // no se
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; // no se
si.wShowWindow = SW_HIDE; // le dice que no muestre la ventana.
si.hStdOutput = ( HANDLE )tmp; // redirige la salida a tmp, lo castea como handle, tmp es el socket creado con wsasocket, (no con socket, ojo)
si.hStdError = ( HANDLE )tmp; // redirige la salida de errores al socket
si.hStdInput = ( HANDLE )tmp; //le indica que el inputo vendrá del socket.
GetEnvironmentVariable( "COMSPEC", buff, 2000 ); //COMSPEC es la variable de entorno que trae la ruta del cmd.
CreateProcess( buff, 0, 0, 0, true, CREATE_NEW_CONSOLE, 0, 0, &si, &pi );
// en buff le dice que abra el cmd, el true es para que herede, no se que, pero es para eso, CREATE_NEW_CONSOLE es la indicacion que hay que
//enviarles, al final le pasa los dos punteros a la estructura, el puntero &si para que sepa como iniciar, y el &pi para que guarde la data
// del proceso (como inició, etc)
CloseHandle( pi.hProcess ); //cierra los dos handle, lo tengo que ver bien, y cierra el socket.
CloseHandle( pi.hThread );
closesocket( tmp );
}
return( 0 );
}
Acá dejo el comentario del tipo que lo posteó en su blog: Actually these are 43 lines counting the blank lines.
Writing “simple telnet server†is a simple task. All you have to do is to spawn the OS shell and redirect its input and output through a socket to the telnet client. Nowadays telnet clients are even smart enough not to need telnet control character when they are unneeded. Anyway occasionally you may see junk characters on the console screen. These are telnet control characters that are not handled by our “simple telnet serverâ€. Of course there is some/lot code you have to write around the real telnet core, that I have skipped. Like checking user/pass credentials, running the shell within the user context, handling telnet control characters etc.
So here comes the 20-line simple telnet server. It has no user check nor error handling. It listens on port 8023 and will spawn the default windows shell expanding ( GetEnvironmentVariable ) the "%COMSPEC%" environment variable. One thing that makes it simpler is that it directly assigns the client socket for stdin/stdout/stderr of the spawned shell. Note that we need to create the socket through the WSASocket function ( and not socket ) so that we could use the socket as handle.
If you play a bit with the program you will find that it can not handle applications like 'edit.com' and it will hang on command waiting for ctrl + c to terminate, such as 'more'.
It is due to the following facts:
1 - 'edit.com' writes 'directly' to the video memory ( using functions like WriteConsole ) So the output is not sent to the console output handle but directly displayed in the console screen buffer. And our simple server does not export the console screen buffer.
2 - the 'more' command terminates on ctrl + c, but in windows console world ctrl + c is not a character, but it is a signal/event. The CTRL_C_EVENT is generated by the system when the keys ctrl + c are pressed in a console window and the event is sent to the console process. If the event is not handled by custom ctrl handler( installed through SetConsoleCtrlHandler ) the console process is closed by its default ctrl handler. Using our redirected input we actually send the ctrl + c character (0x03) to the stdio handle, and the system does not generate CTRL_C_EVENT.
y dejo el link:
Código:
http://www.kpym.com/blog/2005/12/src-simple-telnet-server-in-20-lines-c.html
El tipo aclara que el programa tiene algunos problemas para abrir el edit, o para manejar un ctrl+c, si alguno de los grosos del foro sabe como resolverlo y mejorar el código, bienvenido sea.
Un abrazo para todos.