home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / sna / aremote / client.c < prev    next >
Text File  |  1997-04-09  |  8KB  |  271 lines

  1. /*
  2. Copyright (c) 1994, 1993 Microsoft Corporation
  3.  
  4. Module Name:
  5.     Client.c
  6.  
  7. Abstract:
  8.     The Client component of Remote. Connects to the remote
  9.     server using named pipes. It sends its stdin to
  10.     the server and output everything from server to
  11.     its stdout.
  12.  
  13. Author:
  14.     Rajivendra Nath (rajnath) 2-Jan-1993
  15.  
  16. Environment:
  17.     Console App. User mode.
  18.  
  19. Revision History:
  20.     Alex Wetmore (t-alexwe) 6-Jun-1994
  21.         - converted remote to use APPC with Windows SNA Server instead of named
  22.           pipes
  23. */
  24.  
  25. #include <windows.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <io.h>
  29. #include <string.h>
  30. #include <winappc.h>
  31. #include "appclib.h"
  32. #include "aremote.h"
  33.  
  34. tpconvid_t EstablishSession(TCHAR *locallu, TCHAR *serverlu, TCHAR *tpname, 
  35.     TCHAR *loctpname, TCHAR *mode_name);
  36. DWORD WINAPI GetServerOut(PVOID *Noarg);
  37. DWORD WINAPI SendServerInp(PVOID *Noarg);
  38. BOOL FilterClientInp(TCHAR *buff, int count);
  39. BOOL Mych(DWORD ctrlT);
  40. VOID SendMyInfo(tpconvid_t tpconv);
  41.  
  42.  
  43. HANDLE iothreads[2];
  44. HANDLE MyStdInp;
  45. HANDLE MyStdOut;
  46. tpconvid_t tpconv;
  47.  
  48.  
  49. CONSOLE_SCREEN_BUFFER_INFO csbi;
  50.  
  51. TCHAR   MyEchoStr[30];
  52. BOOL   CmdSent;
  53. DWORD  LinesToSend=LINESTOSEND;
  54.  
  55. VOID Client(TCHAR *local_lu, TCHAR *server_lu, TCHAR *tp_name, 
  56.             TCHAR *loc_tp_name, TCHAR *mode_name) {
  57.     DWORD  tid;
  58.  
  59.  
  60.     MyStdInp=GetStdHandle(STD_INPUT_HANDLE);
  61.     MyStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
  62.  
  63.     WRITEF((VBuff,TEXT("**************************************\n")));
  64.     WRITEF((VBuff,TEXT("***********     REMOTE    ************\n")));
  65.     WRITEF((VBuff,TEXT("***********     CLIENT    ************\n")));
  66.     WRITEF((VBuff,TEXT("**************************************\n")));
  67.  
  68.     tpconv = EstablishSession(local_lu, server_lu, tp_name, loc_tp_name, 
  69.         mode_name);
  70.     if (tpconv == NULL) {
  71.         appcdestroy();
  72.         return;
  73.     }
  74.  
  75.     SetConsoleCtrlHandler((PHANDLER_ROUTINE)Mych,TRUE);
  76.  
  77.     // Start Thread For Server --> Client Flow
  78.     if ((iothreads[0]=CreateThread((LPSECURITY_ATTRIBUTES)NULL,     // No security attributes.
  79.             (DWORD)0,                                               // Use same stack size.
  80.             (LPTHREAD_START_ROUTINE)GetServerOut,                     // Thread procedure.
  81.             (LPVOID)NULL,                                              // Parameter to pass.
  82.             (DWORD)0,                                               // Run immediately.
  83.             (LPDWORD)&tid))==NULL)                                  // Thread identifier.
  84.     {
  85.  
  86.         Errormsg(TEXT("Could Not Create rwSrv2Cl Thread"));
  87.         return;
  88.     }
  89.  
  90.  
  91.  
  92.     //
  93.     // Start Thread for Client --> Server Flow
  94.     //
  95.  
  96.     if ((iothreads[1]=CreateThread((LPSECURITY_ATTRIBUTES)NULL,           // No security attributes.
  97.                     (DWORD)0,                           // Use same stack size.
  98.                     (LPTHREAD_START_ROUTINE)SendServerInp, // Thread procedure.
  99.                     (LPVOID)NULL,          // Parameter to pass.
  100.                     (DWORD)0,                           // Run immediately.
  101.                     (LPDWORD)&tid))==NULL)              // Thread identifier.
  102.     {
  103.  
  104.         Errormsg(TEXT("Could Not Create rwSrv2Cl Thread"));
  105.         return;
  106.     }
  107.  
  108.     WaitForSingleObject(iothreads[0], INFINITE);
  109.  
  110.     TerminateThread(iothreads[1],1);
  111.  
  112.     appcclose(tpconv);
  113.     appcdestroy();
  114.  
  115.     WRITEF((VBuff,TEXT("*** SESSION OVER ***\n")));
  116. }
  117.  
  118.  
  119. DWORD WINAPI GetServerOut(PVOID *Noarg) {
  120.     TCHAR buffin[1024];
  121.     DWORD dread=0,tmp;
  122.  
  123.     while (appcvalid(tpconv)) {
  124.         dread = appcread(tpconv, (void *) buffin, 1000);
  125.         if (dread > 0) {
  126.             if (!WriteConsole(MyStdOut, buffin, dread/2, &tmp, NULL))
  127.                 break;
  128.         }
  129.     }
  130.     return 1;
  131. }
  132.  
  133. DWORD WINAPI SendServerInp(PVOID *Noarg) {
  134.     TCHAR buff[1000];
  135.     DWORD dread;
  136.     SetLastError(0);
  137.  
  138.     while(ReadConsole(MyStdInp,buff,999,&dread,NULL)) {
  139.         if (FilterClientInp(buff, dread)) continue;
  140.         appcwrite(tpconv, (void *) buff, dread * sizeof(TCHAR));
  141.     }
  142.     return 0;
  143. }
  144.  
  145. BOOL FilterClientInp(TCHAR *buff, int count) {
  146.     if (count==0)
  147.         return(TRUE);
  148.  
  149.     if (buff[0]==2)  //Adhoc screening of ^B so that i386kd/mipskd
  150.         return(TRUE);//do not terminate.
  151.  
  152.     if (buff[0]==COMMANDCHAR) {
  153.         switch (tolower(buff[1])) {
  154.             case TEXT('k'):
  155.             case TEXT('q'):
  156.                 return(FALSE);
  157.  
  158.             case TEXT('h'):
  159.                 WRITEF((VBuff,TEXT("%cM : Send Message\n"),COMMANDCHAR));
  160.                 WRITEF((VBuff,TEXT("%cP : Show Popup on Server\n"),COMMANDCHAR));
  161.                 WRITEF((VBuff,TEXT("%cS : Status of Server\n"),COMMANDCHAR));
  162.                 WRITEF((VBuff,TEXT("%cQ : Quit client\n"),COMMANDCHAR));
  163.                 WRITEF((VBuff,TEXT("%cH : This Help\n"),COMMANDCHAR));
  164.                 return(TRUE);
  165.  
  166.             default:
  167.                 return(FALSE);
  168.         }
  169.  
  170.     }
  171.     return(FALSE);
  172. }
  173.  
  174.  
  175. BOOL Mych(DWORD ctrlT) {
  176.     TCHAR  c[3];
  177.     DWORD send;
  178.  
  179.     if (ctrlT==CTRL_C_EVENT) {
  180.         c[0] = 3;
  181.         send = 1;
  182.         appcwrite(tpconv, (void *) c, send);
  183.     }
  184.     if ((ctrlT==CTRL_BREAK_EVENT) ||
  185.         (ctrlT==CTRL_CLOSE_EVENT) ||
  186.         (ctrlT==CTRL_LOGOFF_EVENT) ||
  187.         (ctrlT==CTRL_SHUTDOWN_EVENT)) {
  188.         c[0] = COMMANDCHAR;
  189.         c[1] = TEXT('q');
  190.         send = 2;
  191.         appcwrite(tpconv, (void *) c, send);
  192.     }
  193.     return(TRUE);
  194. }
  195.  
  196. tpconvid_t EstablishSession(TCHAR *local_lu, TCHAR *server_lu, TCHAR *tp_name, 
  197.                             TCHAR *loc_tp_name, TCHAR *mode_name) {
  198.     TCHAR buf[255];
  199.     tpconvid_t tpconv;
  200.  
  201.     appcinit();
  202.     WRITEF((VBuff, TEXT("\nClient Connection Information:\n")));
  203.     WRITEF((VBuff, TEXT("  Local LU       = %ws\n"), local_lu));
  204.     WRITEF((VBuff, TEXT("  Server LU      = %ws\n"), server_lu));
  205.     WRITEF((VBuff, TEXT("  Server TP Name = %ws\n"), tp_name));
  206.     WRITEF((VBuff, TEXT("  Client TP Name = %ws\n"), loc_tp_name));
  207.     WRITEF((VBuff, TEXT("  Mode Name      = %ws\n"), mode_name));
  208.     WRITEF((VBuff, TEXT("\n")));
  209.     WRITEF((VBuff, TEXT("Connecting . . . ")));
  210.  
  211.     // connect to the server
  212.     tpconv = appcconnect(local_lu, server_lu, tp_name, loc_tp_name, mode_name);
  213.  
  214.     // the server will either send us zero bytes (signifying a valid 
  215.     // connection), or close our connection.  If it is closed then
  216.     // let the client know
  217.     appcread(tpconv, buf, 255);
  218.     if (!appcvalid(tpconv)) {
  219.         WRITEF((VBuff, 
  220.             TEXT("Remote: server doesn't have any available sessions\n")));
  221.         return NULL;
  222.     }
  223.     if (lstrcmp(buf, REMOTE_INIT_MSG) != 0) {
  224.         WRITEF((VBuff, 
  225.             TEXT("Remote: this doesn't seem to be a remote server\n")));
  226.         return NULL;
  227.     }
  228.  
  229.     WRITEF((VBuff, TEXT("\rConnected        \n\n")));
  230.     SendMyInfo(tpconv);
  231.  
  232.     return tpconv;
  233. }
  234.  
  235. VOID SendMyInfo(tpconvid_t tpconv) {
  236.     DWORD  hostlen=HOSTNAMELEN-1;
  237.     DWORD  tmp, BytesToRead;
  238.     SESSION_STARTUPINFO ssi;
  239.     SESSION_STARTREPLY  ssr;
  240.     TCHAR   *buff;
  241.  
  242.     // fill out the SESSION_STARTUPINFO structure
  243.     ssi.MagicNumber = MAGICNUMBER;
  244.     GetComputerName((TCHAR *) ssi.ClientName, &hostlen);
  245.     ssi.LinesToSend = LinesToSend;
  246.     ssi.Flag = ClientToServerFlag;
  247.     appcwrite(tpconv, (void *) &ssi, sizeof(ssi));
  248.  
  249.     // receive a SESSION_STARTUPREPLY structure
  250.     appcread(tpconv, (void *) &ssr, sizeof(ssr));
  251.  
  252.     if (ssr.MagicNumber < MAGICNUMBER) {
  253.         WRITEF((VBuff, TEXT("Warning: this APPC Remote server is older than your client\n")));
  254.     } else if (ssr.MagicNumber > MAGICNUMBER) {
  255.         WRITEF((VBuff, TEXT("Warning: your APPC Remote client is older than the server \n")));
  256.     }
  257.  
  258.     BytesToRead=MINIMUM(ssr.FileSize,ssi.LinesToSend*CHARS_PER_LINE);
  259.     buff=calloc(BytesToRead+1,sizeof(TCHAR));
  260.     if (buff!=NULL)
  261.     {
  262.         DWORD  bytesread=0;
  263.  
  264.         bytesread = appcread(tpconv, (void *) buff, BytesToRead*sizeof(TCHAR));
  265.  
  266.         WriteConsole(MyStdOut,buff,bytesread/sizeof(TCHAR),&tmp,NULL);
  267.         LocalFree(buff);
  268.     }
  269.  
  270. }
  271.