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: test7.c (DuplicateHandle)
8**
9** Purpose: Tests the PAL implementation of the DuplicateHandle function,
10** with a handle from CreateThread. The test will create a thread
11** handle and its duplicate. Then get the priorities of the threads,
12** set the priority of one and the change should be seen in the
13** other.
14**
15**
16**===================================================================*/
17
18#include <palsuite.h>
19
20DWORD PALAPI CreateTestThread(LPVOID lpParam);
21
22int __cdecl main(int argc, char* argv[])
23{
24 HANDLE hThread;
25 HANDLE hDupThread;
26 DWORD dwThreadId = 0;
27 LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread;
28 HANDLE hSyncEvent;
29
30 int threadPriority;
31 int duplicatePriority;
32 int finalPriority;
33
34 /* Initialize the PAL.*/
35 if ((PAL_Initialize(argc, argv)) != 0)
36 {
37 return (FAIL);
38 }
39
40 LPSECURITY_ATTRIBUTES lpEventAttributes = NULL;
41 BOOL bManualReset = TRUE;
42 BOOL bInitialState = FALSE;
43 hSyncEvent = CreateEvent(lpEventAttributes,
44 bManualReset,
45 bInitialState,
46 NULL);
47
48 if (hSyncEvent == NULL)
49 {
50 Fail("ERROR:%u: Unable to create sync event.\n",
51 GetLastError());
52 }
53
54 /* Create a thread.*/
55 hThread = CreateThread(NULL, /* SD*/
56 (DWORD)0, /* initial stack size*/
57 lpStartAddress, /* thread function*/
58 (VOID*)hSyncEvent,/* thread argument*/
59 (DWORD)0, /* creation option*/
60 &dwThreadId); /* thread identifier*/
61 if (hThread == NULL)
62 {
63 Fail("ERROR:%u: Unable to create thread.\n",
64 GetLastError());
65 }
66
67 /* Duplicate the thread handle.*/
68 if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/
69 hThread, /* handle to duplicate*/
70 GetCurrentProcess(), /* target process handle*/
71 &hDupThread, /* duplicate handle*/
72 (DWORD)0, /* requested access*/
73 FALSE, /* handle inheritance*/
74 DUPLICATE_SAME_ACCESS))) /* optional actions*/
75 {
76 Trace("ERROR: %ld :Fail to create the duplicate handle"
77 " to hThread=0x%lx",
78 GetLastError(),
79 hThread);
80 CloseHandle(hThread);
81 Fail("");
82 }
83
84 /* Get the priority of the thread.*/
85 threadPriority = GetThreadPriority(hThread);
86 if(threadPriority != 0)
87 {
88 Trace("ERROR: Thread priority of hThread=0x%lx should be "
89 "set to normal THREAD_PRIORITY_NORMAL=%d\n",
90 hThread,
91 THREAD_PRIORITY_NORMAL);
92 CloseHandle(hThread);
93 CloseHandle(hDupThread);
94 Fail("");
95 }
96
97 /* Get the priority of the duplicated handle, and compare it to
98 * the priority of the original thread. Should be the same.*/
99 duplicatePriority = GetThreadPriority(hThread);
100 if(duplicatePriority != threadPriority)
101 {
102 Trace("ERROR: Expected priority of hThread=0x%lx and hDupThread=0x%lx"
103 " to be the same. Priorities:hThread=\"%d\":hDupThread=\"%d\"\n",
104 hThread,
105 hDupThread,
106 threadPriority,
107 duplicatePriority);
108 CloseHandle(hThread);
109 CloseHandle(hDupThread);
110 Fail("");
111 }
112
113 /* Set the priority of the duplicate thread.*/
114 if(!SetThreadPriority (hDupThread,THREAD_PRIORITY_HIGHEST))
115 {
116 Trace("ERROR:%u: SetThreadPriority failed on hThread=0x%lx\n",
117 GetLastError(),
118 hDupThread);
119 CloseHandle(hThread);
120 CloseHandle(hDupThread);
121 Fail("");
122 }
123
124 /* Get the priority of the original thread, and
125 * compare it to what the duplicate was set to.*/
126 finalPriority = GetThreadPriority(hThread);
127 if (finalPriority != THREAD_PRIORITY_HIGHEST)
128 {
129 Trace("ERROR: Expected priority of hThread=0x%lw and "
130 "hDupThread=0x%lw to be set the same. Priorities:"
131 "hThread=\"%d\":hDupThread=\"%d\".\n",
132 hThread,
133 hDupThread,
134 threadPriority,
135 duplicatePriority);
136 CloseHandle(hThread);
137 CloseHandle(hDupThread);
138 Fail("");
139 }
140
141 /* Signal the helper thread that it can shut down */
142 if (!SetEvent(hSyncEvent))
143 {
144 Fail("ERROR:%u: Failed to set event.\n",
145 GetLastError());
146 }
147
148 /* Wait on the original thread.*/
149 if((WaitForSingleObject(hThread, 100)) != WAIT_OBJECT_0)
150 {
151 Trace("ERROR:%u: hThread=0x%lx is in a non-signalled "
152 "mode, yet created signalled.\n",
153 GetLastError(),
154 hThread);
155 CloseHandle(hThread);
156 CloseHandle(hDupThread);
157 Fail("");
158 }
159
160 /* Clean-up thread and Terminate the PAL.*/
161 CloseHandle(hSyncEvent);
162 CloseHandle(hThread);
163 CloseHandle(hDupThread);
164 PAL_Terminate();
165 return PASS;
166}
167
168/*Thread testing function*/
169DWORD PALAPI CreateTestThread(LPVOID lpParam)
170{
171 HANDLE hSyncEvent = (HANDLE)lpParam;
172
173 /* Wait until the main thread signals that this helper thread should shut down */
174 WaitForSingleObject(hSyncEvent, INFINITE);
175
176 return (DWORD)0;
177}
178
179