1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*=====================================================================
6**
7** Source: test5.c (DuplicateHandle)
8**
9** Purpose: Tests the PAL implementation of the DuplicateHandle function,
10** with CreatePipe. This test will create a pipe and write to it,
11** the duplicate the read handle and read what was written.
12**
13** Depends: WriteFile
14** ReadFile
15** memcmp
16** CloseHandle
17**
18**
19**===================================================================*/
20
21#include <palsuite.h>
22
23const char* cTestString = "one fish, two fish, red fish, blue fish.";
24
25int __cdecl main(int argc, char **argv)
26{
27 HANDLE hReadPipe = NULL;
28 HANDLE hWritePipe = NULL;
29 HANDLE hDupPipe = NULL;
30 BOOL bRetVal = FALSE;
31 DWORD dwBytesWritten;
32 DWORD dwBytesRead;
33 char buffer[256];
34
35 SECURITY_ATTRIBUTES lpPipeAttributes;
36
37 /*Initialize the PAL*/
38 if ((PAL_Initialize(argc, argv)) != 0)
39 {
40 return (FAIL);
41 }
42
43 /*Setup SECURITY_ATTRIBUTES structure for CreatePipe*/
44 lpPipeAttributes.nLength = sizeof(lpPipeAttributes);
45 lpPipeAttributes.lpSecurityDescriptor = NULL;
46 lpPipeAttributes.bInheritHandle = TRUE;
47
48 /*Create a Pipe*/
49 bRetVal = CreatePipe(&hReadPipe, /* read handle*/
50 &hWritePipe, /* write handle */
51 &lpPipeAttributes,/* security attributes*/
52 0); /* pipe size*/
53 if (bRetVal == FALSE)
54 {
55 Fail("ERROR:%u:Unable to create pipe\n", GetLastError());
56 }
57
58 /*Write to the write pipe handle*/
59 bRetVal = WriteFile(hWritePipe, /* handle to write pipe*/
60 cTestString, /* buffer to write*/
61 strlen(cTestString),/* number of bytes to write*/
62 &dwBytesWritten, /* number of bytes written*/
63 NULL); /* overlapped buffer*/
64 if (bRetVal == FALSE)
65 {
66 Trace("ERROR:%u:unable to write to write pipe handle "
67 "hWritePipe=0x%lx\n", GetLastError(), hWritePipe);
68 CloseHandle(hReadPipe);
69 CloseHandle(hWritePipe);
70 Fail("");
71 }
72
73 /*Duplicate the pipe handle*/
74 if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/
75 hReadPipe, /* handle to duplicate*/
76 GetCurrentProcess(), /* target process handle*/
77 &hDupPipe, /* duplicate handle*/
78 GENERIC_READ|GENERIC_WRITE,/* requested access*/
79 FALSE, /* handle inheritance*/
80 DUPLICATE_SAME_ACCESS))) /* optional actions*/
81 {
82 Trace("ERROR:%u:Fail to create the duplicate handle"
83 " to hReadPipe=0x%lx",
84 GetLastError(),
85 hReadPipe);
86 CloseHandle(hReadPipe);
87 CloseHandle(hWritePipe);
88 Fail("");
89 }
90
91 /*Read from the duplicated handle, 256 bytes, more bytes
92 than actually written. This will allow us to use the
93 value that ReadFile returns for comparision.*/
94 bRetVal = ReadFile(hDupPipe, /* handle to read pipe*/
95 buffer, /* buffer to write to*/
96 256, /* number of bytes to read*/
97 &dwBytesRead, /* number of bytes read*/
98 NULL); /* overlapped buffer*/
99 if (bRetVal == FALSE)
100 {
101 Trace("ERROR:%u:unable read from the duplicated pipe "
102 "hDupPipe=0x%lx\n",
103 GetLastError(),
104 hDupPipe);
105 CloseHandle(hReadPipe);
106 CloseHandle(hWritePipe);
107 CloseHandle(hDupPipe);
108 Fail("");
109 }
110
111 /*Compare what was read with what was written.*/
112 if ((memcmp(cTestString, buffer, dwBytesRead)) != 0)
113 {
114 Trace("ERROR:%u: read \"%s\" expected \"%s\" \n",
115 GetLastError(),
116 buffer,
117 cTestString);
118 CloseHandle(hReadPipe);
119 CloseHandle(hWritePipe);
120 CloseHandle(hDupPipe);
121 Fail("");
122 }
123
124 /*Compare values returned from WriteFile and ReadFile.*/
125 if (dwBytesWritten != dwBytesRead)
126 {
127 Trace("ERROR:%u: WriteFile wrote \"%s\", but ReadFile read \"%s\","
128 " these should be the same\n",
129 GetLastError(),
130 buffer,
131 cTestString);
132 CloseHandle(hReadPipe);
133 CloseHandle(hWritePipe);
134 CloseHandle(hDupPipe);
135 Fail("");
136 }
137
138 /*Cleanup.*/
139 CloseHandle(hWritePipe);
140 CloseHandle(hReadPipe);
141 CloseHandle(hDupPipe);
142
143 PAL_Terminate();
144 return (PASS);
145}
146