Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Windows.h>
- #include <stdio.h>
- #include <tchar.h>
- #define NPC_MAX_RETRIES 3
- #define NPC_WAIT_TIMEOUT_IN_MS 10000
- #define NPC_TRANSFER_BUFFER_SIZE 8192
- #define NPC_WAIT_DATA_TIMEOUT 1000
- #define NPC_READ_END 0
- #define NPC_WRITE_END 1
- //
- // Structures
- //
- typedef struct _NPC_CONNECTION
- {
- HANDLE Peer1;
- HANDLE Peer2;
- } NPC_CONNECTION, *PNPC_CONNECTION;
- typedef enum _NPC_TRANSFER_STATE
- {
- IoPending,
- Idle
- } NPC_TRANSFER_STATE, *PNPC_TRANSFER_STATE;
- typedef struct _NPC_ENDPOINT
- {
- OVERLAPPED Overlap;
- UCHAR TransferBuffer[4048];
- NPC_TRANSFER_STATE State;
- HANDLE Pipe;
- } NPC_ENDPOINT, *PNPC_ENDPOINT;
- //
- // Macros
- //
- #define NpcCreateConnection(Connection, From, To) \
- (Connection)->Peer1 = (From); \
- (Connection)->Peer2 = (To);
- #define NpcPrintError(Message, Code) \
- PrintError((Message), (Code), TEXT(__FILE__), __LINE__);
- HANDLE Server1, Server2;
- HANDLE Mutex;
- VOID PrintError(TCHAR *Message, DWORD ErrorCode, TCHAR* File, DWORD Line)
- {
- LPVOID lpMessageBuffer;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- ErrorCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMessageBuffer,
- 0,
- NULL );
- _tprintf(TEXT("[ERROR] %ws:%d: %ws: %ws"), File, Line, Message, lpMessageBuffer);
- LocalFree( lpMessageBuffer );
- }
- HANDLE NpcOpenPipe(TCHAR *PipeName)
- {
- HANDLE Pipe;
- do
- {
- int ConnectionRetries = 0;
- BOOL WaitSuccessful = FALSE;
- Pipe = CreateFile(
- PipeName,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- NULL);
- if (Pipe != INVALID_HANDLE_VALUE)
- {
- return Pipe;
- }
- if (GetLastError() != ERROR_PIPE_BUSY)
- {
- NpcPrintError(TEXT("CreateFile"), GetLastError());
- return Pipe;
- }
- // All pipe instances are busy, so wait some time ...
- for(ConnectionRetries = 0; ConnectionRetries < NPC_MAX_RETRIES; ConnectionRetries++)
- {
- WaitSuccessful = WaitNamedPipe(PipeName, NPC_WAIT_TIMEOUT_IN_MS);
- if (WaitSuccessful)
- {
- break;
- }
- }
- if (!WaitSuccessful)
- {
- NpcPrintError(TEXT("WaitNamedPipe"), GetLastError());
- break;
- }
- } while (TRUE);
- return INVALID_HANDLE_VALUE;
- }
- BOOL NpcInitializeIoEvents(__ecount(EventCount) PHANDLE Events, DWORD EventCount)
- {
- DWORD i;
- for (i = 0; i < EventCount; i++)
- {
- Events[i] = CreateEvent(
- NULL,
- TRUE,
- FALSE,
- NULL);
- if (Events[i] == INVALID_HANDLE_VALUE)
- {
- NpcPrintError(TEXT("CreateEvent"), GetLastError());
- return FALSE;
- }
- }
- return TRUE;
- }
- DWORD WINAPI NpcTransferThread(LPVOID Param)
- {
- PNPC_CONNECTION Connection = (PNPC_CONNECTION) Param;
- UCHAR TransferBuffer[NPC_TRANSFER_BUFFER_SIZE];
- DWORD BytesRead = 0, BytesWritten;
- BOOL OperationSuccess = FALSE;
- PUCHAR NextByte = TransferBuffer;
- HANDLE IoEvents[2];
- DWORD ThreadId = GetCurrentThreadId();
- char * WaitPeer1 = "";
- DWORD BulkRead;
- PUCHAR ReadOffset;
- OVERLAPPED Peer1Overlap, Peer2Overlap;
- ZeroMemory(TransferBuffer, sizeof(TransferBuffer));
- ZeroMemory(&Peer1Overlap, sizeof(OVERLAPPED));
- ZeroMemory(&Peer2Overlap, sizeof(OVERLAPPED));
- if (!NpcInitializeIoEvents(IoEvents, 2))
- {
- NpcPrintError(TEXT("NpcInitializeIoEvents"), GetLastError());
- return -1;
- }
- Peer1Overlap.hEvent = IoEvents[NPC_READ_END];
- Peer2Overlap.hEvent = IoEvents[NPC_WRITE_END];
- while (1)
- {
- // Read data from Peer 1
- ReadOffset = TransferBuffer;
- BulkRead = 0;
- OperationSuccess = ReadFile(
- Connection->Peer1,
- TransferBuffer,
- sizeof(TransferBuffer),
- &BytesRead,
- &Peer1Overlap);
- //
- // Ignore if there is more data to read since we will continue reading
- // data at the next iteration of the loop.
- //
- if (!OperationSuccess)
- {
- if (GetLastError() == ERROR_IO_PENDING)
- {
- //
- // Now update how many data we read
- //
- if (!GetOverlappedResult(
- Connection->Peer1,
- &Peer1Overlap,
- &BytesRead,
- TRUE))
- {
- NpcPrintError(TEXT("GetOverlappedResult"), GetLastError());
- return GetLastError();
- }
- }
- else
- {
- NpcPrintError(TEXT("ReadFile"), GetLastError());
- return -1;
- }
- }
- //
- // Send data to peer 2, as long as we have data in the buffer ...
- //
- NextByte = TransferBuffer;
- TransferBuffer[BytesRead] = 0;
- while (BytesRead)
- {
- OperationSuccess = WriteFile(
- Connection->Peer2,
- NextByte,
- BytesRead,
- &BytesWritten,
- &Peer2Overlap);
- if (!OperationSuccess)
- {
- if (GetLastError() == ERROR_IO_PENDING)
- {
- if (!GetOverlappedResult(Connection->Peer2, &Peer2Overlap, &BytesWritten, TRUE))
- {
- NpcPrintError(TEXT("GetOverlappedResult"), GetLastError());
- return GetLastError();
- }
- }
- else
- {
- NpcPrintError(TEXT("WriteFile"),GetLastError());
- return -1;
- }
- }
- BytesRead -= BytesWritten;
- NextByte += BytesWritten;
- }
- }
- return 0;
- }
- HANDLE NpcConnect(PNPC_CONNECTION Connection)
- {
- return CreateThread(
- NULL,
- 0,
- NpcTransferThread,
- Connection,
- 0,
- NULL);
- }
- int _tmain(int argc, TCHAR *argv[])
- {
- NPC_CONNECTION Peer1_to_Peer2;
- NPC_CONNECTION Peer2_to_Peer1;
- HANDLE WaitableResources[4];
- PHANDLE Connections = WaitableResources;
- PHANDLE Servers = &WaitableResources[2];
- if (argc != 3)
- {
- printf("Usage: %ws <pipe1> <pipe2>\n", argv[0]);
- return -1;
- }
- _tprintf(TEXT("Connecting '%s' <-> '%s' ...\n"), argv[1], argv[2]);
- Servers[0] = NpcOpenPipe(argv[1]);
- if (Server1 == INVALID_HANDLE_VALUE)
- {
- NpcPrintError(TEXT("NpcOpenPipe 1"), GetLastError());
- return -1;
- }
- Servers[1] = NpcOpenPipe(argv[2]);
- if (Server2 == INVALID_HANDLE_VALUE)
- {
- NpcPrintError(TEXT("NpcOpenPipe 2"), GetLastError());
- return -1;
- }
- NpcCreateConnection(&Peer1_to_Peer2, Servers[0], Servers[1]);
- NpcCreateConnection(&Peer2_to_Peer1, Servers[1], Servers[0]);
- Mutex = CreateMutex(
- NULL,
- FALSE,
- NULL);
- if (Mutex == INVALID_HANDLE_VALUE)
- {
- NpcPrintError(TEXT("CreateMutex"), GetLastError());
- return -1;
- }
- Connections[0] = NpcConnect(&Peer1_to_Peer2);
- if (Connections[0] == INVALID_HANDLE_VALUE)
- {
- NpcPrintError(TEXT("NpcConnect"), GetLastError());
- return -1;
- }
- Connections[1] = NpcConnect(&Peer2_to_Peer1);
- if (Connections[1] == INVALID_HANDLE_VALUE)
- {
- NpcPrintError(TEXT("NpcConnect"), GetLastError());
- return -1;
- }
- _tprintf(TEXT("Connection established.\n"));
- WaitForMultipleObjects(
- 4,
- WaitableResources,
- TRUE,
- INFINITE);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement