#include <windows.h> 
#include <stdio.h>
// Generic-Text Mappings which are Microsoft extensions
// that are not ANSI compatible. However those related
// string/text functions can be 'ported'/migrated easily
// to ANSI
// http://msdn.microsoft.com/en-us/library/c426s321.aspx
#include <tchar.h>

#define BUFSIZE 512
 
int _tmain(int argc, TCHAR *argv[]) 
{
	HANDLE hPipe;
	LPTSTR lpvMessage=TEXT(" \"Default message from client\"");
	TCHAR chBuf[BUFSIZE];
	BOOL fSuccess;
	DWORD cbRead, cbWritten, dwMode;
	LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\pipebodo");
	
	if(argc > 1)
		lpvMessage = argv[1];
	else
	{
		printf("Usage: %S <message to send>\n", argv[0]);
		printf("Example: %S \"Some test message\"\n", argv[0]);
	}
	
	// Try to open a named pipe; wait for it, if necessary
	while (1)
	{
		hPipe = CreateFile(
			lpszPipename,   // pipe name
			GENERIC_READ |  // read and write access
			GENERIC_WRITE,
			0,              // no sharing
			NULL,           // default security attributee
			OPEN_EXISTING,  // opens existing pipe
			0,              // default attributes
			NULL);          // no template file
		
		// Break if the pipe handle is valid
		if (hPipe != INVALID_HANDLE_VALUE)
			break;
		
		// Exit if an error other than ERROR_PIPE_BUSY occurs
		if (GetLastError() != ERROR_PIPE_BUSY)
		{
			printf("Could not open pipe!");
			return 0;
		}
		
		// All pipe instances are busy, so wait for 20 seconds
		if (!WaitNamedPipe(lpszPipename, 20000))
		{
			printf("Could not open pipe!");
			return 0;
		}
		printf("pipe was opened and connected successfully!\n");
	}
	
	// The pipe connected; change to message-read mode
	dwMode = PIPE_READMODE_MESSAGE;
	fSuccess = SetNamedPipeHandleState(
		hPipe,    // pipe handle
		&dwMode,  // new pipe mode
		NULL,     // don't set maximum bytes
		NULL);    // don't set maximum time
	if (!fSuccess)
	{
		printf("SetNamedPipeHandleState() failed with error code %d", GetLastError());
		return 0;
	}
	else
		printf("SetNamedPipeHandleState() is OK!\n");
	
	// Send a message to the pipe server
	fSuccess = WriteFile(
		hPipe,                  // pipe handle
		lpvMessage,             // message
		(lstrlen(lpvMessage)+1)*sizeof(TCHAR), // message length
		&cbWritten,             // bytes written
		NULL);                  // not overlapped
	if (!fSuccess)
	{
		printf("WriteFile() failed with error code %d\n", GetLastError());
		return 0;
	}
	else
		printf("WriteFile() is fine!\n");

	do
	{
		// Read from the pipe
		fSuccess = ReadFile(
			hPipe,    // pipe handle
			chBuf,    // buffer to receive reply
			BUFSIZE*sizeof(TCHAR),  // size of buffer
			&cbRead,  // number of bytes read
			NULL);    // not overlapped
		
		if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
			break;
		_tprintf( TEXT("%s\n"), chBuf );
	} while (!fSuccess);  // repeat loop if ERROR_MORE_DATA
	
	if(CloseHandle(hPipe) != 0)
		printf("hPipe handle closed successfully!\n");
	else
		printf("Failed to close hFile handle, error code %d\n", GetLastError());
	
	return 0;
}