home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / winnt / rcmd / client.c next >
C/C++ Source or Header  |  1997-10-05  |  6KB  |  284 lines

  1. /*++
  2.  
  3. Copyright 1996 - 1997 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     client.c
  8.  
  9. Abstract:
  10.  
  11.     This sample illustrates a simple client side of the DuplicateTokenEx()
  12.     server sample.
  13.  
  14.     This client functions correctly on the following platforms:
  15.     Windows NT 3.5
  16.     Windows NT 3.51
  17.     Windows NT 4.0
  18.     Windows 95
  19.  
  20. Author:
  21.  
  22.     Scott Field (sfield)    02-Apr-96
  23.  
  24. --*/
  25.  
  26. #include <windows.h>
  27. #include <stdio.h>
  28.  
  29. DWORD
  30. WINAPI
  31. ReadFunc(
  32.     LPVOID lpParam
  33.     );
  34.  
  35. DWORD
  36. WINAPI
  37. WriteFunc(
  38.     LPVOID lpParam
  39.     );
  40.  
  41. void
  42. DisplayWinError(
  43.     LPSTR szAPI,    // pointer to Ansi function name
  44.     DWORD dwError   // DWORD WinError
  45.     );
  46.  
  47. #define RTN_OK 0
  48. #define RTN_USAGE 1
  49. #define RTN_ERROR 13
  50.  
  51. int
  52. __cdecl
  53. main(
  54.     int argc,
  55.     char *argv[]
  56.     )
  57. {
  58.     HANDLE hFileRead;
  59.     HANDLE hFileWrite;
  60.  
  61.     HANDLE hThread;
  62.     DWORD dwThreadId;
  63.  
  64.     CHAR PipeIn[255];
  65.     CHAR PipeOut[255];
  66.  
  67.     if(argc == 1) {
  68.         printf("Usage: %s <\\\\server\n", argv[0]);
  69.         printf("  %s \\\\WINBASE (remote server is \\\\winbase)\n", argv[0]);
  70.         printf("  %s \\\\. (local server)\n",   argv[0]);
  71.         return RTN_USAGE;
  72.     }
  73.  
  74.     //
  75.     // build Pipe names
  76.     //
  77.     wsprintf(PipeIn, "%s\\pipe\\rcmd_out", argv[1]);
  78.     wsprintf(PipeOut, "%s\\pipe\\rcmd_in", argv[1]);
  79.  
  80.     //
  81.     // wait for the outbound (inbound on server-side) pipe to be available
  82.     //
  83.     WaitNamedPipe(PipeOut, NMPWAIT_WAIT_FOREVER);
  84.  
  85.     hFileWrite = CreateFile(
  86.         PipeOut,
  87.         GENERIC_WRITE,
  88.         0, // exclusive open
  89.         NULL,
  90.         OPEN_EXISTING,
  91.         SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, // server can impersonate
  92.         NULL
  93.         );
  94.  
  95.     if(hFileWrite == INVALID_HANDLE_VALUE) {
  96.         DisplayWinError("CreateFile", GetLastError());
  97.         return RTN_ERROR;
  98.     }
  99.  
  100.     //
  101.     // wait for the inbound (outbound on server-side) pipe to be available
  102.     // we time-out in 5 seconds because the server should be ready for us
  103.     // right-away
  104.     //
  105.     WaitNamedPipe(PipeIn, 5 * 1000);
  106.  
  107.     hFileRead = CreateFile(
  108.         PipeIn,
  109.         GENERIC_READ,
  110.         0, // exclusive open
  111.         NULL,
  112.         OPEN_EXISTING,
  113.         0,
  114.         NULL
  115.         );
  116.  
  117.     if(hFileRead == INVALID_HANDLE_VALUE) {
  118.         DisplayWinError("CreateFile", GetLastError());
  119.         return RTN_ERROR;
  120.     }
  121.  
  122.     //
  123.     // start a thread to handle stdin redirection to the pipe
  124.     //
  125.     hThread = CreateThread(
  126.         NULL,
  127.         0,
  128.         WriteFunc,
  129.         (LPVOID)hFileWrite, // parm
  130.         0,
  131.         &dwThreadId
  132.         );
  133.  
  134.     if(hThread == NULL) {
  135.         DisplayWinError("CreateThread", GetLastError());
  136.         return RTN_ERROR;
  137.     }
  138.  
  139.     //
  140.     // handle stdout redirection
  141.     //
  142.     ReadFunc((LPVOID)hFileRead);
  143.  
  144.     //
  145.     // if the read returned, kill the write, cleanup, and then exit
  146.     //
  147.     TerminateThread(hThread, 0xFFFFFFFF);
  148.     CloseHandle(hThread);
  149.  
  150.     CloseHandle(hFileRead);
  151.     CloseHandle(hFileWrite);
  152.  
  153.     return RTN_OK;
  154. }
  155.  
  156. DWORD
  157. WINAPI
  158. ReadFunc(
  159.     LPVOID lpParam
  160.     )
  161. {
  162.     #define BUFFER_SIZE 4096
  163.  
  164.     HANDLE hFile = (HANDLE)lpParam;
  165.     BYTE lpBuffer[BUFFER_SIZE];
  166.  
  167.     DWORD dwBytesRead;
  168.     DWORD dwBytesWritten;
  169.  
  170.     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  171.  
  172.     DWORD dwLastError;
  173.  
  174.     while (1) {
  175.         if(!ReadFile(
  176.             hFile,
  177.             lpBuffer,
  178.             BUFFER_SIZE,
  179.             &dwBytesRead,
  180.             NULL
  181.             )) {
  182.             dwLastError = GetLastError();
  183.  
  184.             if(dwLastError == ERROR_NO_DATA) continue;
  185.             if(dwLastError != ERROR_MORE_DATA) break;
  186.         }
  187.  
  188.         if(!WriteFile(
  189.             hStdOut,
  190.             lpBuffer,
  191.             dwBytesRead,
  192.             &dwBytesWritten,
  193.             NULL
  194.             )) break;
  195.     }
  196.  
  197.     return GetLastError();
  198. }
  199.  
  200. DWORD
  201. WINAPI
  202. WriteFunc(
  203.     LPVOID lpParam
  204.     )
  205. {
  206.     HANDLE hPipe = (HANDLE)lpParam;
  207.  
  208.     BYTE lpBuffer[ 1 ]; // change this later
  209.  
  210.     DWORD dwBytesRead;
  211.     DWORD dwBytesWritten;
  212.  
  213.     HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
  214.  
  215.     while (1) {
  216.         //
  217.         // TODO rework this loop to be line-based.
  218.         // this would entail doing the console buffering outselves.
  219.         //
  220.         if(!ReadFile(
  221.             hStdIn,
  222.             lpBuffer,
  223.             1,
  224.             &dwBytesRead,
  225.             NULL
  226.             )) break;
  227.  
  228.         if(!WriteFile(
  229.             hPipe,
  230.             lpBuffer,
  231.             dwBytesRead,
  232.             &dwBytesWritten,
  233.             NULL
  234.             )) break;
  235.     }
  236.  
  237.     return GetLastError();
  238. }
  239.  
  240. void
  241. DisplayWinError(
  242.     LPSTR szAPI,    // pointer to Ansi function name
  243.     DWORD dwError   // DWORD WinError
  244.     )
  245. {
  246.     LPSTR MessageBuffer;
  247.     DWORD dwBufferLength;
  248.  
  249.     //
  250.     // TODO get this fprintf out of here!
  251.     //
  252.     fprintf(stderr,"%s error!\n", szAPI);
  253.  
  254.     if(dwBufferLength=FormatMessageA(
  255.             FORMAT_MESSAGE_ALLOCATE_BUFFER |
  256.             FORMAT_MESSAGE_FROM_SYSTEM,
  257.             NULL,
  258.             dwError,
  259.             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  260.             (LPSTR) &MessageBuffer,
  261.             0,
  262.             NULL
  263.             ))
  264.     {
  265.         DWORD dwBytesWritten; // unused
  266.  
  267.         //
  268.         // Output message string on stderr
  269.         //
  270.         WriteFile(
  271.                 GetStdHandle(STD_ERROR_HANDLE),
  272.                 MessageBuffer,
  273.                 dwBufferLength,
  274.                 &dwBytesWritten,
  275.                 NULL
  276.                 );
  277.  
  278.         //
  279.         // free the buffer allocated by the system
  280.         //
  281.         LocalFree(MessageBuffer);
  282.     }
  283. }
  284.