6#include <winpr/tchar.h>
7#include <winpr/winpr.h>
8#include <winpr/print.h>
9#include <winpr/synch.h>
10#include <winpr/wlog.h>
11#include <winpr/thread.h>
17#define PIPE_BUFFER_SIZE 32
19static HANDLE ReadyEvent;
21static const char lpszPipeNameMt[] =
"\\\\.\\pipe\\winpr_test_pipe_mt";
22static const char lpszPipeNameSt[] =
"\\\\.\\pipe\\winpr_test_pipe_st";
24static BOOL testFailed = FALSE;
26static DWORD WINAPI named_pipe_client_thread(LPVOID arg)
28 HANDLE hNamedPipe =
nullptr;
29 BYTE* lpReadBuffer =
nullptr;
30 BYTE* lpWriteBuffer =
nullptr;
31 BOOL fSuccess = FALSE;
32 DWORD nNumberOfBytesToRead = 0;
33 DWORD nNumberOfBytesToWrite = 0;
34 DWORD lpNumberOfBytesRead = 0;
35 DWORD lpNumberOfBytesWritten = 0;
36 (void)WaitForSingleObject(ReadyEvent, INFINITE);
37 hNamedPipe = winpr_CreateFile(lpszPipeNameMt, GENERIC_READ | GENERIC_WRITE, 0,
nullptr,
38 OPEN_EXISTING, 0,
nullptr);
40 if (hNamedPipe == INVALID_HANDLE_VALUE)
42 printf(
"%s: Named Pipe CreateFile failure: INVALID_HANDLE_VALUE\n", __func__);
46 if (!(lpReadBuffer = (BYTE*)malloc(PIPE_BUFFER_SIZE)))
48 printf(
"%s: Error allocating read buffer\n", __func__);
52 if (!(lpWriteBuffer = (BYTE*)malloc(PIPE_BUFFER_SIZE)))
54 printf(
"%s: Error allocating write buffer\n", __func__);
58 lpNumberOfBytesWritten = 0;
59 nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
60 FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x59);
62 if (!WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten,
64 lpNumberOfBytesWritten != nNumberOfBytesToWrite)
66 printf(
"%s: Client NamedPipe WriteFile failure\n", __func__);
70 lpNumberOfBytesRead = 0;
71 nNumberOfBytesToRead = PIPE_BUFFER_SIZE;
72 ZeroMemory(lpReadBuffer, PIPE_BUFFER_SIZE);
74 if (!ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead,
nullptr) ||
75 lpNumberOfBytesRead != nNumberOfBytesToRead)
77 printf(
"%s: Client NamedPipe ReadFile failure\n", __func__);
81 printf(
"Client ReadFile: %" PRIu32
" bytes\n", lpNumberOfBytesRead);
82 winpr_HexDump(
"pipe.test", WLOG_DEBUG, lpReadBuffer, lpNumberOfBytesRead);
87 (void)CloseHandle(hNamedPipe);
96static DWORD WINAPI named_pipe_server_thread(LPVOID arg)
98 BYTE* lpReadBuffer =
nullptr;
99 BYTE* lpWriteBuffer =
nullptr;
100 BOOL fSuccess = FALSE;
101 BOOL fConnected = FALSE;
102 DWORD nNumberOfBytesToRead = 0;
103 DWORD nNumberOfBytesToWrite = 0;
104 DWORD lpNumberOfBytesRead = 0;
105 DWORD lpNumberOfBytesWritten = 0;
108 WCHAR* str = ConvertUtf8ToWCharAlloc(lpszPipeNameMt,
nullptr);
110 char* str = _strdup(lpszPipeNameMt);
114 CreateNamedPipe(str, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
115 PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0,
nullptr);
119 printf(
"%s: CreateNamedPipe failure: nullptr handle\n", __func__);
123 if (hNamedPipe == INVALID_HANDLE_VALUE)
125 printf(
"%s: CreateNamedPipe failure: INVALID_HANDLE_VALUE\n", __func__);
129 (void)SetEvent(ReadyEvent);
140 ConnectNamedPipe(hNamedPipe,
nullptr) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
144 printf(
"%s: ConnectNamedPipe failure\n", __func__);
148 if (!(lpReadBuffer = (BYTE*)calloc(1, PIPE_BUFFER_SIZE)))
150 printf(
"%s: Error allocating read buffer\n", __func__);
154 if (!(lpWriteBuffer = (BYTE*)malloc(PIPE_BUFFER_SIZE)))
156 printf(
"%s: Error allocating write buffer\n", __func__);
160 lpNumberOfBytesRead = 0;
161 nNumberOfBytesToRead = PIPE_BUFFER_SIZE;
163 if (!ReadFile(hNamedPipe, lpReadBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead,
nullptr) ||
164 lpNumberOfBytesRead != nNumberOfBytesToRead)
166 printf(
"%s: Server NamedPipe ReadFile failure\n", __func__);
170 printf(
"Server ReadFile: %" PRIu32
" bytes\n", lpNumberOfBytesRead);
171 winpr_HexDump(
"pipe.test", WLOG_DEBUG, lpReadBuffer, lpNumberOfBytesRead);
172 lpNumberOfBytesWritten = 0;
173 nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
174 FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x45);
176 if (!WriteFile(hNamedPipe, lpWriteBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten,
178 lpNumberOfBytesWritten != nNumberOfBytesToWrite)
180 printf(
"%s: Server NamedPipe WriteFile failure\n", __func__);
188 (void)CloseHandle(hNamedPipe);
197#define TESTNUMPIPESST 16
198static DWORD WINAPI named_pipe_single_thread(LPVOID arg)
200 HANDLE servers[TESTNUMPIPESST] = WINPR_C_ARRAY_INIT;
201 HANDLE clients[TESTNUMPIPESST] = WINPR_C_ARRAY_INIT;
205 BOOL bSuccess = FALSE;
206 numPipes = TESTNUMPIPESST;
207 (void)WaitForSingleObject(ReadyEvent, INFINITE);
209 for (
int i = 0; i < numPipes; i++)
212 WCHAR* str = ConvertUtf8ToWCharAlloc(lpszPipeNameSt,
nullptr);
214 char* str = _strdup(lpszPipeNameSt);
216 servers[i] = CreateNamedPipe(
217 str, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
218 PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, 0,
nullptr);
222 printf(
"%s: CreateNamedPipe #%d failed\n", __func__, i);
229 for (
int i = 0; i < numPipes; i++)
231 WINPR_NAMED_PIPE* p = (WINPR_NAMED_PIPE*)servers[i];
233 if (strcmp(lpszPipeNameSt, p->name) != 0)
235 printf(
"%s: Pipe name mismatch for pipe #%d ([%s] instead of [%s])\n", __func__, i,
236 p->name, lpszPipeNameSt);
240 if (p->clientfd != -1)
242 printf(
"%s: Unexpected client fd value for pipe #%d (%d instead of -1)\n", __func__, i,
249 printf(
"%s: Unexpected server fd value for pipe #%d (%d is not > 0)\n", __func__, i,
254 if (p->ServerMode == FALSE)
256 printf(
"%s: Unexpected ServerMode value for pipe #%d (0 instead of 1)\n", __func__, i);
263 for (
int i = 0; i < numPipes; i++)
266 if ((clients[i] = winpr_CreateFile(lpszPipeNameSt, GENERIC_READ | GENERIC_WRITE, 0,
nullptr,
267 OPEN_EXISTING, 0,
nullptr)) == INVALID_HANDLE_VALUE)
269 printf(
"%s: CreateFile #%d failed\n", __func__, i);
282 ConnectNamedPipe(servers[i],
nullptr) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
286 printf(
"%s: ConnectNamedPipe #%d failed. (%" PRIu32
")\n", __func__, i, GetLastError());
293 for (
int i = 0; i < numPipes; i++)
295 WINPR_NAMED_PIPE* p = servers[i];
299 printf(
"%s: Unexpected client fd value for pipe #%d (%d is not > 0)\n", __func__, i,
306 printf(
"%s: Unexpected ServerMode value for pipe #%d (1 instead of 0)\n", __func__, i);
311 for (
int i = 0; i < numPipes; i++)
314 char sndbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
315 char rcvbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
317 (void)sprintf_s(sndbuf,
sizeof(sndbuf),
"CLIENT->SERVER ON PIPE #%05d", i);
319 if (!WriteFile(clients[i], sndbuf,
sizeof(sndbuf), &dwWritten,
nullptr) ||
320 dwWritten !=
sizeof(sndbuf))
322 printf(
"%s: Error writing to client end of pipe #%d\n", __func__, i);
326 if (!ReadFile(servers[i], rcvbuf, dwWritten, &dwRead,
nullptr) || dwRead != dwWritten)
328 printf(
"%s: Error reading on server end of pipe #%d\n", __func__, i);
332 if (memcmp(sndbuf, rcvbuf,
sizeof(sndbuf)) != 0)
334 printf(
"%s: Error data read on server end of pipe #%d is corrupted\n", __func__, i);
340 char sndbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
341 char rcvbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
344 (void)sprintf_s(sndbuf,
sizeof(sndbuf),
"SERVER->CLIENT ON PIPE #%05d", i);
346 if (!WriteFile(servers[i], sndbuf,
sizeof(sndbuf), &dwWritten,
nullptr) ||
347 dwWritten !=
sizeof(sndbuf))
349 printf(
"%s: Error writing to server end of pipe #%d\n", __func__, i);
353 if (!ReadFile(clients[i], rcvbuf, dwWritten, &dwRead,
nullptr) || dwRead != dwWritten)
355 printf(
"%s: Error reading on client end of pipe #%d\n", __func__, i);
359 if (memcmp(sndbuf, rcvbuf,
sizeof(sndbuf)) != 0)
361 printf(
"%s: Error data read on client end of pipe #%d is corrupted\n", __func__, i);
372 int i = numPipes - 1;
373 if (!DisconnectNamedPipe(servers[i]))
376 char sndbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
377 char rcvbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
378 if (ReadFile(clients[i], rcvbuf,
sizeof(rcvbuf), &dwRead,
nullptr))
380 printf(
"%s: Error ReadFile on client should have failed after DisconnectNamedPipe on "
386 if (WriteFile(clients[i], sndbuf,
sizeof(sndbuf), &dwWritten,
nullptr))
389 "%s: Error WriteFile on client end should have failed after DisconnectNamedPipe on "
395 if (!CloseHandle(servers[i]))
397 if (!CloseHandle(clients[i]))
405 (void)CloseHandle(servers[i]);
408 char sndbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
409 char rcvbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
411 if (ReadFile(clients[i], rcvbuf,
sizeof(rcvbuf), &dwRead,
nullptr))
414 "%s: Error ReadFile on client end should have failed after CloseHandle on server\n",
419 if (WriteFile(clients[i], sndbuf,
sizeof(sndbuf), &dwWritten,
nullptr))
421 printf(
"%s: Error WriteFile on client end should have failed after CloseHandle on "
427 (void)CloseHandle(clients[i]);
434 (void)CloseHandle(clients[i]);
437 char sndbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
438 char rcvbuf[PIPE_BUFFER_SIZE] = WINPR_C_ARRAY_INIT;
440 if (ReadFile(servers[i], rcvbuf,
sizeof(rcvbuf), &dwRead,
nullptr))
443 "%s: Error ReadFile on server end should have failed after CloseHandle on client\n",
448 if (WriteFile(servers[i], sndbuf,
sizeof(sndbuf), &dwWritten,
nullptr))
450 printf(
"%s: Error WriteFile on server end should have failed after CloseHandle on "
457 if (!DisconnectNamedPipe(servers[i]))
459 if (!CloseHandle(servers[i]))
464 for (
int i = 0; i < numPipes; i++)
466 if (!DisconnectNamedPipe(servers[i]))
468 if (!CloseHandle(servers[i]))
470 if (!CloseHandle(clients[i]))
483int TestPipeCreateNamedPipe(
int argc,
char* argv[])
485 HANDLE SingleThread =
nullptr;
486 HANDLE ClientThread =
nullptr;
487 HANDLE ServerThread =
nullptr;
488 HANDLE hPipe =
nullptr;
492 hPipe = CreateNamedPipeA(
nullptr, 0, 0, 0, 0, 0, 0,
nullptr);
493 if (hPipe != INVALID_HANDLE_VALUE)
495 printf(
"CreateNamedPipe unexpectedly returned %p instead of INVALID_HANDLE_VALUE (%p)\n",
496 hPipe, INVALID_HANDLE_VALUE);
501 (void)signal(SIGPIPE, SIG_IGN);
503 if (!(ReadyEvent = CreateEvent(
nullptr, TRUE, FALSE,
nullptr)))
505 printf(
"CreateEvent failure: (%" PRIu32
")\n", GetLastError());
508 if (!(SingleThread = CreateThread(
nullptr, 0, named_pipe_single_thread,
nullptr, 0,
nullptr)))
510 printf(
"CreateThread (SingleThread) failure: (%" PRIu32
")\n", GetLastError());
513 if (!(ClientThread = CreateThread(
nullptr, 0, named_pipe_client_thread,
nullptr, 0,
nullptr)))
515 printf(
"CreateThread (ClientThread) failure: (%" PRIu32
")\n", GetLastError());
518 if (!(ServerThread = CreateThread(
nullptr, 0, named_pipe_server_thread,
nullptr, 0,
nullptr)))
520 printf(
"CreateThread (ServerThread) failure: (%" PRIu32
")\n", GetLastError());
523 (void)WaitForSingleObject(SingleThread, INFINITE);
524 (void)WaitForSingleObject(ClientThread, INFINITE);
525 (void)WaitForSingleObject(ServerThread, INFINITE);
526 (void)CloseHandle(SingleThread);
527 (void)CloseHandle(ClientThread);
528 (void)CloseHandle(ServerThread);