Blame winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c

Packit Service fa4841
Packit Service fa4841
#include <stdio.h>
Packit Service fa4841
#include <winpr/crt.h>
Packit Service fa4841
#include <winpr/pipe.h>
Packit Service fa4841
#include <winpr/file.h>
Packit Service fa4841
#include <winpr/tchar.h>
Packit Service fa4841
#include <winpr/winpr.h>
Packit Service fa4841
#include <winpr/print.h>
Packit Service fa4841
#include <winpr/synch.h>
Packit Service fa4841
#include <winpr/wlog.h>
Packit Service fa4841
#include <winpr/thread.h>
Packit Service fa4841
#ifndef _WIN32
Packit Service fa4841
#include <signal.h>
Packit Service fa4841
#endif
Packit Service fa4841
#include "../pipe.h"
Packit Service fa4841
Packit Service bb5c11
#define PIPE_BUFFER_SIZE	32
Packit Service fa4841
Packit Service fa4841
static HANDLE ReadyEvent;
Packit Service fa4841
Packit Service fa4841
static LPTSTR lpszPipeNameMt = _T("\\\\.\\pipe\\winpr_test_pipe_mt");
Packit Service fa4841
static LPTSTR lpszPipeNameSt = _T("\\\\.\\pipe\\winpr_test_pipe_st");
Packit Service fa4841
Packit Service fa4841
static BOOL testFailed = FALSE;
Packit Service fa4841
Packit Service fa4841
static DWORD WINAPI named_pipe_client_thread(LPVOID arg)
Packit Service fa4841
{
Packit Service fa4841
	HANDLE hNamedPipe = NULL;
Packit Service fa4841
	BYTE* lpReadBuffer = NULL;
Packit Service fa4841
	BYTE* lpWriteBuffer = NULL;
Packit Service fa4841
	BOOL fSuccess = FALSE;
Packit Service fa4841
	DWORD nNumberOfBytesToRead;
Packit Service fa4841
	DWORD nNumberOfBytesToWrite;
Packit Service fa4841
	DWORD lpNumberOfBytesRead;
Packit Service fa4841
	DWORD lpNumberOfBytesWritten;
Packit Service fa4841
	WaitForSingleObject(ReadyEvent, INFINITE);
Packit Service bb5c11
	hNamedPipe = CreateFile(lpszPipeNameMt, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
Packit Service fa4841
Packit Service fa4841
	if (hNamedPipe == INVALID_HANDLE_VALUE)
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Named Pipe CreateFile failure: INVALID_HANDLE_VALUE\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service bb5c11
	if (!(lpReadBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE)))
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Error allocating read buffer\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service bb5c11
	if (!(lpWriteBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE)))
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Error allocating write buffer\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	lpNumberOfBytesWritten = 0;
Packit Service fa4841
	nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
Packit Service fa4841
	FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x59);
Packit Service fa4841
Packit Service bb5c11
	if (!WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, NULL) ||
Packit Service bb5c11
			lpNumberOfBytesWritten != nNumberOfBytesToWrite)
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Client NamedPipe WriteFile failure\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	lpNumberOfBytesRead = 0;
Packit Service fa4841
	nNumberOfBytesToRead = PIPE_BUFFER_SIZE;
Packit Service fa4841
	ZeroMemory(lpReadBuffer, PIPE_BUFFER_SIZE);
Packit Service fa4841
Packit Service fa4841
	if (!ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead, NULL) ||
Packit Service bb5c11
			lpNumberOfBytesRead != nNumberOfBytesToRead)
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Client NamedPipe ReadFile failure\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service bb5c11
	printf("Client ReadFile: %"PRIu32" bytes\n", lpNumberOfBytesRead);
Packit Service fa4841
	winpr_HexDump("pipe.test", WLOG_DEBUG, lpReadBuffer, lpNumberOfBytesRead);
Packit Service fa4841
	fSuccess = TRUE;
Packit Service fa4841
out:
Packit Service fa4841
	free(lpReadBuffer);
Packit Service fa4841
	free(lpWriteBuffer);
Packit Service fa4841
	CloseHandle(hNamedPipe);
Packit Service fa4841
Packit Service fa4841
	if (!fSuccess)
Packit Service fa4841
		testFailed = TRUE;
Packit Service fa4841
Packit Service fa4841
	ExitThread(0);
