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: test3.c
8**
9** Purpose: Test to ensure that OpenEventW() works when
10** opening an event created by another process. This test
11** program launches a child process which creates a
12** named, initially-unset event. The child waits up to
13** 10 seconds for the parent process to open that event
14** and set it, and returns PASS if the event was set or FAIL
15** otherwise. The parent process checks the return value
16** from the child to verify that the opened event was
17** properly used across processes.
18**
19** Dependencies: PAL_Initialize
20** PAL_Terminate
21** Fail
22** ZeroMemory
23** GetCurrentDirectoryW
24** CreateProcessW
25** WaitForSingleObject
26** GetExitCodeProcess
27** GetLastError
28** strlen
29** strncpy
30**
31**
32**===========================================================================*/
33#include <palsuite.h>
34
35#define TIMEOUT 60000
36
37int __cdecl main( int argc, char **argv )
38{
39 BOOL ret = FAIL;
40 LPSECURITY_ATTRIBUTES lpEventAttributes = NULL;
41
42 STARTUPINFO si;
43 PROCESS_INFORMATION pi;
44
45 DWORD dwExitCode;
46
47 DWORD dwRet = 0;
48 HANDLE hEvent = NULL;
49 WCHAR wcName[] = {'P','A','L','R','o','c','k','s','\0'};
50 LPWSTR lpName = wcName;
51 char lpCommandLine[MAX_PATH] = "";
52
53 /* initialize the PAL */
54 if( PAL_Initialize(argc, argv) != 0 )
55 {
56 return( FAIL );
57 }
58
59 /* zero our process and startup info structures */
60 ZeroMemory( &si, sizeof(si) );
61 si.cb = sizeof( si );
62 ZeroMemory( &pi, sizeof(pi) );
63
64 /* create an event which we can use with SetEvent */
65 hEvent = CreateEventW( lpEventAttributes,
66 TRUE, /* manual reset */
67 FALSE, /* unsignalled */
68 lpName );
69
70 if( hEvent == NULL )
71 {
72 /* ERROR */
73 Fail( "ERROR:%lu:CreateEventW() call failed in child\n",
74 GetLastError());
75 }
76
77 ZeroMemory( lpCommandLine, MAX_PATH );
78 if ( sprintf_s( lpCommandLine, MAX_PATH-1, "childprocess ") < 0 )
79 {
80 Fail ("Error: Insufficient lpCommandline for\n");
81 }
82
83 /* launch the child process */
84 if( !CreateProcess( NULL, /* module name to execute */
85 lpCommandLine, /* command line */
86 NULL, /* process handle not */
87 /* inheritable */
88 NULL, /* thread handle not */
89 /* inheritable */
90 FALSE, /* handle inheritance */
91 CREATE_NEW_CONSOLE, /* dwCreationFlags */
92 NULL, /* use parent's environment */
93 NULL, /* use parent's starting */
94 /* directory */
95 &si, /* startup info struct */
96 &pi ) /* process info struct */
97 )
98 {
99 Fail( "ERROR:%lu:CreateProcess call failed\n",
100 GetLastError() );
101 }
102
103 /* verify that the event is signalled by the child process */
104 dwRet = WaitForSingleObject( hEvent, TIMEOUT );
105 if( dwRet != WAIT_OBJECT_0 )
106 {
107 ret = FAIL;
108 /* ERROR */
109 Trace( "ERROR:WaitForSingleObject() call returned %lu, "
110 "expected WAIT_TIMEOUT\n",
111 "expected WAIT_OBJECT_0\n",
112 dwRet );
113
114 goto cleanup;
115
116 if( !CloseHandle( hEvent ) )
117 {
118 Trace( "ERROR:%lu:CloseHandle() call failed in child\n",
119 GetLastError());
120 }
121 goto cleanup;
122 }
123
124 /* wait for the child process to complete */
125 dwRet = WaitForSingleObject ( pi.hProcess, TIMEOUT );
126 if( dwRet != WAIT_OBJECT_0 )
127 {
128 ret = FAIL;
129 Trace( "ERROR:WaitForSingleObject() returned %lu, "
130 "expected %lu\n",
131 dwRet,
132 WAIT_OBJECT_0 );
133 goto cleanup;
134 }
135
136 /* check the exit code from the process */
137 if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
138 {
139 ret = FAIL;
140 Trace( "ERROR:%lu:GetExitCodeProcess call failed\n",
141 GetLastError() );
142 goto cleanup;
143 }
144
145 /* check for success */
146 ret = (dwExitCode == PASS) ? PASS : FAIL;
147
148cleanup:
149 if( hEvent != NULL )
150 {
151 if( ! CloseHandle ( hEvent ) )
152 {
153 Trace( "ERROR:%lu:CloseHandle call failed on event handle\n",
154 GetLastError() );
155 ret = FAIL;
156 }
157 }
158
159
160 /* close process and thread handle */
161 if( ! CloseHandle ( pi.hProcess ) )
162 {
163 Trace( "ERROR:%lu:CloseHandle call failed on process handle\n",
164 GetLastError() );
165 ret = FAIL;
166 }
167
168 if( ! CloseHandle ( pi.hThread ) )
169 {
170 Trace( "ERROR:%lu:CloseHandle call failed on thread handle\n",
171 GetLastError() );
172 ret = FAIL;
173 }
174
175 /* output a convenient error message and exit if we failed */
176 if( ret == FAIL )
177 {
178 Fail( "test failed\n" );
179 }
180
181
182 /* terminate the PAL */
183 PAL_Terminate();
184
185 /* return success */
186 return ret;
187}
188