CLIENT.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:17k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright 1992 - 1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- ******************************************************************************/
- /*++
- Copyright 1992 - 1997 Microsoft Corporation
- Module Name:
- Client.c
- Abstract:
- The Client component of Remote. Connects to the remote
- server using named pipes. It sends its stdin to
- the server and output everything from server to
- its stdout.
- Author:
- Rajivendra Nath 2-Jan-1992
- Dave Hart Summer 1997 single-pipe operation
- Environment:
- Console App. User mode.
- Revision History:
- --*/
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <process.h>
- #include <io.h>
- #include <string.h>
- #include "Remote.h"
- BOOL fAsyncPipe = TRUE; // need this so server has it TRUE
- HANDLE*
- EstablishSession(
- char *server,
- char *pipe
- );
- DWORD
- WINAPI
- SendServerInp(
- LPVOID pvParam
- );
- BOOL
- FilterClientInp(
- char *buff,
- int count
- );
- BOOL
- Mych(
- DWORD ctrlT
- );
- VOID
- SendMyInfo(
- PHANDLE Pipes
- );
- HANDLE MyStdInp;
- HANDLE MyStdOut;
- //
- // ReadPipe and WritePipe are referenced by multiple
- // threads so need to be volatile.
- //
- volatile HANDLE ReadPipe;
- volatile HANDLE WritePipe;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- char MyEchoStr[30];
- BOOL CmdSent;
- DWORD LinesToSend=LINESTOSEND;
- VOID
- Client(
- char* Server,
- char* Pipe
- )
- {
- HANDLE *Connection;
- DWORD dwThreadID;
- HANDLE hThread;
- DWORD cb;
- OVERLAPPED ol;
- char rgchBuf[1024];
- MyStdInp=GetStdHandle(STD_INPUT_HANDLE);
- MyStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
- printf("**************************************n");
- printf("*********** REMOTE ************n");
- printf("*********** CLIENT ************n");
- printf("**************************************n");
- if ((Connection=EstablishSession(Server,Pipe))==NULL)
- return;
- ReadPipe=Connection[0];
- WritePipe=Connection[1];
- SetConsoleCtrlHandler((PHANDLER_ROUTINE)Mych,TRUE);
- // Start Thread For Client --> Server Flow
- hThread = (HANDLE)
- _beginthreadex(
- NULL, // security
- 0, // default stack size
- SendServerInp, // thread proc
- NULL, // parm
- 0, // not suspended
- &dwThreadID
- );
- if ( ! hThread)
- {
- Errormsg("REMOTE /C Could Not Create Thread.");
- return;
- }
- ZeroMemory(&ol, sizeof(ol));
- ol.hEvent =
- CreateEvent(
- NULL, // security
- TRUE, // auto-reset
- FALSE, // initially nonsignaled
- NULL // unnamed
- );
- while (ReadFileSynch(ReadPipe, rgchBuf, sizeof rgchBuf, &cb, 0, &ol)) {
- if (cb) {
- if ( ! WriteFile(MyStdOut, rgchBuf, cb, &cb, NULL)) {
- break;
- }
- }
- }
- CloseHandle(ol.hEvent);
- printf("*** SESSION OVER ***");
- fflush(stdout);
- //
- // Terminate the keyboard reading thread.
- //
- TerminateThread(hThread, 0);
- CloseHandle(hThread);
- CloseClientPipes();
- printf("n");
- fflush(stdout);
- }
- DWORD
- WINAPI
- SendServerInp(
- LPVOID pvParam
- )
- {
- DWORD dread,dwrote;
- OVERLAPPED ol;
- char buff[512];
- UNREFERENCED_PARAMETER(pvParam);
- ZeroMemory(&ol, sizeof(ol));
- ol.hEvent =
- CreateEvent(
- NULL, // security
- TRUE, // auto-reset
- FALSE, // initially nonsignaled
- NULL // unnamed
- );
- while(ReadFile(MyStdInp,buff,sizeof buff,&dread,NULL))
- {
- if (FilterClientInp(buff,dread))
- continue;
- if (!WriteFileSynch(WritePipe,buff,dread,&dwrote,0,&ol))
- break;
- }
- return 0;
- }
- BOOL
- FilterClientInp(
- char *buff,
- int count
- )
- {
- if (count==0)
- return(TRUE);
- if (buff[0]==2) // Adhoc screening of ^B so that i386kd/mipskd
- return(TRUE); // do not terminate.
- if (buff[0]==COMMANDCHAR)
- {
- switch (buff[1])
- {
- case 'k':
- case 'K':
- case 'q':
- case 'Q':
- CloseClientPipes();
- return(FALSE);
- case 'h':
- case 'H':
- printf("%cM : Send Messagen",COMMANDCHAR);
- printf("%cP : Show Popup on Servern",COMMANDCHAR);
- printf("%cS : Status of Servern",COMMANDCHAR);
- printf("%cQ : Quit clientn",COMMANDCHAR);
- printf("%cH : This Helpn",COMMANDCHAR);
- return(TRUE);
- default:
- return(FALSE);
- }
- }
- return(FALSE);
- }
- BOOL
- Mych(
- DWORD ctrlT
- )
- {
- char c[2];
- DWORD tmp;
- OVERLAPPED ol;
- c[0]=CTRLC;
- if (ctrlT==CTRL_C_EVENT)
- {
- ZeroMemory(&ol, sizeof(ol));
- ol.hEvent =
- CreateEvent(
- NULL, // security
- TRUE, // auto-reset
- FALSE, // initially nonsignaled
- NULL // unnamed
- );
- if (INVALID_HANDLE_VALUE != WritePipe &&
- !WriteFileSynch(WritePipe,c,1,&tmp,0,&ol))
- {
- CloseHandle(ol.hEvent);
- Errormsg("Error Sending ^c");
- return(FALSE);
- }
- CloseHandle(ol.hEvent);
- return(TRUE);
- }
- if ((ctrlT==CTRL_BREAK_EVENT)||
- (ctrlT==CTRL_CLOSE_EVENT)||
- (ctrlT==CTRL_LOGOFF_EVENT)||
- (ctrlT==CTRL_SHUTDOWN_EVENT)
- ) {
- CloseClientPipes();
- }
- return(FALSE);
- }
- VOID
- CloseClientPipes(
- VOID
- )
- {
- HANDLE WriteHandle, ReadHandle;
- WriteHandle = (HANDLE) InterlockedExchange(
- (LPLONG) &WritePipe,
- (LONG) INVALID_HANDLE_VALUE
- );
- if (INVALID_HANDLE_VALUE != WriteHandle) {
- CloseHandle(WriteHandle);
- ReadHandle = (HANDLE) InterlockedExchange(
- (LPLONG) &ReadPipe,
- (LONG) INVALID_HANDLE_VALUE
- );
- if (INVALID_HANDLE_VALUE != ReadHandle &&
- WriteHandle != ReadHandle) {
- CloseHandle(ReadHandle);
- }
- }
- }
- VOID
- HandleConnectError(
- char *server,
- char *srvpipename
- )
- {
- DWORD Err = GetLastError();
- char msg[128];
- Errormsg("*** Unable to Connect ***");
- //
- // Print a helpful message
- //
- switch(Err)
- {
- case ERROR_FILE_NOT_FOUND:
- sprintf(msg,"invalid pipe name %s", srvpipename);
- break;
- case ERROR_BAD_NETPATH:
- sprintf(msg,"\\%s not found", server);
- break;
- default:
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, Err, 0, msg, sizeof(msg), NULL);
- break;
- }
- printf("Diagnosis: %sn",msg);
- //
- // If the machine exists but the pipe doesn't do an
- // automatic remote /q to list pipes available on
- // that machine.
- //
- if (ERROR_FILE_NOT_FOUND == Err) {
- printf("nREMOTE /Q %sn", server);
- fflush(stdout);
- QueryRemotePipes(server);
- }
- }
- HANDLE*
- EstablishSession(
- char *server,
- char *srvpipename
- )
- {
- extern BOOL bForceTwoPipes;
- static HANDLE PipeH[2];
- char pipenameSrvIn[200];
- char pipenameSrvOut[200];
- BOOL fOldServer;
- DWORD dwError;
- DWORD RetryCount = 0;
- //
- // Since in single-pipe operation we'll be using the same
- // pipe in two threads, we have to open the handles for
- // overlapped operation, even though we always want
- // synchronous operation.
- //
- sprintf(pipenameSrvIn ,SERVER_READ_PIPE ,server,srvpipename);
- sprintf(pipenameSrvOut,SERVER_WRITE_PIPE,server,srvpipename);
- if (bForceTwoPipes) {
- dwError = ERROR_NOT_SUPPORTED;
- } else {
- RetrySrvBidi:
- if (INVALID_HANDLE_VALUE ==
- (PipeH[1] =
- CreateFile(
- pipenameSrvIn,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- NULL
- ))) {
- dwError = GetLastError();
- if (ERROR_PIPE_BUSY == dwError) {
- printf( "All pipe instances busy, waiting for another...n");
- WaitNamedPipe(
- pipenameSrvIn,
- 15000
- );
- if (RetryCount++ < 6) {
- goto RetrySrvBidi;
- }
- }
- if (ERROR_ACCESS_DENIED != dwError &&
- ERROR_NOT_SUPPORTED != dwError) {
- HandleConnectError(server, srvpipename);
- return NULL;
- }
- } else {
- PipeH[0] = PipeH[1];
- fAsyncPipe = TRUE;
- printf("Connected...nn");
- SendMyInfo(PipeH);
- return PipeH;
- }
- }
- //
- // Old remote servers don't allow you to open the
- // server IN pipe for READ access, so go down the
- // old path, notably opening OUT first so the
- // server knows we'll be using both pipes. We'll
- // also come down this path on Win95 because
- // it doesn't allow you to open an overlapped
- // pipe handle. Or if remote /c mach pipe /2 is used.
- //
- fOldServer = (ERROR_ACCESS_DENIED == dwError);
- RetrySrvOut:
- if (INVALID_HANDLE_VALUE ==
- (PipeH[0] =
- CreateFile(
- pipenameSrvOut,
- GENERIC_READ,
- 0,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL
- ))) {
- if (ERROR_PIPE_BUSY == GetLastError()) {
- printf( "All OUT pipe instances busy, waiting for another...n");
- WaitNamedPipe(
- pipenameSrvOut,
- 32000 // server recycles abandoned
- ); // OUT pipe after two minutes
- if (RetryCount++ < 6) {
- goto RetrySrvOut;
- }
- }
- HandleConnectError(server, srvpipename);
- return NULL;
- }
- RetrySrvIn:
- if (INVALID_HANDLE_VALUE ==
- (PipeH[1] =
- CreateFile(
- pipenameSrvIn,
- GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL
- ))) {
- dwError = GetLastError();
- if (ERROR_PIPE_BUSY == dwError) {
- printf( "All IN pipe instances busy, waiting for another...n");
- WaitNamedPipe(
- pipenameSrvIn,
- 15000
- );
- if (RetryCount++ < 6) {
- goto RetrySrvIn;
- }
- }
- HandleConnectError(server, srvpipename);
- return NULL;
- }
- fAsyncPipe = FALSE;
- printf("Connected... %snn",
- fOldServer
- ? "to two-pipe remote server."
- : "using two pipes."
- );
- SendMyInfo(PipeH);
- return PipeH;
- }
- VOID
- SendMyInfo(
- PHANDLE pipeH
- )
- {
- HANDLE rPipe=pipeH[0];
- HANDLE wPipe=pipeH[1];
- DWORD hostlen;
- WORD BytesToSend=sizeof(SESSION_STARTUPINFO);
- DWORD tmp;
- OVERLAPPED ol;
- SESSION_STARTUPINFO ssi;
- SESSION_STARTREPLY ssr;
- ol.hEvent =
- CreateEvent(
- NULL, // security
- TRUE, // auto-reset
- FALSE, // initially nonsignaled
- NULL // unnamed
- );
- ssi.Size=BytesToSend;
- ssi.Version=VERSION;
- hostlen = sizeof(ssi.ClientName) / sizeof(ssi.ClientName[0]);
- GetComputerName(ssi.ClientName, &hostlen);
- ssi.LinesToSend=LinesToSend;
- ssi.Flag=ClientToServerFlag;
- {
- DWORD NewCode=MAGICNUMBER;
- char Name[MAX_COMPUTERNAME_LENGTH+1];
- strcpy(Name,(char *)ssi.ClientName);
- memcpy(&Name[11],(char *)&NewCode,sizeof(NewCode));
- //
- // The server needs to know if we're doing single-pipe
- // operation so it can complete the connection properly.
- // So if we are, change the first byte of the first
- // send (the computername, which is later superceded
- // by the one in the SESSION_STARTUPINFO structure)
- // to an illegal computername character, question mark.
- //
- if (wPipe == rPipe) {
- Name[0] = '?';
- }
- WriteFileSynch(wPipe,(char *)Name,HOSTNAMELEN-1,&tmp,0,&ol);
- ReadFileSynch(rPipe ,(char *)&ssr.MagicNumber,sizeof(ssr.MagicNumber),&tmp,0,&ol);
- if (ssr.MagicNumber!=MAGICNUMBER)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- ErrorExit("Pipe connected but server not recognized.n");
- }
- //Get Rest of the info-its not the old server
- ReadFileSynch(
- rPipe,
- (char *)&ssr + sizeof(ssr.MagicNumber),
- sizeof(ssr)-sizeof(ssr.MagicNumber),
- &tmp,
- 0,
- &ol
- );
- }
- if (!WriteFileSynch(wPipe,(char *)&ssi,BytesToSend,&tmp,0,&ol))
- {
- Errormsg("INFO Send Error");
- }
- CloseHandle(ol.hEvent);
- }
- VOID
- QueryRemotePipes(
- char* pszServer
- )
- {
- HANDLE hQPipe;
- DWORD dwRead;
- DWORD dwError;
- char fullname[400];
- char* msg;
- int msgLen;
- if (pszServer[0] == '\' && pszServer[1] == '\') {
- pszServer += 2;
- }
- printf("Querying server \\%sn", pszServer);
- sprintf(fullname, QUERY_DEBUGGERS_PIPE, pszServer);
- //
- // Send request and display the query result
- //
- hQPipe = CreateFile(fullname,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if(hQPipe == INVALID_HANDLE_VALUE) {
- dwError = GetLastError();
- if (ERROR_FILE_NOT_FOUND == dwError) {
- printf("No Remote servers running on \\%sn", pszServer);
- } else if (ERROR_BAD_NETPATH == dwError) {
- printf("\\%s not found on the networkn", pszServer);
- } else {
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, dwError, 0,
- fullname, sizeof(fullname), NULL);
- printf("Can't query server %s: %sn", pszServer, fullname);
- }
- return;
- }
- // Send Query Command
- if(!WriteFile(hQPipe, "q", 1, &dwRead, NULL)
- || (dwRead != 1))
- {
- printf("nError: Can't send commandn");
- goto failure;
- }
- if(!ReadFile(hQPipe,
- &msgLen,
- sizeof(int), // read msg dimension
- &dwRead,
- NULL)
- || (dwRead != sizeof(int)))
- {
- printf("nError: Can't read messagen");
- goto failure;
- }
- if(!msgLen)
- {
- printf("nNo visible sessions on server %s", pszServer);
- goto failure;
- }
- if(msgLen > 65535) // error
- {
- printf("Error querying server %s, got %d for msg length, 65535 max.n",
- pszServer,
- msgLen
- );
- goto failure;
- }
- if((msg = (char*)malloc(msgLen*sizeof(char))) == NULL)
- {
- printf("nOut of memoryn");
- goto failure;
- }
- ReadFile(hQPipe,
- msg,
- msgLen * sizeof(char), // read msg
- &dwRead,
- NULL);
- printf("nVisible sessions on server %s:nn", pszServer);
- printf("%sn", msg);
- free(msg);
- failure:
- CloseHandle(hQPipe);
- }