Advertisement
Guest User

Untitled

a guest
Feb 11th, 2011
1,336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.46 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement