#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define NUM_PIPES 5
#define BUFFER_SIZE 256


void main(void)
{
	HANDLE PipeHandles[NUM_PIPES];
	DWORD BytesTransferred;
	CHAR Buffer[NUM_PIPES][BUFFER_SIZE];
	INT i;
	OVERLAPPED Ovlap[NUM_PIPES];
	HANDLE Event[NUM_PIPES];

	BOOL DataRead[NUM_PIPES];
	DWORD Ret;
	DWORD Pipe;

	for(i = 0; i < NUM_PIPES; i++)
	{
		if ((PipeHandles[i] = CreateNamedPipe("\\\\.\\Pipe\\Wohlhabend3215",
			PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
			PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, NUM_PIPES,
			0, 0, 1000, NULL)) == INVALID_HANDLE_VALUE)
		{
			printf("CreateNamedPipe for pipe %d failed "
				"with error %d\n", i, GetLastError());
			_getch();
			return;
		}

		if ((Event[i] = CreateEvent(NULL, TRUE, FALSE, NULL)) 
			== NULL)
		{
			printf("CreateEvent for pipe %d failed with error %d\n",
				i, GetLastError());
			continue;
		}
		DataRead[i] = FALSE;

		ZeroMemory(&Ovlap[i], sizeof(OVERLAPPED));
		Ovlap[i].hEvent = Event[i];
		// Listen for client connections using ConnectNamedPipe()
		if (ConnectNamedPipe(PipeHandles[i], &Ovlap[i]) == 0)
		{
			if (GetLastError() != ERROR_IO_PENDING)
			{
				printf("ConnectNamedPipe for pipe %d failed with",
				    " error %d\n", i, GetLastError());
				CloseHandle(PipeHandles[i]);
				_getch();
				return;
			}
		}
	}

	printf("Server is now running\n");


	while(1) 
	{
		if ((Ret = WaitForMultipleObjects(NUM_PIPES, Event, 
			FALSE, INFINITE)) == WAIT_FAILED)
		{
			printf("WaitForMultipleObjects failed with error %d\n",
				GetLastError());
			_getch();
			return;
		}
		Pipe = Ret - WAIT_OBJECT_0;
		ResetEvent(Event[Pipe]);
		if (GetOverlappedResult(PipeHandles[Pipe], &Ovlap[Pipe],
			&BytesTransferred, TRUE) == 0)
		{
			printf("GetOverlapped result failed %d start over\n", 
				GetLastError());
			if (DisconnectNamedPipe(PipeHandles[Pipe]) == 0)
			{
				printf("DisconnectNamedPipe failed with error %d\n",
					GetLastError());
				_getch();
				return;
			}
			if (ConnectNamedPipe(PipeHandles[Pipe],
				&Ovlap[Pipe]) == 0)
			{
				if (GetLastError() != ERROR_IO_PENDING)
				{
					// Severe error on pipe. Close this
					// handle forever.
		printf("ConnectNamedPipe for pipe %d failed with""error %d\n", i, GetLastError());
					CloseHandle(PipeHandles[Pipe]);
				}
			}
			DataRead[Pipe] = FALSE;
		} 
		else
		{
			if (DataRead[Pipe] == FALSE)
			{
				ZeroMemory(&Ovlap[Pipe], sizeof(OVERLAPPED));
				Ovlap[Pipe].hEvent = Event[Pipe];
				if (ReadFile(PipeHandles[Pipe], Buffer[Pipe],
					BUFFER_SIZE, NULL, &Ovlap[Pipe]) == 0)
				{
					if (GetLastError() != ERROR_IO_PENDING)
					{
						printf("ReadFile failed with error %d\n",
						GetLastError());
					}
				}
Buffer[Pipe][BytesTransferred]='\0';
printf("%s\n",Buffer[Pipe]);
				DataRead[Pipe] = TRUE;
			}
			else
			{
				
				printf("Received %d bytes, echo bytes back\n",
					BytesTransferred);
			//	_getch();
		//		DataRead[Pipe] = TRUE;
				ZeroMemory(&Ovlap[Pipe], sizeof(OVERLAPPED));
				Ovlap[Pipe].hEvent = Event[Pipe];
				if (WriteFile(PipeHandles[Pipe], "Stop",
				BUFFER_SIZE, NULL, &Ovlap[Pipe]) == 0)
				{
					if (GetLastError() != ERROR_IO_PENDING)
					{
						printf("WriteFile failed with error %d\n",
						GetLastError());
					}
				}
				DataRead[Pipe] = FALSE;
			}
		}
	}		
}
