windows-nt/Source/XPSP1/NT/base/headless/tcsrv/client/main.c

300 lines
7.9 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
* Copyright (c) Microsoft Corporation
*
* Module Name :
* main.c
*
* This is the main file containing the client code.
*
*
* Sadagopan Rajaram -- Oct 14, 1999
*
*/
// Can kill this program on a normal NT console using the
// Alt - X Key combination. Just a shortcut, that is all.
// Serves no useful purpose.
#include "tcclnt.h"
#include "tcsrvc.h"
WSABUF ReceiveBuffer;
CHAR RecvBuf[MAX_BUFFER_SIZE];
IO_STATUS_BLOCK IoStatus;
HANDLE InputHandle;
DWORD bytesRecvd;
WSAOVERLAPPED junk;
SOCKET cli_sock;
DWORD flags;
#if _MSC_FULL_VER >= 13008827
#pragma warning(push)
#pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
#endif
DWORD
inputUpdate(
PVOID dummy
)
{
// Runs in a single thread getting all the inputs
// from the keyboard.
ULONG result;
// gets a multibyte string for every character
// pressed on the keyboard.
CHAR r[MB_CUR_MAX + 1];
while(1){
r[0] = _T('\0');
inchar(r);
// BUGBUG - Performance issues in sending a single character
// at a time across the n/w
if(strlen(r)){
// may send a single byte or two bytes.
send(cli_sock,r,strlen(r),0);
}
}
return 1;
}
#if _MSC_FULL_VER >= 13008827
#pragma warning(pop)
#endif
VOID sendUpdate(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverLapped,
IN DWORD dwFlags
)
{
int error,i;
// Receives a packet and sends it through the stream parser
// BUGBUG - For effeciency it can be made inline.
// I am not sure of the performance increase, but it should
// be substantial as we will be sending a lot of data.
if(dwError != 0){
exit(1);
}
for(i=0;i < (int)cbTransferred;i++){
PrintChar(ReceiveBuffer.buf[i]);
}
// Repost the receive on the socket.
error = WSARecv(cli_sock,
&ReceiveBuffer,
1,
&bytesRecvd,
&flags,
&junk,
sendUpdate
);
if((error == SOCKET_ERROR)
&&(WSAGetLastError()!=WSA_IO_PENDING)){
// Implies something wrong with the socket.
exit(1);
}
return;
}
int __cdecl
main(
IN int argc,
char *argv[]
)
/*++
Opens a single port, binds to the tcserver and passes information back and forth.
--*/
{
struct sockaddr_in srv_addr,cli_addr;
LPHOSTENT host_info;
CLIENT_INFO SendInfo;
int status;
WSADATA data;
#ifdef UNICODE
// BUGBUG - Trying to write a code that works for
// both Unicode and ASCII. Gets multi byte sequences
// Confusion when the tcclnt and tcclnt are in different
// modes.
ANSI_STRING Src;
UNICODE_STRING Dest;
#endif
NTSTATUS Status;
HANDLE Thread;
DWORD ThreadId;
COORD coord;
SMALL_RECT rect;
int RetVal;
struct hostent *ht;
ULONG r;
TCHAR Buffer[80];
if((argc<2) || (argc >4)){
// Error in running the program
printf("Usage - tcclnt COMPORTNAME [ipaddress]\n");
exit(0);
}
ThreadId = GetEnvironmentVariable(_T("TERM"),Buffer , 80);
// We need to know if we have a vt100 screen or an ANSI screen.
AttributeFunction = ProcessTextAttributes;
if(ThreadId >0){
// Terminal type exists in the environment.
// Use it
if((_tcsncmp(Buffer, _T("VT100"), 5) == 0)||
_tcsncmp(Buffer, _T("vt100"),5) ==0 )
AttributeFunction = vt100Attributes;
}
hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
coord.X = MAX_TERMINAL_WIDTH;
coord.Y = MAX_TERMINAL_HEIGHT;
rect.Left = rect.Top = 0;
rect.Right = MAX_TERMINAL_WIDTH -1;
rect.Bottom = MAX_TERMINAL_HEIGHT -1;
if(hConsoleOutput == NULL){
printf("Could not get current console handle %d\n", GetLastError());
return 1;
}
RetVal = SetConsoleScreenBufferSize(hConsoleOutput,
coord
);
RetVal = SetConsoleWindowInfo(hConsoleOutput,
TRUE,
&rect
);
if (RetVal == FALSE) {
printf("Could not set window size %d\n", GetLastError());
return 1;
}
RetVal = SetConsoleMode(hConsoleOutput,ENABLE_PROCESSED_OUTPUT);
if(RetVal == FALSE){
printf("Could not console mode %d\n", GetLastError());
return 1;
}
/* Set up client socket */
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
if(InputHandle == NULL) return 1;
SetConsoleMode(InputHandle, 0);
status=WSAStartup(514,&data);
if(status){
printf("Cannot start up %d\n",status);
return(1);
}
cli_sock=WSASocket(PF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
if (cli_sock==INVALID_SOCKET){
printf("Windows Sockets error %d: Couldn't create socket.",
WSAGetLastError());
return(1);
}
cli_addr.sin_family=AF_INET;
cli_addr.sin_addr.s_addr=INADDR_ANY;
cli_addr.sin_port=0; /* no specific port req'd */
/* Bind client socket to any local interface and port */
if (bind(cli_sock,(LPSOCKADDR)&cli_addr,sizeof(cli_addr))==SOCKET_ERROR){
printf("Windows Sockets error %d: Couldn't bind socket.",
WSAGetLastError());
return(1);
}
srv_addr.sin_family = AF_INET;
if(argc == 3){
srv_addr.sin_addr.s_addr = inet_addr(argv[2]);
if (srv_addr.sin_addr.s_addr == INADDR_NONE) {
ht = gethostbyname(argv[2]);
if(!ht || !ht->h_addr){ // cannot resolve the name
printf("Cannot resolve %s", argv[2]);
exit(1);
}
memcpy((&(srv_addr.sin_addr.s_addr)),ht->h_addr, ht->h_length);
}
}
else{
srv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
}
srv_addr.sin_port=htons(SERVICE_PORT);
/* Connect to FTP server at address SERVER */
if (connect(cli_sock,(LPSOCKADDR)&srv_addr,sizeof(srv_addr))==SOCKET_ERROR){
printf("Windows Sockets error %d: Couldn't connect socket.\n",
WSAGetLastError());
return(1);
}
SendInfo.len = sizeof(CLIENT_INFO);
#ifdef UNICODE
Src.Buffer = argv[1];
Src.Length = (USHORT)strlen(argv[1]);
Dest.Buffer = SendInfo.device;
Dest.MaximumLength = MAX_BUFFER_SIZE;
Status = RtlAnsiStringToUnicodeString(&Dest, &Src, FALSE);
if (!NT_SUCCESS(Status)) {
printf("RtlAnsiStringToUnicodeString failed, ec = 0x%08x\n",Status);
exit(1);
}
send(cli_sock, (PCHAR) &SendInfo, sizeof(CLIENT_INFO), 0);
#else
// We are sending to an ANSI String
strcpy(SendInfo.device, argv[1]);
send(cli_sock, (PCHAR) &SendInfo, sizeof(CLIENT_INFO), 0);
#endif
ReceiveBuffer.len = MAX_BUFFER_SIZE;
ReceiveBuffer.buf = RecvBuf;
status=WSARecv(cli_sock,
&ReceiveBuffer,
1,
&bytesRecvd,
&flags,
&junk,
sendUpdate
);
if((status == SOCKET_ERROR)
&&(WSAGetLastError() != WSA_IO_PENDING)){
printf("Error in recv %d\n",WSAGetLastError());
exit(1);
}
// Create a thread that gets input from the console
// to send to the bridge.
Thread = CreateThread(NULL,
0,
inputUpdate,
NULL,
0,
&ThreadId
);
if (Thread== NULL) {
exit(1);
}
CloseHandle(Thread);
while(1){
// Put this thread in an alertable
// state so that the receive calls can
// asynchronously terminate within the
// context of this thread.
status=SleepEx(INFINITE,TRUE);
}
// We never return here.
closesocket(cli_sock);
return 0;
}