Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Mar 31st, 2011  |  syntax: C  |  size: 7.15 KB  |  views: 259  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /* gcc -g -Wall -o server.exe server4.c */
  2.  
  3. #include <stdio.h>
  4.  
  5. #include <windows.h>
  6. #include <process.h>
  7.  
  8.  
  9. #define BUFSIZE 512
  10.  
  11. HANDLE objects[3];
  12.  
  13. typedef struct
  14. {
  15.   HANDLE pipe;
  16.   HANDLE event_exit;
  17.   OVERLAPPED ol;
  18.   OVERLAPPED ol_read;
  19.   DWORD read_count;
  20.   int exit_thread;
  21.  
  22.   /* in normal struct */
  23.   void *data;
  24.   int size;
  25. } Server;
  26.  
  27. void print_last_error(const char *fct);
  28.  
  29.  
  30. static __stdcall unsigned int
  31. _read_data_cb(void *data)
  32. {
  33. #define READ_BUFSIZE 5
  34.   char buf[READ_BUFSIZE];
  35.   Server *svr;
  36.   DWORD ret;
  37.   DWORD nbr_bytes;
  38.   BOOL res;
  39.  
  40.   svr = (Server *)data;
  41.  
  42.   while (!svr->exit_thread)
  43.     {
  44.       ret = ReadFile(svr->pipe, buf, sizeof(buf), &nbr_bytes, &svr->ol_read);
  45.       if (!ret)
  46.         {
  47.           DWORD err = GetLastError();
  48.           if (err == ERROR_IO_PENDING)
  49.             {
  50.               /* Let's wait for the event to be signaled  ?? */
  51.               /* Call GetOverlappedResult ?? */
  52.             }
  53.           else if (ret == ERROR_BROKEN_PIPE)
  54.             {
  55.               printf(" * broken pipe\n");
  56.               SetEvent(svr->event_exit);
  57.             }
  58.           else
  59.             {
  60.               printf(" * unexpected error %ld\n", ret);
  61.               SetEvent(svr->event_exit);
  62.             }
  63.         }
  64.       else
  65.         {
  66.           printf(" * ReadFile : %ld\n", nbr_bytes);
  67.         }
  68.     }
  69.  
  70.   _endthreadex(0);
  71.   return 0;
  72. }
  73.  
  74. void print_last_error(const char *fct)
  75. {
  76.   char *buf;
  77.   DWORD dw = GetLastError();
  78.  
  79.   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  80.                 FORMAT_MESSAGE_FROM_SYSTEM |
  81.                 FORMAT_MESSAGE_IGNORE_INSERTS,
  82.                 NULL,
  83.                 dw,
  84.                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  85.                 (LPTSTR) &buf,
  86.                 0, NULL );
  87.  
  88.     // Display the error message and exit the process
  89.  
  90.   printf("%s failed with error %ld: %s\n", fct, dw, buf);
  91.   LocalFree(buf);
  92. }
  93.  
  94. Server *
  95. server_new(const char *name)
  96. {
  97.   char buf[256];
  98.   Server *svr;
  99.   HANDLE event;
  100.   BOOL res;
  101.  
  102.   if (!name)
  103.     return NULL;
  104.  
  105.   svr = (Server *)calloc(1,sizeof(Server));
  106.   if (!svr)
  107.     return NULL;
  108.  
  109.   snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", name);
  110.  
  111.   /*
  112.    * Asynchronuous
  113.    * block mode
  114.    */
  115.   svr->pipe = CreateNamedPipe(buf,
  116.                               PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
  117.                               PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
  118.                               PIPE_UNLIMITED_INSTANCES,
  119.                               512, 512, 5000, NULL);
  120.   if (!svr->pipe)
  121.     {
  122.       print_last_error("CreateNamedPipe");
  123.       goto free_svr;
  124.     }
  125.  
  126.   /*
  127.    * Manual reset
  128.    * Initial state : non signaled
  129.    */
  130.   event = CreateEvent(NULL, TRUE, FALSE, NULL);
  131.   if (!event)
  132.     {
  133.       print_last_error("CreateEvent");
  134.       goto close_pipe;
  135.     }
  136.  
  137.   memset(&svr->ol, 0, sizeof(svr->ol));
  138.   svr->ol.hEvent = event;
  139.  
  140.   res = ConnectNamedPipe(svr->pipe, &svr->ol);
  141.   if (res)
  142.     {
  143.       print_last_error("ConnectNamedPipe");
  144.       goto close_event;
  145.     }
  146.   else
  147.     {
  148.       DWORD err = GetLastError();
  149.  
  150.       if (err == ERROR_PIPE_CONNECTED)
  151.         {
  152.           SetEvent(svr->ol.hEvent);
  153.           printf("client connected\n");
  154.         }
  155.       else if (err != ERROR_IO_PENDING)
  156.         {
  157.           print_last_error("ConnectNamedPipe");
  158.           goto close_event;
  159.         }
  160.       /* else, we have ERROR_IO_PENDING, so a connection link is pending */
  161.     }
  162.  
  163.   /*
  164.    * Manual reset
  165.    * Initial state : non signaled
  166.    */
  167.   svr->event_exit = CreateEvent(NULL, TRUE, FALSE, NULL);
  168.   if (!svr->event_exit)
  169.     {
  170.       print_last_error("CreateEvent (event exit)");
  171.       goto close_event;
  172.     }
  173.  
  174.   /*
  175.    * Manual reset
  176.    * Initial state : non signaled
  177.    */
  178.   memset(&svr->ol_read, 0, sizeof(svr->ol_read));
  179.   svr->ol_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  180.   if (!svr->ol_read.hEvent)
  181.     {
  182.       print_last_error("CreateEvent (event exit)");
  183.       goto close_event_exit;
  184.     }
  185.  
  186.   /* start reading the pipe */
  187.   objects[0] = event;
  188.   objects[1] = svr->event_exit;
  189.   objects[2] = svr->ol_read.hEvent;
  190.  
  191.   return svr;
  192.  
  193.  close_event_exit:
  194.   CloseHandle(svr->event_exit);
  195.  close_event:
  196.   CloseHandle(event);
  197.  close_pipe:
  198.   CloseHandle(svr->pipe);
  199.  free_svr:
  200.   free(svr);
  201.  
  202.   return NULL;
  203. }
  204.  
  205. void
  206. server_del(Server *svr)
  207. {
  208.   if (!svr)
  209.     return;
  210.  
  211.   CloseHandle(svr->event_exit);
  212.   if (!FlushFileBuffers(svr->pipe))
  213.     {
  214.       print_last_error("FlushFileBuffers");
  215.     }
  216.   if (!DisconnectNamedPipe(svr->pipe))
  217.     {
  218.       print_last_error("DisconnectNamedPipe");
  219.     }
  220.   CloseHandle(svr->ol.hEvent);
  221.   CloseHandle(svr->pipe);
  222.   free(svr);
  223. }
  224.  
  225. int main()
  226. {
  227.   Server *svr;
  228.   DWORD ret;
  229.   DWORD nbr_bytes;
  230.   BOOL res;
  231.  
  232.   svr = server_new("toto");
  233.   if (!svr)
  234.     return -1;
  235.  
  236.   printf("waiting for client...\n");
  237.  
  238.   while (1)
  239.     {
  240.       ret = WaitForMultipleObjects(3, objects, FALSE, INFINITE);
  241.       if (ret == WAIT_FAILED)
  242.         {
  243.           print_last_error("WaitForMultipleObjects");
  244.           goto beach;
  245.         }
  246.       printf("WaitForMultipleObjects : %ld\n", ret);
  247.  
  248.       if (ret == WAIT_OBJECT_0)
  249.         {
  250.           ResetEvent(svr->ol.hEvent);
  251.  
  252.           res = GetOverlappedResult(svr->pipe, &svr->ol,
  253.                                     &nbr_bytes, FALSE);
  254.           if (!res)
  255.             {
  256.               print_last_error("GetOverlappedResult");
  257.  
  258.               if (!DisconnectNamedPipe(svr->pipe))
  259.                 {
  260.                   print_last_error("DisconnectNamedPipe");
  261.                   goto beach;
  262.                 }
  263.  
  264.               res = ConnectNamedPipe(svr->pipe, &svr->ol);
  265.               if (res)
  266.                 {
  267.                   print_last_error("ConnectNamedPipe");
  268.                   goto beach;
  269.                 }
  270.               else
  271.                 {
  272.                   DWORD err = GetLastError();
  273.  
  274.                   if (err == ERROR_PIPE_CONNECTED)
  275.                     {
  276.                       SetEvent(svr->ol.hEvent);
  277.                     }
  278.                   else if (err != ERROR_IO_PENDING)
  279.                     {
  280.                       print_last_error("ConnectNamedPipe");
  281.                       goto beach;
  282.                     }
  283.                   /* else, we have ERROR_IO_PENDING, so a connection link is pending */
  284.                 }
  285.             }
  286.           else
  287.             {
  288.               printf("client connected (%d)\n", res);
  289.  
  290.               /* read pipe */
  291.               _beginthreadex(NULL, 0, _read_data_cb, svr, 0, NULL);
  292.             }
  293.         }
  294.       if (ret == (WAIT_OBJECT_0 + 1))
  295.         {
  296.           printf("client connection closed\n");
  297.           svr->exit_thread = 1;
  298.           goto beach;
  299.         }
  300.       if (ret == (WAIT_OBJECT_0 + 2))
  301.         {
  302.           ResetEvent(svr->ol_read.hEvent);
  303.           /* res = GetOverlappedResult(svr->pipe, &svr->ol_read, */
  304.           /*                           &nbr_bytes, TRUE); */
  305.           /* if (res) printf(" nbr bytes : %ld\n", nbr_bytes); */
  306.           /* else */
  307.           /*   print_last_error("GetOverlappedResult"); */
  308.         }
  309.     }
  310.  
  311.  beach:
  312.   server_del(svr);
  313.  
  314.   return 0;
  315. }