Packit Service fa4841
	return 0;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static DWORD WINAPI named_pipe_server_thread(LPVOID arg)
Packit Service fa4841
{
Packit Service fa4841
	HANDLE hNamedPipe = NULL;
Packit Service fa4841
	BYTE* lpReadBuffer = NULL;
Packit Service fa4841
	BYTE* lpWriteBuffer = NULL;
Packit Service fa4841
	BOOL fSuccess = FALSE;
Packit Service fa4841
	BOOL fConnected = FALSE;
Packit Service fa4841
	DWORD nNumberOfBytesToRead;
Packit Service fa4841
	DWORD nNumberOfBytesToWrite;
Packit Service fa4841
	DWORD lpNumberOfBytesRead;
Packit Service fa4841
	DWORD lpNumberOfBytesWritten;
Packit Service bb5c11
	hNamedPipe = CreateNamedPipe(lpszPipeNameMt,
Packit Service bb5c11
								 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
Packit Service bb5c11
								 PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL);
Packit Service fa4841
Packit Service fa4841
	if (!hNamedPipe)
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: CreateNamedPipe failure: NULL handle\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (hNamedPipe == INVALID_HANDLE_VALUE)
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: CreateNamedPipe failure: INVALID_HANDLE_VALUE\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	SetEvent(ReadyEvent);
Packit Service fa4841
Packit Service fa4841
	/**
Packit Service fa4841
	 * Note:
Packit Service fa4841
	 * If a client connects before ConnectNamedPipe is called, the function returns zero and
Packit Service fa4841
	 * GetLastError returns ERROR_PIPE_CONNECTED. This can happen if a client connects in the
Packit Service fa4841
	 * interval between the call to CreateNamedPipe and the call to ConnectNamedPipe.
Packit Service fa4841
	 * In this situation, there is a good connection between client and server, even though
Packit Service fa4841
	 * the function returns zero.
Packit Service fa4841
	 */
Packit Service bb5c11
	fConnected = ConnectNamedPipe(hNamedPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
Packit Service fa4841
Packit Service fa4841
	if (!fConnected)
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: ConnectNamedPipe failure\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service bb5c11
	if (!(lpReadBuffer = (BYTE*) calloc(1, PIPE_BUFFER_SIZE)))
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Error allocating read buffer\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service bb5c11
	if (!(lpWriteBuffer = (BYTE*) malloc(PIPE_BUFFER_SIZE)))
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Error allocating write buffer\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	lpNumberOfBytesRead = 0;
Packit Service fa4841
	nNumberOfBytesToRead = PIPE_BUFFER_SIZE;
Packit Service fa4841
Packit Service fa4841
	if (!ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead, NULL) ||
Packit Service bb5c11
			lpNumberOfBytesRead != nNumberOfBytesToRead)
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Server NamedPipe ReadFile failure\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service bb5c11
	printf("Server ReadFile: %"PRIu32" bytes\n", lpNumberOfBytesRead);
Packit Service fa4841
	winpr_HexDump("pipe.test", WLOG_DEBUG, lpReadBuffer, lpNumberOfBytesRead);
Packit Service fa4841
	lpNumberOfBytesWritten = 0;
Packit Service fa4841
	nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
Packit Service fa4841
	FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x45);
Packit Service fa4841
Packit Service bb5c11
	if (!WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, NULL) ||
Packit Service bb5c11
			lpNumberOfBytesWritten != nNumberOfBytesToWrite)
