Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1406 lines
36 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
Server.c
Abstract:
The server component of Remote. It spawns a child process
and redirects the stdin/stdout/stderr of child to itself.
Waits for connections from clients - passing the
output of child process to client and the input from clients
to child process.
Author:
Rajivendra Nath (rajnath) 2-Jan-1992
Environment:
Console App. User mode.
Revision History:
--*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
#include "Remote.h"
#define MAX_SESSION 10
#define COMMANDFORMAT "%c%-15s [%-15s %s]\n%c"
#define LOCALNAME "Local"
#define LOCALCLIENT(x) (strcmp((char *)(x->Name),LOCALNAME)==0)
#define RemoteInfo(prt,flg) {if (!(flg&&0x80000000)) prt;}
#define CMDSTRING(OutBuff,InpBuff,Client,szTime) { \
sprintf \
( \
&OutBuff[0],COMMANDFORMAT,\
BEGINMARK,InpBuff, \
Client->Name,szTime, \
ENDMARK \
); \
} \
#define BUFFSIZE 256
#ifdef INTERNALUSECOMPONENT
VOID InitAd(BOOL IsAdvertise);
VOID ShutAd(BOOL IsAdvertise);
#endif
SESSION_TYPE ClientList[MAX_SESSION];
HANDLE ChildStdInp; //Server Writes to it
HANDLE ChildStdOut; //Server Reads from it
HANDLE ChildStdErr; //Server Reads from it
HANDLE SaveFile; //File containing all that was
//output by child process.
//Each connection opens a handle to this file
//and is sent through PipeWriteH.
char SaveFileName[64]; //Name of above file - all new sessions need
HANDLE ChldProc;
HANDLE ListenThreadH;
// GetFormattedTime -- returns pointer to formatted time
//
// returns pointer to static buffer which should be OK.
//
PCHAR GetFormattedTime(VOID)
{
static char szTime[30];
//
// Get time and format to characters
//
GetTimeFormat( LOCALE_USER_DEFAULT,
TIME_NOSECONDS | TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER,
NULL, // use current time
NULL, // use default format
szTime,
30 );
return( (PCHAR) &szTime );
}
HANDLE
ForkChildProcess( // Creates a new process
char *cmd, // Redirects its stdin,stdout
PHANDLE in, // and stderr - returns the
PHANDLE out, // corresponding pipe ends.
PHANDLE err
);
HANDLE
OldForkChildProcess( //Same as above except different
char *cmd, //method for redirection...for
PHANDLE in, //compatibility with.
PHANDLE out,
PHANDLE err
);
DWORD
ListenForSession( //THREAD:Listens for new connections and
char* pipe //spawns of new seesions - Updates the
); //Status in Client DataStructure.
DWORD
NewSession( //Manages the session with a client.
SESSION_TYPE* Client
);
DWORD //2 THREAD:Each reads either
GetChldOutput( //StdOut or StdErr of child and
HANDLE rhandle //writes to SaveFile.
);
DWORD
TransferFileToClient( //X THREADS:Reads the save
SESSION_TYPE* Client //file and sendsoutput to a client.
);
DWORD
GetClientInput( //X THREADS:Gets input from Child pipe
SESSION_TYPE* Client //and sends to childs StdIn.
);
BOOL
FilterCommand( //Filters input from client
SESSION_TYPE *cl, //for commands intended for REMOTE
char *buff,
int dread
);
DWORD
LocalSession(
PVOID noarg
);
DWORD
RemoteSession(
SESSION_TYPE* Client
);
BOOL
SrvCtrlHand(
DWORD event
);
VOID
SendStatus(
HANDLE hClientPipe
);
DWORD
ShowPopup(
char *mssg
);
VOID
RemoveInpMark(
char* Buff,
DWORD Size
);
VOID
CloseClient(
SESSION_TYPE *Client
);
VOID
InitClientList(
);
/*************************************************************/
VOID
Server( //Main routine for server.
char* ChildCmd,
char* PipeName
)
{
DWORD ThreadID ;//No use
HANDLE WaitH[3];
DWORD WaitObj;
char tmpdir[32];
WRITEF((VBuff,"**************************************\n"));
WRITEF((VBuff,"*********** REMOTE ************\n"));
WRITEF((VBuff,"*********** SERVER ************\n"));
WRITEF((VBuff,"**************************************\n"));
WRITEF((VBuff,"To Connect: Remote /C %s %s\n\n",HostName,PipeName));
InitClientList();
//
// set environment variable
//
SetEnvironmentVariable("_REMOTE", PipeName);
//
//Start the command as a child process
//
ChldProc=ForkChildProcess(ChildCmd,&ChildStdInp,&ChildStdOut,&ChildStdErr);
//
//Create a tempfile for storing Child process output.
//
{
DWORD size=sizeof(tmpdir);
if (
(GetEnvironmentVariable("TMP" ,tmpdir,size)==0)&&
(GetEnvironmentVariable("TEMP",tmpdir,size)==0)
)
{
sprintf(tmpdir,"%s",".");
}
if (!GetTempFileName(tmpdir,"REMOTE",0,SaveFileName))
GetTempFileName(".","REMOTE",0,SaveFileName);
}
if ((SaveFile=CreateFile(
(LPCTSTR)SaveFileName, /* address of name of the file */ \
GENERIC_READ|GENERIC_WRITE, /* access (read/write) mode */ \
FILE_SHARE_READ|FILE_SHARE_WRITE,/* share mode */ \
(LPSECURITY_ATTRIBUTES)NULL, /* security descriptor */ \
CREATE_ALWAYS, /* how to create */ \
FILE_ATTRIBUTE_NORMAL, /* File Attribute */ /* file attributes */ \
(HANDLE)NULL))==NULL)
{
TerminateProcess(ChldProc,0);
ErrorExit("Could not Create Output File");
}
//
//Start 2 threads to save the output from stdout and stderr of cmd to savefile.
//
if ((WaitH[0]=CreateThread(
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)GetChldOutput, // Thread procedure.
(LPVOID)ChildStdErr, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ThreadID))==NULL)
{
TerminateProcess(ChldProc,0);
ErrorExit("Failed to Create GetGhldOutput#1 Thread");
}
if ((WaitH[1]=CreateThread(
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)GetChldOutput, // Thread procedure.
(LPVOID)ChildStdOut, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ThreadID))==NULL)
{
TerminateProcess(ChldProc,0);
ErrorExit("Failed to Create GetGhldOutput#2 Thread");
}
//
//Start Thread to listen for new Connections
//
if ((ListenThreadH=CreateThread((LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)ListenForSession, // Thread procedure.
(LPVOID)PipeName, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ThreadID))==NULL)
{
TerminateProcess(ChldProc,0);
ErrorExit("Failed To Create ListenForSession Thread");
}
//
//Start Local Thread
//
if ((ClientList[0].hThread=CreateThread((LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)LocalSession, // Thread procedure.
(LPVOID)NULL, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ThreadID))==NULL)
{
TerminateProcess(ChldProc,0);
ErrorExit("Failed To Create ListenForSession Thread");
}
SetConsoleCtrlHandler((PHANDLER_ROUTINE)SrvCtrlHand,TRUE);
#ifdef INTERNALUSECOMPONENT
InitAd(IsAdvertise);
#endif
WaitH[2]=ChldProc;
WaitObj=WaitForMultipleObjects(3,WaitH,FALSE,INFINITE);
switch (WaitObj-WAIT_OBJECT_0)
{
case 0: // Error Writing to savefile
case 1:
TerminateProcess(ChldProc,0);
break;
case 2: // Child Proc Terminated
break;
default: // Out of Some Resource
printf("Out of Resource Error %d..Terminating\n",GetLastError());
break;
}
TerminateThread(ListenThreadH,0);
#ifdef INTERNALUSECOMPONENT
ShutAd(IsAdvertise);
#endif
CloseHandle(ChildStdInp);
CloseHandle(ChildStdOut);
CloseHandle(ChildStdErr);
WRITEF((VBuff,"\nRemote:Parent exiting. Child(%s) dead..\n",ChildCmd));
CloseHandle(SaveFile);
{
int i;
for (i=0;i<MAX_SESSION;i++)
CloseClient(&ClientList[i]);
}
if (!DeleteFile(SaveFileName))
WRITEF((VBuff,"Temp File %s not deleted..\n",SaveFileName));
return;
}
/*************************************************************/
HANDLE
ForkChildProcess( // Creates a new process
char *cmd, // Redirects its stdin,stdout
PHANDLE inH, // and stderr - returns the
PHANDLE outH, // corresponding pipe ends.
PHANDLE errH
)
{
SECURITY_ATTRIBUTES lsa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE ChildIn;
HANDLE ChildOut;
HANDLE ChildErr;
lsa.nLength=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor=NULL;
lsa.bInheritHandle=TRUE;
//
//Create Parent_Write to ChildStdIn Pipe
//
if (!CreatePipe(&ChildIn,inH,&lsa,0))
ErrorExit("Could Not Create Parent-->Child Pipe");
//
//Create ChildStdOut to Parent_Read pipe
//
if (!CreatePipe(outH,&ChildOut,&lsa,0))
ErrorExit("Could Not Create Child-->Parent Pipe");
//
//Create ChildStdOut to Parent_Read pipe
//
if (!CreatePipe(errH,&ChildErr,&lsa,0))
ErrorExit("Could Not Create Child-->Parent Pipe");
//
// Lets Redirect Console StdHandles - easy enough
//
si.cb=sizeof(STARTUPINFO);
si.lpReserved=NULL;
si.lpTitle=NULL;
si.lpDesktop=NULL;
si.dwX=si.dwY=si.dwYSize=si.dwXSize=0;
si.dwFlags=STARTF_USESTDHANDLES;
si.hStdInput =ChildIn;
si.hStdOutput=ChildOut;
si.hStdError =ChildErr;
si.wShowWindow=SW_SHOW;
si.lpReserved2=NULL;
si.cbReserved2=0;
//
//Create Child Process
//
if (!CreateProcess( NULL,
cmd,
NULL,
NULL,
TRUE,
NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi))
{
if (GetLastError()==2)
WRITEF((VBuff,"Executable %s not found\n",cmd));
ErrorExit("Could Not Create Child Process");
}
//
//Close unneccesary Handles and Restore the crt handles
//
CloseHandle(ChildIn);
CloseHandle(ChildOut);
CloseHandle(ChildErr);
return(pi.hProcess);
}
/*************************************************************/
HANDLE
OldForkChildProcess(
char *cmd,
PHANDLE inH,
PHANDLE outH,
PHANDLE errH
)
{
SECURITY_ATTRIBUTES lsa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE OldStdIn =GetStdHandle(STD_INPUT_HANDLE);
HANDLE OldStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE OldStdErr=GetStdHandle(STD_ERROR_HANDLE);
HANDLE ChildStdIn;
HANDLE ChildStdOut;
HANDLE ChildStdErr;
lsa.nLength=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor=NULL;
lsa.bInheritHandle=TRUE;
//Create Parent_Write to ChildStdIn Pipe
if (!CreatePipe(&ChildStdIn,inH,&lsa,0))
ErrorExit("Could Not Create Parent-->Child Pipe");
//Create ChildStdOut to Parent_Read pipe
if (!CreatePipe(outH,&ChildStdOut,&lsa,0))
ErrorExit("Could Not Create Child-->Parent Pipe");
//Create ChildStdOut to Parent_Read pipe
if (!CreatePipe(errH,&ChildStdErr,&lsa,0))
ErrorExit("Could Not Create Child-->Parent Pipe");
//Make ChildStdIn and Out as standard handles and get it inherited by child
if (!SetStdHandle(STD_INPUT_HANDLE,ChildStdIn))
ErrorExit("Could not change StdIn");
if (!SetStdHandle(STD_OUTPUT_HANDLE,ChildStdOut))
ErrorExit("Could Not change StdOut");
if (!SetStdHandle(STD_ERROR_HANDLE,ChildStdErr))
ErrorExit("Could Not change StdErr");
si.cb=sizeof(STARTUPINFO);
si.lpReserved=NULL;
si.lpTitle=NULL;
si.lpDesktop=NULL;
si.dwX=si.dwY=si.dwYSize=si.dwXSize=si.dwFlags=0L;
si.wShowWindow=SW_SHOW;
si.lpReserved2=NULL;
si.cbReserved2=0;
//Create Child Process
if (!CreateProcess( NULL,
cmd,
NULL,
NULL,
TRUE,
NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi))
ErrorExit("Could Not Create Child Process");
//reset StdIn StdOut
if (!SetStdHandle(STD_INPUT_HANDLE,OldStdIn))
{
TerminateProcess(pi.hProcess,1);
ErrorExit("Could not RESET StdIn");
}
if (!SetStdHandle(STD_OUTPUT_HANDLE,OldStdOut))
{
TerminateProcess(pi.hProcess,1);
ErrorExit("Could not RESET StdIn");
}
if (!SetStdHandle(STD_ERROR_HANDLE,OldStdErr))
{
TerminateProcess(pi.hProcess,1);
ErrorExit("Could not RESET StdIn");
}
//Close unneccesary Handles
CloseHandle(ChildStdIn);
CloseHandle(ChildStdOut);
CloseHandle(ChildStdErr);
return(pi.hProcess);
}
/*************************************************************/
/*************************************************************/
DWORD
ListenForSession(
char* pipename
)
{
int i;
DWORD ThreadID;
HANDLE PipeH[2];
SECURITY_DESCRIPTOR SecurityDescriptor;
HANDLE TokenHandle;
TOKEN_DEFAULT_DACL DefaultDacl;
SECURITY_ATTRIBUTES lsa;
char fullnameIn[BUFFSIZE];
char fullnameOut[BUFFSIZE];
sprintf(fullnameIn,SERVER_READ_PIPE ,".",pipename);
sprintf(fullnameOut,SERVER_WRITE_PIPE,".",pipename);
//
// Initialize the security descriptor that we're going to
// use.
//
InitializeSecurityDescriptor
(
&SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION
);
(VOID) SetSecurityDescriptorDacl
(
&SecurityDescriptor,
TRUE,
NULL,
FALSE
);
DefaultDacl.DefaultDacl = NULL;
if (OpenProcessToken
(
GetCurrentProcess(),
TOKEN_ADJUST_DEFAULT,
&TokenHandle
))
{
//
// Remove the default DACL on the token
//
SetTokenInformation
(
TokenHandle,
TokenDefaultDacl,
&DefaultDacl,
sizeof( TOKEN_DEFAULT_DACL )
);
}
lsa.nLength=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor=&SecurityDescriptor;
lsa.bInheritHandle=TRUE;
while(TRUE)
{
PipeH[0]=CreateNamedPipe
(
fullnameIn ,
PIPE_ACCESS_INBOUND ,
PIPE_TYPE_BYTE,
PIPE_UNLIMITED_INSTANCES,
0,0,0,&lsa
);
PipeH[1]=CreateNamedPipe
(
fullnameOut,
PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE,
PIPE_UNLIMITED_INSTANCES,
0,0,0,&lsa
);
if (!ConnectNamedPipe(PipeH[0],NULL))
{
if (GetLastError()!=ERROR_PIPE_CONNECTED)
{
CloseHandle(PipeH[0]);
CloseHandle(PipeH[1]);
continue;
}
}
if (!ConnectNamedPipe(PipeH[1],NULL))
{
if (GetLastError()!=ERROR_PIPE_CONNECTED)
{
CloseHandle(PipeH[0]);
CloseHandle(PipeH[1]);
continue;
}
}
//
//Look For a Free Slot & if not- then terminate connection
//
for (i=1;i<MAX_SESSION;i++)
{
//
// Locate a Free Client block
//
if (!ClientList[i].Active)
break;
}
if (i<MAX_SESSION)
{
//
// Initialize the Client
//
ClientList[i].PipeReadH=PipeH[0];
ClientList[i].PipeWriteH=PipeH[1];
ClientList[i].Active=TRUE;
ClientList[i].SendOutput=TRUE;
ClientList[i].CommandRcvd=FALSE;
}
else
{
WRITEF((VBuff,"Remote:Closing New Session - No more slots\n"));
CloseHandle(PipeH[0]);
CloseHandle(PipeH[1]);
continue;
}
//
//start new thread for this connection
//
if((ClientList[i].hThread=CreateThread (
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)RemoteSession, // Thread procedure.
(LPVOID)&ClientList[i], // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ThreadID))==NULL)
{
CloseClient(&ClientList[i]);
continue;
}
}
return(0);
}
/*************************************************************/
DWORD
RemoteSession(
SESSION_TYPE *MyClient
)
{
DWORD ReadCnt;
SESSION_STARTUPINFO ssi;
char *headerbuff;
char msg[BUFFSIZE];
DWORD tmp;
SESSION_STARTREPLY ssr;
memset((char *)&ssi,0,sizeof(ssi));
if ((MyClient->rSaveFile=CreateFile(
SaveFileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL))==NULL)
{
CloseClient(MyClient);
return(1);
}
{
DWORD reply=0;
ReadFixBytes(MyClient->PipeReadH,(char *)MyClient->Name,HOSTNAMELEN-1,0);
//
//Last four Bytes contains a code
//
memcpy((char *)&reply,(char *)&(MyClient->Name[11]),4);
if (reply!=MAGICNUMBER)
{
//
// Unknown client
//
CloseClient(MyClient);
return(1);
}
ssr.MagicNumber=MAGICNUMBER;
ssr.Size=sizeof(ssr);
ssr.FileSize=GetFileSize( MyClient->rSaveFile, &tmp );
WriteFile(MyClient->PipeWriteH,(char *)&ssr,sizeof(ssr),&tmp,NULL);
}
if (ReadFixBytes(MyClient->PipeReadH,(char *)&(ssi.Size),sizeof(ssi.Size),0)!=0)
{
CloseClient(MyClient);
return(1);
}
if (ssi.Size>1024) //Sanity Check
{
sprintf(msg,"%s","Server:Unknown Header..Terminating session\n");
WriteFile(MyClient->PipeWriteH,msg,strlen(msg),&tmp,NULL);
CloseClient(MyClient);
return(1);
}
if ((headerbuff=(char *)calloc(ssi.Size,1))==NULL)
{
sprintf(msg,"%s","Server:Not Enough Memory..Terminating session\n");
WriteFile(MyClient->PipeWriteH,msg,strlen(msg),&tmp,NULL);
CloseClient(MyClient);
return(1);
}
ReadCnt=ssi.Size-sizeof(ssi.Size);
if (ReadFixBytes(MyClient->PipeReadH,(char *)headerbuff,ReadCnt,0)!=0)
{
CloseClient(MyClient);
return(1);
}
memcpy((char *)&ssi+sizeof(ssi.Size),headerbuff,sizeof(ssi)-sizeof(ssi.Size));
free(headerbuff);
/* Version */
if (ssi.Version!=VERSION)
{
sprintf(msg,"Remote Warning:Server Version=%d Client Version=%d\n",VERSION,ssi.Version);
WriteFile(MyClient->PipeWriteH,msg,strlen(msg),&tmp,NULL);
}
/* Name */
{
memcpy(MyClient->Name,ssi.ClientName,15);
MyClient->Name[14]=0;
}
/* Lines */
if (ssi.LinesToSend!=-1)
{
long PosFromEnd=ssi.LinesToSend*CHARS_PER_LINE;
DWORD BytesToSend=MINIMUM((DWORD)PosFromEnd,ssr.FileSize);
DWORD BytesRead;
char *buff=(char *)calloc(BytesToSend+1,1);
if (ssr.FileSize > (DWORD)PosFromEnd)
{
SetFilePointer( MyClient->rSaveFile,
-PosFromEnd,
(PLONG)NULL,
FILE_END
);
}
if (buff!=NULL)
{
if (!ReadFile(MyClient->rSaveFile,buff,BytesToSend,&BytesRead,NULL))
{
CloseClient(MyClient);
return(1);
}
RemoveInpMark(buff,BytesRead);
if (!WriteFile(MyClient->PipeWriteH,buff,BytesRead,&tmp,NULL))
{
CloseClient(MyClient);
return(1);
}
}
free(buff);
}
RemoteInfo(printf("\n**Remote:Connected To %s [%s]\n",MyClient->Name,GetFormattedTime()),ssi.Flag);
NewSession(MyClient);
RemoteInfo(printf("\n**Remote:Disconnected From %s [%s]\n",MyClient->Name,GetFormattedTime()),ssi.Flag);
CloseClient(MyClient);
return(0);
}
/*************************************************************/
DWORD
NewSession(
SESSION_TYPE* MyClient
)
{
DWORD ThreadId;
HANDLE rwThread[3];
MyClient->MoreData=CreateEvent
(
(LPSECURITY_ATTRIBUTES) NULL,/* address of security attributes */
FALSE, /* flag for manual-reset event */
TRUE, /* flag for initial state */
NULL /* address of event-object name */
);
if ((rwThread[0]=CreateThread (
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)GetClientInput, // Thread procedure.
(LPVOID)MyClient, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ThreadId))==NULL)
{
return(GetLastError());
}
if ((rwThread[1]=CreateThread (
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)TransferFileToClient, // Thread procedure.
(LPVOID)MyClient, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ThreadId))==NULL)
{
CloseHandle(rwThread[0]);
return(GetLastError());
}
rwThread[2]=ChldProc;
WaitForMultipleObjects(3, rwThread,FALSE, INFINITE);
TerminateThread(rwThread[0],1);
TerminateThread(rwThread[1],1);
CloseHandle(rwThread[0]);
CloseHandle(rwThread[1]);
return(0);
}
/*************************************************************/
DWORD
GetChldOutput(
HANDLE readH
)
{
char buff[BUFFSIZE];
DWORD dread;
DWORD tmp;
while(ReadFile(readH,buff,BUFFSIZE-1,&dread,NULL))
{
buff[dread]='\0';
if (!WriteFile(SaveFile,buff,dread,&tmp,NULL))
{
return(1);
}
//
// Signal Reader Thread that more data
//
{
int i;
DWORD err; //REMOVE
for (i=0;i<MAX_SESSION;i++)
{
if (ClientList[i].Active)
{
if (!SetEvent(ClientList[i].MoreData))
err=GetLastError(); //REMOVE
}
}
}
}
return(1);
}
/*************************************************************/
DWORD
TransferFileToClient(
SESSION_TYPE *MyClient
)
{
char buffin[BUFFSIZE],buffout[BUFFSIZE],cmdbuff[BUFFSIZE];
DWORD tmp;
DWORD dread=0,dwrite=0;
BOOL incmd=FALSE;
DWORD cmdP=0;
DWORD i;
char MyEchoStr[30];
sprintf(MyEchoStr,"[%-15s",MyClient->Name);
while(ReadFile(MyClient->rSaveFile,buffin,BUFFSIZE-1,&dread,NULL))
{
if (dread==0)
{
WaitForSingleObject(MyClient->MoreData,INFINITE);
continue;
}
dwrite=0;
for(i=0;i<dread;i++)
{
if (incmd)
{
if ((buffin[i]==ENDMARK)||(cmdP==BUFFSIZE-1))
{
incmd=FALSE;
cmdbuff[cmdP]=0;
if ((strstr(cmdbuff,MyEchoStr)==NULL)||
(!MyClient->CommandRcvd))
{
if (!WriteFile(
MyClient->PipeWriteH,
cmdbuff,cmdP,&tmp,NULL))
{
return(1);
}
}
cmdP=0;
}
else
{
cmdbuff[cmdP++]=buffin[i];
}
}
else
{
if (buffin[i]==BEGINMARK)
{
if (dwrite!=0)
{
if (!WriteFile(
MyClient->PipeWriteH,
buffout,dwrite,&tmp,NULL))
{
return(1);
}
dwrite=0;
}
incmd=TRUE;
continue;
}
else
{
buffout[dwrite++]=buffin[i];
}
}
}
if (dwrite!=0)
{
if (!WriteFile(
MyClient->PipeWriteH,
buffout,dwrite,&tmp,NULL))
{
return(0);
}
}
}
return(1);
}
/*************************************************************/
DWORD
GetClientInput(
SESSION_TYPE *MyClient
)
{
char buff[BUFFSIZE];
DWORD tmp,dread;
while(ReadFile(MyClient->PipeReadH,buff,BUFFSIZE,&dread,NULL))
{
buff[dread]=0;
MyClient->CommandRcvd=TRUE;
if (FilterCommand(MyClient,buff,dread))
continue;
if (!WriteFile(ChildStdInp,buff,dread,&tmp,NULL))
{
ExitThread(0);
}
}
return(1);
}
/*************************************************************/
BOOL
FilterCommand(
SESSION_TYPE *cl,
char *buff,
int dread
)
{
char inp_buff[4096];
char tmpchar;
char ch[3];
DWORD tmp;
int len;
DWORD ThreadID; //Useless
if (dread==0)
return(FALSE);
buff[dread]=0;
if (buff[0]==COMMANDCHAR)
{
switch(buff[1])
{
case 'o':
case 'O': cl->SendOutput=!cl->SendOutput;
break;
case 'k':
case 'K':TerminateProcess(ChldProc,1);
break;
case 's':
case 'S':
SendStatus(cl->PipeWriteH);
break;
case 'p':
case 'P':
{
char *mssg=(char *)calloc(4096,1); //Free it in called Proc
char *ack="Remote:Popup Shown..\n";
if (mssg==NULL)
break;
sprintf(mssg,"From %s [%s]\n\n%s\n",cl->Name,GetFormattedTime(),&buff[2]);
CreateThread(
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)ShowPopup, // Thread procedure.
(LPVOID)mssg, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ThreadID
);
WriteFile(cl->PipeWriteH,ack,strlen(ack),&tmp,NULL);
break;
}
case 'm':
case 'M':
buff[dread-2]=0;
CMDSTRING(inp_buff,buff,cl,GetFormattedTime());
len=strlen(inp_buff);
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
break;
case '@':
buff[dread-2]=0;
CMDSTRING(inp_buff,&buff[1],cl,GetFormattedTime());
len=strlen(inp_buff);
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
//
// Remove the first @ sign
//
MoveMemory(buff,&buff[1],dread-1);
buff[dread-1]=' ';
return(FALSE); //Send it it to the chile process
break;
default :
sprintf(inp_buff,"%s","** Unknown Command **\n");
WriteFile(cl->PipeWriteH,inp_buff,strlen(inp_buff),&tmp,NULL);
case 'h':
case 'H':
sprintf(inp_buff,"%cM: To Send Message\n",COMMANDCHAR);
WriteFile(cl->PipeWriteH,inp_buff,strlen(inp_buff),&tmp,NULL);
sprintf(inp_buff,"%cP: To Generate popup\n",COMMANDCHAR);
WriteFile(cl->PipeWriteH,inp_buff,strlen(inp_buff),&tmp,NULL);
sprintf(inp_buff,"%cK: To kill the server\n",COMMANDCHAR);
WriteFile(cl->PipeWriteH,inp_buff,strlen(inp_buff),&tmp,NULL);
sprintf(inp_buff,"%cH: This Help\n",COMMANDCHAR);
WriteFile(cl->PipeWriteH,inp_buff,strlen(inp_buff),&tmp,NULL);
break;
}
return(TRUE);
}
if ((buff[0]<26))
{
BOOL ret=FALSE;
sprintf(ch,"^%c",buff[0]+64);
CMDSTRING(inp_buff,ch,cl,GetFormattedTime());
len=strlen(inp_buff);
if (buff[0]==CTRLC)
{
cl->CommandRcvd=FALSE;
GenerateConsoleCtrlEvent(CTRL_C_EVENT,0);
ret=TRUE; //Already sent to child
}
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
return(ret); //FALSE:send it to child StdIn
}
tmpchar=buff[dread-2]; //must be 13;but just incase
buff[dread-2]=0;
CMDSTRING(inp_buff,buff,cl,GetFormattedTime());
buff[dread-2]=tmpchar;
len=strlen(inp_buff);
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
return(FALSE);
}
/*************************************************************/
VOID
SendStatus(
HANDLE hClientPipe
)
{
char buff[1024];
int i;
DWORD tmp;
char *env=(char *)GetEnvironmentStrings();
DWORD ver=GetVersion();
sprintf(buff,"Command = %s\n",ChildCmd);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
sprintf(buff,"Server = %s PIPE=%s\n",HostName,PipeName);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
sprintf(buff,"Build = %d \n",((WORD *)&ver)[1]);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
for (i=1;i<MAX_SESSION;i++)
{
if (ClientList[i].Active)
{
sprintf(buff,"ACTIVE SESSION=%s\n",ClientList[i].Name);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
}
}
sprintf(buff,"====================\n",Server,PipeName);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
sprintf(buff,"ENVIRONMENT VARIABLES\n",Server,PipeName);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
sprintf(buff,"====================\n",Server,PipeName);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
try
{
while (*env!=0)
{
sprintf(buff,"%s\n",env);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
while(*(env++)!=0);
}
}
except(EXCEPTION_EXECUTE_HANDLER)
{
sprintf(buff,"Exception Generated Getting Environment Block\n",env);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
}
sprintf(buff,"====================\n",Server,PipeName);
WriteFile(hClientPipe,buff,strlen(buff),&tmp,NULL);
return;
}
/*************************************************************/
DWORD
ShowPopup(
char *mssg
)
{
MessageBox(GetActiveWindow(),mssg,"***REMOTE***",MB_OK|MB_SETFOREGROUND);
free(mssg);
return(0);
}
/*************************************************************/
BOOL SrvCtrlHand(
DWORD event
)
{
if (event==CTRL_BREAK_EVENT)
{
TerminateProcess(ChldProc,1);
return(TRUE);
}
else if (event==CTRL_C_EVENT)
return(TRUE);
return(FALSE);
}
/*************************************************************/
DWORD LocalSession(PVOID noarg)
{
//Local is ClientList[0]
char *name=(char *)ClientList[0].Name;
strcpy(name,LOCALNAME);
if ((ClientList[0].rSaveFile=CreateFile(SaveFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL))==NULL)
{
WRITEF((VBuff,"Remote:Cannot open ReadHandle to Savefile:%d\n",GetLastError()));
ClientList[0].Active=FALSE;
return(1);
}
ClientList[0].PipeReadH=GetStdHandle(STD_INPUT_HANDLE);
ClientList[0].PipeWriteH=GetStdHandle(STD_OUTPUT_HANDLE);
ClientList[0].SendOutput=TRUE;
ClientList[0].Active=TRUE;
NewSession(&ClientList[0]);
CloseClient(&ClientList[0]);
return(0);
}
VOID
CloseClient(
SESSION_TYPE *Client
)
{
ZeroMemory(Client->Name,HOSTNAMELEN);
if (Client->PipeReadH!=INVALID_HANDLE_VALUE)
{
CloseHandle(Client->PipeReadH);
Client->PipeReadH=INVALID_HANDLE_VALUE;
}
if (Client->PipeWriteH!=INVALID_HANDLE_VALUE)
{
CloseHandle(Client->PipeWriteH);
Client->PipeWriteH=INVALID_HANDLE_VALUE;
}
if (Client->rSaveFile!=INVALID_HANDLE_VALUE)
{
CloseHandle(Client->rSaveFile);
Client->rSaveFile=INVALID_HANDLE_VALUE;
}
if (Client->MoreData!=NULL)
{
CloseHandle(Client->MoreData);
Client->MoreData=NULL;
}
Client->Active=FALSE; //Keep it last else synch problem.
return;
}
VOID
InitClientList(
)
{
int i;
for (i=0;i<MAX_SESSION;i++)
{
ZeroMemory(ClientList[i].Name,HOSTNAMELEN);
ClientList[i].PipeReadH=INVALID_HANDLE_VALUE;
ClientList[i].PipeWriteH=INVALID_HANDLE_VALUE;
ClientList[i].rSaveFile=INVALID_HANDLE_VALUE;
ClientList[i].MoreData=NULL;
ClientList[i].Active=FALSE;
ClientList[i].CommandRcvd=FALSE;
ClientList[i].SendOutput=FALSE;
ClientList[i].hThread=NULL;
}
return;
}
VOID
RemoveInpMark(
char* Buff,
DWORD Size
)
{
DWORD i;
for (i=0;i<Size;i++)
{
switch (Buff[i])
{
case BEGINMARK:
Buff[i]=' ';
break;
case ENDMARK:
if (i<2)
{
Buff[i]= ' ';
}
else
{
Buff[i] =Buff[i-1];
Buff[i-1]=Buff[i-2];
Buff[i-2]=' ';
}
break;
default:
break;
}
}
}