Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Feb 11th, 2011  |  syntax: C  |  size: 6.46 KB  |  views: 502  |  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. #include <Windows.h>
  2. #include <stdio.h>
  3. #include <tchar.h>
  4.  
  5. #define NPC_MAX_RETRIES 3
  6. #define NPC_WAIT_TIMEOUT_IN_MS 10000
  7. #define NPC_TRANSFER_BUFFER_SIZE 8192
  8. #define NPC_WAIT_DATA_TIMEOUT 1000
  9.  
  10. #define NPC_READ_END 0
  11. #define NPC_WRITE_END 1
  12.  
  13. //
  14. // Structures
  15. //
  16.  
  17. typedef struct _NPC_CONNECTION
  18. {
  19.         HANDLE Peer1;
  20.         HANDLE Peer2;
  21. } NPC_CONNECTION, *PNPC_CONNECTION;
  22.  
  23. typedef enum _NPC_TRANSFER_STATE
  24. {
  25.         IoPending,
  26.         Idle
  27. } NPC_TRANSFER_STATE, *PNPC_TRANSFER_STATE;
  28.  
  29. typedef struct _NPC_ENDPOINT
  30. {
  31.         OVERLAPPED Overlap;
  32.         UCHAR TransferBuffer[4048];
  33.         NPC_TRANSFER_STATE State;
  34.         HANDLE Pipe;
  35. } NPC_ENDPOINT, *PNPC_ENDPOINT;
  36.  
  37. //
  38. // Macros
  39. //
  40.  
  41. #define NpcCreateConnection(Connection, From, To) \
  42.         (Connection)->Peer1 = (From); \
  43.         (Connection)->Peer2 = (To);
  44.  
  45. #define NpcPrintError(Message, Code) \
  46.         PrintError((Message), (Code), TEXT(__FILE__), __LINE__);
  47.  
  48. HANDLE Server1, Server2;
  49. HANDLE Mutex;
  50.  
  51. VOID PrintError(TCHAR *Message, DWORD ErrorCode, TCHAR* File, DWORD Line)
  52. {
  53.         LPVOID lpMessageBuffer;
  54.  
  55.         FormatMessage(
  56.                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
  57.                 FORMAT_MESSAGE_FROM_SYSTEM,
  58.                 NULL,
  59.                 ErrorCode,  
  60.                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  61.                 (LPTSTR) &lpMessageBuffer,  
  62.                 0,  
  63.                 NULL );
  64.  
  65.         _tprintf(TEXT("[ERROR] %ws:%d: %ws: %ws"), File, Line, Message, lpMessageBuffer);
  66.  
  67.         LocalFree( lpMessageBuffer );
  68. }
  69.  
  70. HANDLE NpcOpenPipe(TCHAR *PipeName)
  71. {
  72.         HANDLE Pipe;
  73.  
  74.         do
  75.         {
  76.                 int ConnectionRetries = 0;
  77.                 BOOL WaitSuccessful = FALSE;
  78.  
  79.                 Pipe = CreateFile(
  80.                         PipeName,
  81.                         GENERIC_READ | GENERIC_WRITE,
  82.                         0,
  83.                         NULL,
  84.                         OPEN_EXISTING,
  85.             FILE_FLAG_OVERLAPPED,
  86.                         NULL);
  87.  
  88.                 if (Pipe != INVALID_HANDLE_VALUE)
  89.                 {
  90.                         return Pipe;
  91.                 }
  92.  
  93.                 if (GetLastError() != ERROR_PIPE_BUSY)
  94.                 {
  95.                         NpcPrintError(TEXT("CreateFile"), GetLastError());
  96.                         return Pipe;
  97.                 }
  98.  
  99.                 // All pipe instances are busy, so wait some time ...
  100.  
  101.                 for(ConnectionRetries = 0; ConnectionRetries < NPC_MAX_RETRIES; ConnectionRetries++)
  102.                 {
  103.                         WaitSuccessful = WaitNamedPipe(PipeName, NPC_WAIT_TIMEOUT_IN_MS);
  104.                         if (WaitSuccessful)
  105.                         {
  106.                                 break;
  107.                         }
  108.                 }
  109.  
  110.                 if (!WaitSuccessful)
  111.                 {
  112.                         NpcPrintError(TEXT("WaitNamedPipe"), GetLastError());
  113.                         break;
  114.                 }
  115.  
  116.         } while (TRUE);
  117.  
  118.         return INVALID_HANDLE_VALUE;
  119.  
  120. }
  121.  
  122. BOOL NpcInitializeIoEvents(__ecount(EventCount) PHANDLE Events, DWORD EventCount)
  123. {
  124.         DWORD i;
  125.  
  126.         for (i = 0; i < EventCount; i++)
  127.         {
  128.                 Events[i] = CreateEvent(
  129.                         NULL,
  130.                         TRUE,
  131.                         FALSE,
  132.                         NULL);
  133.  
  134.                 if (Events[i] == INVALID_HANDLE_VALUE)
  135.                 {
  136.                         NpcPrintError(TEXT("CreateEvent"), GetLastError());
  137.                         return FALSE;
  138.                 }
  139.         }
  140.  
  141.         return TRUE;
  142. }
  143.  
  144. DWORD WINAPI NpcTransferThread(LPVOID Param)
  145. {
  146.         PNPC_CONNECTION Connection = (PNPC_CONNECTION) Param;
  147.         UCHAR TransferBuffer[NPC_TRANSFER_BUFFER_SIZE];
  148.         DWORD BytesRead = 0, BytesWritten;
  149.         BOOL OperationSuccess = FALSE;
  150.         PUCHAR NextByte = TransferBuffer;
  151.         HANDLE IoEvents[2];
  152.     DWORD ThreadId = GetCurrentThreadId();
  153.     char * WaitPeer1 = "";
  154.  
  155.     DWORD BulkRead;
  156.     PUCHAR ReadOffset;
  157.  
  158.         OVERLAPPED Peer1Overlap, Peer2Overlap;
  159.  
  160.         ZeroMemory(TransferBuffer, sizeof(TransferBuffer));
  161.         ZeroMemory(&Peer1Overlap, sizeof(OVERLAPPED));
  162.         ZeroMemory(&Peer2Overlap, sizeof(OVERLAPPED));
  163.  
  164.         if (!NpcInitializeIoEvents(IoEvents, 2))
  165.         {
  166.                 NpcPrintError(TEXT("NpcInitializeIoEvents"), GetLastError());
  167.                 return -1;
  168.         }
  169.  
  170.         Peer1Overlap.hEvent = IoEvents[NPC_READ_END];
  171.         Peer2Overlap.hEvent = IoEvents[NPC_WRITE_END];
  172.  
  173.         while (1)
  174.         {
  175.  
  176.                 // Read data from Peer 1
  177.  
  178.         ReadOffset = TransferBuffer;
  179.         BulkRead = 0;
  180.                
  181.                 OperationSuccess = ReadFile(
  182.                         Connection->Peer1,
  183.                         TransferBuffer,
  184.                         sizeof(TransferBuffer),
  185.                         &BytesRead,
  186.                         &Peer1Overlap);
  187.  
  188.                 //
  189.                 // Ignore if there is more data to read since we will continue reading
  190.                 // data at the next iteration of the loop.
  191.                 //
  192.  
  193.                 if (!OperationSuccess)
  194.                 {
  195.                         if (GetLastError() == ERROR_IO_PENDING)
  196.                         {
  197.  
  198.                                 //
  199.                                 // Now update how many data we read
  200.                                 //
  201.                                 if (!GetOverlappedResult(
  202.                                         Connection->Peer1,
  203.                                         &Peer1Overlap,
  204.                                         &BytesRead,
  205.                                         TRUE))
  206.                                 {
  207.                                         NpcPrintError(TEXT("GetOverlappedResult"), GetLastError());
  208.                                         return GetLastError();
  209.                                 }
  210.  
  211.                         }
  212.                         else
  213.                         {
  214.                                 NpcPrintError(TEXT("ReadFile"), GetLastError());
  215.                                 return -1;
  216.                         }
  217.                 }
  218.  
  219.  
  220.                 //
  221.                 // Send data to peer 2, as long as we have data in the buffer ...
  222.                 //
  223.  
  224.                 NextByte = TransferBuffer;
  225.         TransferBuffer[BytesRead] = 0;
  226.                 while (BytesRead)
  227.                 {
  228.  
  229.                         OperationSuccess = WriteFile(
  230.                                 Connection->Peer2,
  231.                                 NextByte,
  232.                                 BytesRead,
  233.                                 &BytesWritten,
  234.                                 &Peer2Overlap);
  235.  
  236.                         if (!OperationSuccess)
  237.                         {
  238.                 if (GetLastError() == ERROR_IO_PENDING)
  239.                 {
  240.                                     if (!GetOverlappedResult(Connection->Peer2, &Peer2Overlap, &BytesWritten, TRUE))
  241.                                     {
  242.                                             NpcPrintError(TEXT("GetOverlappedResult"), GetLastError());
  243.                                             return GetLastError();
  244.                                     }
  245.  
  246.                 }
  247.                 else
  248.                 {
  249.                     NpcPrintError(TEXT("WriteFile"),GetLastError());
  250.                     return -1;
  251.                 }
  252.                         }
  253.  
  254.                         BytesRead -= BytesWritten;
  255.                         NextByte += BytesWritten;
  256.            
  257.                 }
  258.         }
  259.  
  260.         return 0;
  261. }
  262.  
  263. HANDLE NpcConnect(PNPC_CONNECTION Connection)
  264. {
  265.         return CreateThread(
  266.                 NULL,
  267.                 0,
  268.                 NpcTransferThread,
  269.                 Connection,
  270.                 0,
  271.                 NULL);
  272. }
  273.  
  274. int _tmain(int argc, TCHAR *argv[])
  275. {
  276.         NPC_CONNECTION Peer1_to_Peer2;
  277.         NPC_CONNECTION Peer2_to_Peer1;
  278.         HANDLE WaitableResources[4];
  279.         PHANDLE Connections = WaitableResources;
  280.         PHANDLE Servers = &WaitableResources[2];
  281.  
  282.         if (argc != 3)
  283.         {
  284.                 printf("Usage: %ws <pipe1> <pipe2>\n", argv[0]);
  285.                 return -1;
  286.         }
  287.  
  288.     _tprintf(TEXT("Connecting '%s' <-> '%s' ...\n"), argv[1], argv[2]);
  289.  
  290.         Servers[0] = NpcOpenPipe(argv[1]);
  291.         if (Server1 == INVALID_HANDLE_VALUE)
  292.         {
  293.                 NpcPrintError(TEXT("NpcOpenPipe 1"), GetLastError());
  294.                 return -1;
  295.         }
  296.  
  297.         Servers[1] = NpcOpenPipe(argv[2]);
  298.         if (Server2 == INVALID_HANDLE_VALUE)
  299.         {
  300.                 NpcPrintError(TEXT("NpcOpenPipe 2"), GetLastError());
  301.                 return -1;
  302.         }
  303.  
  304.         NpcCreateConnection(&Peer1_to_Peer2, Servers[0], Servers[1]);
  305.         NpcCreateConnection(&Peer2_to_Peer1, Servers[1], Servers[0]);
  306.  
  307.     Mutex = CreateMutex(
  308.         NULL,
  309.         FALSE,
  310.         NULL);
  311.     if (Mutex == INVALID_HANDLE_VALUE)
  312.     {
  313.         NpcPrintError(TEXT("CreateMutex"), GetLastError());
  314.         return -1;
  315.     }
  316.  
  317.         Connections[0] = NpcConnect(&Peer1_to_Peer2);
  318.         if (Connections[0] == INVALID_HANDLE_VALUE)
  319.         {
  320.                 NpcPrintError(TEXT("NpcConnect"), GetLastError());
  321.                 return -1;
  322.         }
  323.  
  324.         Connections[1] = NpcConnect(&Peer2_to_Peer1);
  325.         if (Connections[1] == INVALID_HANDLE_VALUE)
  326.         {
  327.                 NpcPrintError(TEXT("NpcConnect"), GetLastError());
  328.                 return -1;
  329.         }
  330.  
  331.  
  332.     _tprintf(TEXT("Connection established.\n"));
  333.  
  334.         WaitForMultipleObjects(
  335.                 4,
  336.                 WaitableResources,
  337.                 TRUE,
  338.                 INFINITE);
  339.  
  340.         return 0;
  341. }
clone this paste RAW Paste Data