Packit Service fa4841
	{
Packit Service fa4841
		printf("%s: Server NamedPipe WriteFile failure\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	fSuccess = TRUE;
Packit Service fa4841
out:
Packit Service fa4841
	free(lpReadBuffer);
Packit Service fa4841
	free(lpWriteBuffer);
Packit Service fa4841
	CloseHandle(hNamedPipe);
Packit Service fa4841
Packit Service fa4841
	if (!fSuccess)
Packit Service fa4841
		testFailed = TRUE;
Packit Service fa4841
Packit Service fa4841
	ExitThread(0);
Packit Service fa4841
	return 0;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
#define TESTNUMPIPESST 16
Packit Service fa4841
static DWORD WINAPI named_pipe_single_thread(LPVOID arg)
Packit Service fa4841
{
Packit Service fa4841
	HANDLE servers[TESTNUMPIPESST];
Packit Service fa4841
	HANDLE clients[TESTNUMPIPESST];
Packit Service fa4841
	char sndbuf[PIPE_BUFFER_SIZE];
Packit Service fa4841
	char rcvbuf[PIPE_BUFFER_SIZE];
Packit Service fa4841
	DWORD dwRead;
Packit Service fa4841
	DWORD dwWritten;
Packit Service fa4841
	int i;
Packit Service fa4841
	int numPipes;
Packit Service fa4841
	BOOL bSuccess = FALSE;
Packit Service fa4841
	numPipes = TESTNUMPIPESST;
Packit Service fa4841
	memset(servers, 0, sizeof(servers));
Packit Service fa4841
	memset(clients, 0, sizeof(clients));
Packit Service fa4841
	WaitForSingleObject(ReadyEvent, INFINITE);
Packit Service fa4841
Packit Service fa4841
	for (i = 0; i < numPipes; i++)
Packit Service fa4841
	{
Packit Service bb5c11
		if (!(servers[i] = CreateNamedPipe(lpszPipeNameSt,
Packit Service bb5c11
										   PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
Packit Service bb5c11
										   PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0, NULL)))
Packit Service fa4841
		{
Packit Service fa4841
			printf("%s: CreateNamedPipe #%d failed\n", __FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
#ifndef _WIN32
Packit Service fa4841
Packit Service fa4841
	for (i = 0; i < numPipes; i++)
Packit Service fa4841
	{
Packit Service fa4841
		WINPR_NAMED_PIPE* p = (WINPR_NAMED_PIPE*)servers[i];
Packit Service fa4841
Packit Service fa4841
		if (strcmp(lpszPipeNameSt, p->name))
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Pipe name mismatch for pipe #%d ([%s] instead of [%s])\n",
Packit Service bb5c11
				   __FUNCTION__, i, p->name, lpszPipeNameSt);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (p->clientfd != -1)
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Unexpected client fd value for pipe #%d (%d instead of -1)\n",
Packit Service bb5c11
				   __FUNCTION__, i, p->clientfd);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (p->serverfd < 1)
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Unexpected server fd value for pipe #%d (%d is not > 0)\n",
Packit Service bb5c11
				   __FUNCTION__, i, p->serverfd);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (p->ServerMode == FALSE)
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Unexpected ServerMode value for pipe #%d (0 instead of 1)\n",
Packit Service bb5c11
				   __FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
	for (i = 0; i < numPipes; i++)
Packit Service fa4841
	{
Packit Service fa4841
		BOOL fConnected;
Packit Service bb5c11
		if ((clients[i] = CreateFile(lpszPipeNameSt, GENERIC_READ | GENERIC_WRITE,
Packit Service bb5c11
									  0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
Packit Service fa4841
		{
Packit Service fa4841
			printf("%s: CreateFile #%d failed\n", __FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		/**
Packit Service fa4841
		 * Note:
Packit Service fa4841
		 * If a client connects before ConnectNamedPipe is called, the function returns zero and
Packit Service fa4841
		 * GetLastError returns ERROR_PIPE_CONNECTED. This can happen if a client connects in the
Packit Service fa4841
		 * interval between the call to CreateNamedPipe and the call to ConnectNamedPipe.
Packit Service fa4841
		 * In this situation, there is a good connection between client and server, even though
Packit Service fa4841
		 * the function returns zero.
Packit Service fa4841
		 */
Packit Service bb5c11
		fConnected = ConnectNamedPipe(servers[i], NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
Packit Service fa4841
Packit Service fa4841
		if (!fConnected)
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: ConnectNamedPipe #%d failed. (%"PRIu32")\n", __FUNCTION__, i, GetLastError());
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
#ifndef _WIN32
Packit Service fa4841
Packit Service fa4841
	for (i = 0; i < numPipes; i++)
Packit Service fa4841
	{
Packit Service fa4841
		WINPR_NAMED_PIPE* p = servers[i];
Packit Service fa4841
Packit Service fa4841
		if (p->clientfd < 1)
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Unexpected client fd value for pipe #%d (%d is not > 0)\n",
Packit Service bb5c11
				   __FUNCTION__, i, p->clientfd);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (p->ServerMode)
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Unexpected ServerMode value for pipe #%d (1 instead of 0)\n",
Packit Service bb5c11
				   __FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	for (i = 0; i < numPipes; i++)
Packit Service fa4841
	{
Packit Service fa4841
		/* Test writing from clients to servers */
Packit Service fa4841
		ZeroMemory(sndbuf, sizeof(sndbuf));
Packit Service fa4841
		ZeroMemory(rcvbuf, sizeof(rcvbuf));
Packit Service fa4841
		sprintf_s(sndbuf, sizeof(sndbuf), "CLIENT->SERVER ON PIPE #%05d", i);
Packit Service fa4841
Packit Service fa4841
		if (!WriteFile(clients[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL) ||
Packit Service bb5c11
				dwWritten != sizeof(sndbuf))
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Error writing to client end of pipe #%d\n",	__FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service bb5c11
		if (!ReadFile(servers[i], rcvbuf, dwWritten, &dwRead, NULL) ||
Packit Service bb5c11
				dwRead != dwWritten)
Packit Service fa4841
		{
Packit Service fa4841
			printf("%s: Error reading on server end of pipe #%d\n", __FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (memcmp(sndbuf, rcvbuf, sizeof(sndbuf)))
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Error data read on server end of pipe #%d is corrupted\n",
Packit Service bb5c11
				   __FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		/* Test writing from servers to clients */
Packit Service fa4841
		ZeroMemory(sndbuf, sizeof(sndbuf));
Packit Service fa4841
		ZeroMemory(rcvbuf, sizeof(rcvbuf));
Packit Service fa4841
		sprintf_s(sndbuf, sizeof(sndbuf), "SERVER->CLIENT ON PIPE #%05d", i);
Packit Service fa4841
Packit Service fa4841
		if (!WriteFile(servers[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL) ||
Packit Service bb5c11
				dwWritten != sizeof(sndbuf))
Packit Service fa4841
		{
Packit Service fa4841
			printf("%s: Error writing to server end of pipe #%d\n", __FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service bb5c11
		if (!ReadFile(clients[i], rcvbuf, dwWritten, &dwRead, NULL) ||
Packit Service bb5c11
				dwRead != dwWritten)
Packit Service fa4841
		{
Packit Service fa4841
			printf("%s: Error reading on client end of pipe #%d\n", __FUNCTION__, i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (memcmp(sndbuf, rcvbuf, sizeof(sndbuf)))
Packit Service fa4841
		{
Packit Service bb5c11
			printf("%s: Error data read on client end of pipe #%d is corrupted\n",
Packit Service bb5c11
				   __FUNCTION__,  i);
Packit Service fa4841
			goto out;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
#endif
Packit Service fa4841
	/**
Packit Service fa4841
	 * After DisconnectNamedPipe on server end
Packit Service fa4841
	 * ReadFile/WriteFile must fail on client end
Packit Service fa4841
	 */
Packit Service fa4841
	i = numPipes - 1;
Packit Service fa4841
	DisconnectNamedPipe(servers[i]);
Packit Service fa4841
Packit Service fa4841
	if (ReadFile(clients[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("%s: Error ReadFile on client should have failed after DisconnectNamedPipe on server\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (WriteFile(clients[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("%s: Error WriteFile on client end should have failed after DisconnectNamedPipe on server\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	CloseHandle(servers[i]);
Packit Service fa4841
	CloseHandle(clients[i]);
Packit Service fa4841
	numPipes--;
Packit Service fa4841
	/**
Packit Service fa4841
	 * After CloseHandle (without calling DisconnectNamedPipe first) on server end
Packit Service fa4841
	 * ReadFile/WriteFile must fail on client end
Packit Service fa4841
	 */
Packit Service fa4841
	i = numPipes - 1;
Packit Service fa4841
	CloseHandle(servers[i]);
Packit Service fa4841
Packit Service fa4841
	if (ReadFile(clients[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("%s: Error ReadFile on client end should have failed after CloseHandle on server\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (WriteFile(clients[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("%s: Error WriteFile on client end should have failed after CloseHandle on server\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	CloseHandle(clients[i]);
Packit Service fa4841
	numPipes--;
Packit Service fa4841
	/**
Packit Service fa4841
	 * After CloseHandle on client end
Packit Service fa4841
	 * ReadFile/WriteFile must fail on server end
Packit Service fa4841
	 */
Packit Service fa4841
	i = numPipes - 1;
Packit Service fa4841
	CloseHandle(clients[i]);
Packit Service fa4841
Packit Service fa4841
	if (ReadFile(servers[i], rcvbuf, sizeof(rcvbuf), &dwRead, NULL))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("%s: Error ReadFile on server end should have failed after CloseHandle on client\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (WriteFile(servers[i], sndbuf, sizeof(sndbuf), &dwWritten, NULL))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("%s: Error WriteFile on server end should have failed after CloseHandle on client\n", __FUNCTION__);
Packit Service fa4841
		goto out;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	DisconnectNamedPipe(servers[i]);
Packit Service fa4841
	CloseHandle(servers[i]);
Packit Service fa4841
	numPipes--;
Packit Service fa4841
Packit Service fa4841
	/* Close all remaining pipes */
Packit Service fa4841
	for (i = 0; i < numPipes; i++)
Packit Service fa4841
	{
Packit Service fa4841
		DisconnectNamedPipe(servers[i]);
Packit Service fa4841
		CloseHandle(servers[i]);
Packit Service fa4841
		CloseHandle(clients[i]);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	bSuccess = TRUE;
Packit Service fa4841
out:
Packit Service fa4841
Packit Service fa4841
	if (!bSuccess)
Packit Service fa4841
		testFailed = TRUE;
Packit Service fa4841
Packit Service fa4841
	return 0;
Packit Service fa4841
}
Packit Service fa4841
Packit Service bb5c11
Packit Service fa4841
int TestPipeCreateNamedPipe(int argc, char* argv[])
Packit Service fa4841
{
Packit Service fa4841
	HANDLE SingleThread;
Packit Service fa4841
	HANDLE ClientThread;
Packit Service fa4841
	HANDLE ServerThread;
Packit Service fa4841
	HANDLE hPipe;
Packit Service fa4841
Packit Service fa4841
	/* Verify that CreateNamedPipe returns INVALID_HANDLE_VALUE on failure */
Packit Service fa4841
	hPipe = CreateNamedPipeA(NULL, 0, 0, 0, 0, 0, 0, NULL);
Packit Service fa4841
	if (hPipe != INVALID_HANDLE_VALUE)
Packit Service fa4841
	{
Packit Service fa4841
		printf("CreateNamedPipe unexpectedly returned %p instead of INVALID_HANDLE_VALUE (%p)\n",
Packit Service bb5c11
			hPipe, INVALID_HANDLE_VALUE);
Packit Service fa4841
		return -1;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
#ifndef _WIN32
Packit Service fa4841
	signal(SIGPIPE, SIG_IGN);
Packit Service fa4841
#endif
Packit Service fa4841
	if (!(ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("CreateEvent failure: (%"PRIu32")\n", GetLastError());
Packit Service fa4841
		return -1;
Packit Service fa4841
	}
Packit Service fa4841
	if (!(SingleThread = CreateThread(NULL, 0, named_pipe_single_thread, NULL, 0, NULL)))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("CreateThread (SingleThread) failure: (%"PRIu32")\n", GetLastError());
Packit Service fa4841
		return -1;
Packit Service fa4841
	}
Packit Service fa4841
	if (!(ClientThread = CreateThread(NULL, 0, named_pipe_client_thread, NULL, 0, NULL)))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("CreateThread (ClientThread) failure: (%"PRIu32")\n", GetLastError());
Packit Service fa4841
		return -1;
Packit Service fa4841
	}
Packit Service fa4841
	if (!(ServerThread = CreateThread(NULL, 0, named_pipe_server_thread, NULL, 0, NULL)))
Packit Service fa4841
	{
Packit Service bb5c11
		printf("CreateThread (ServerThread) failure: (%"PRIu32")\n", GetLastError());
Packit Service fa4841
		return -1;
Packit Service fa4841
	}
Packit Service fa4841
	WaitForSingleObject(SingleThread, INFINITE);
Packit Service fa4841
	WaitForSingleObject(ClientThread, INFINITE);
Packit Service fa4841
	WaitForSingleObject(ServerThread, INFINITE);
Packit Service fa4841
	CloseHandle(SingleThread);
Packit Service fa4841
	CloseHandle(ClientThread);
Packit Service fa4841
	CloseHandle(ServerThread);
Packit Service fa4841
	return testFailed;
Packit Service fa4841
}